vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850

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 (192) hide show
  1. package/package.json +1 -1
  2. package/src/agents/AgentCheckDiscoveryService.js +180 -0
  3. package/src/agents/AgentCheckService.js +18 -261
  4. package/src/agents/AgentCheckStatisticsService.js +195 -0
  5. package/src/agents/EnvironmentConfigurationManager.js +31 -380
  6. package/src/agents/InstallationType.js +19 -6
  7. package/src/agents/SimpleAgentCheckService.js +472 -0
  8. package/src/agents/config-managers/ConfigUtils.js +72 -0
  9. package/src/agents/config-managers/DefaultConfig.js +58 -0
  10. package/src/agents/config-managers/EnvVarLoader.js +66 -0
  11. package/src/agents/config-managers/FileConfigLoader.js +124 -0
  12. package/src/agents/config-managers/TypeConverters.js +61 -0
  13. package/src/agents/config-managers/VariableMappings.js +92 -0
  14. package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
  15. package/src/agents/discovery/AgentDiscoveryService.js +29 -403
  16. package/src/agents/discovery/agent-validator.js +262 -0
  17. package/src/agents/discovery/discovery-results.js +176 -0
  18. package/src/agents/discovery/discovery-scanner.js +268 -0
  19. package/src/agents/discovery/discovery-utils.js +161 -0
  20. package/src/agents/discovery/executable-analyzer.js +290 -0
  21. package/src/agents/discovery/history-manager.js +310 -0
  22. package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
  23. package/src/agents/verification/ResultAnalyzer.js +30 -431
  24. package/src/agents/verification/analysis-utils.js +310 -0
  25. package/src/agents/verification/batch-analyzer.js +440 -0
  26. package/src/agents/verification/pattern-recognizer.js +369 -0
  27. package/src/agents/verification/report-generator.js +320 -0
  28. package/src/agents/verification/test-analyzer.js +290 -0
  29. package/src/agents/windows/InstallerFactory.js +4 -0
  30. package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
  31. package/src/analysis/analysis-engine.js +314 -0
  32. package/src/analysis/ast-analyzer.js +342 -0
  33. package/src/analysis/boundary-detector-refactored.js +378 -0
  34. package/src/analysis/boundary-detector.js +200 -603
  35. package/src/analysis/boundary-scanner.js +609 -0
  36. package/src/analysis/boundary-types.js +118 -0
  37. package/src/analysis/boundary-utils.js +293 -0
  38. package/src/analysis/deadline-priority-calculator.js +18 -0
  39. package/src/analysis/detection-methods.js +347 -0
  40. package/src/analysis/importance-priority-calculator.js +18 -0
  41. package/src/analysis/priority/factor-calculators.js +204 -0
  42. package/src/analysis/priority/factor-helpers.js +71 -0
  43. package/src/analysis/priority/priority-constants.js +73 -0
  44. package/src/analysis/priority/priority-factor-calculators.js +301 -0
  45. package/src/analysis/priority/reasons-generator.js +44 -0
  46. package/src/analysis/priority-calculator.js +15 -580
  47. package/src/analysis/strategy-generator.js +16 -66
  48. package/src/analysis/type-priority-calculator.js +18 -0
  49. package/src/analysis/urgency-priority-calculator.js +18 -0
  50. package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
  51. package/src/commands/disable-requirement.js +60 -0
  52. package/src/commands/disable-spec.js +60 -0
  53. package/src/commands/enable-requirement.js +60 -0
  54. package/src/commands/enable-spec.js +60 -0
  55. package/src/commands/registry.js +1 -6
  56. package/src/commands/requirements.js +8 -2
  57. package/src/ide-integration/applescript-manager.cjs +9 -24
  58. package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
  59. package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
  60. package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
  61. package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
  62. package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
  63. package/src/ide-integration/cdp-manager.js +28 -573
  64. package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
  65. package/src/ide-integration/ide-openers/claude-opener.js +171 -0
  66. package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
  67. package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
  68. package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
  69. package/src/ide-integration/macos-ide-manager.js +20 -582
  70. package/src/ide-integration/macos-quota-checker.js +164 -0
  71. package/src/ide-integration/macos-text-sender.js +19 -38
  72. package/src/ide-integration/provider-manager.cjs +52 -7
  73. package/src/index.cjs +6 -0
  74. package/src/index.js +10 -0
  75. package/src/llm/direct-llm-manager.cjs +501 -0
  76. package/src/localization/translations/en-part1.js +363 -0
  77. package/src/localization/translations/en-part2.js +320 -0
  78. package/src/localization/translations/en.js +4 -687
  79. package/src/localization/translations/es-part1.js +363 -0
  80. package/src/localization/translations/es-part2.js +320 -0
  81. package/src/localization/translations/es.js +4 -688
  82. package/src/models/file-analysis-collection.js +139 -0
  83. package/src/models/file-analysis-metrics.js +50 -0
  84. package/src/models/file-analysis.js +15 -262
  85. package/src/models/plan-manager.js +410 -0
  86. package/src/models/refactoring-models.js +380 -0
  87. package/src/models/refactoring-plan-refactored.js +81 -0
  88. package/src/models/refactoring-plan.js +2 -663
  89. package/src/monitoring/alert-system.js +4 -45
  90. package/src/monitoring/continuous-scan-notifications.js +37 -191
  91. package/src/monitoring/notification-handlers/base-handler.js +58 -0
  92. package/src/monitoring/notification-handlers/error-handler.js +36 -0
  93. package/src/monitoring/notification-handlers/index.js +21 -0
  94. package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
  95. package/src/monitoring/notification-handlers/progress-handler.js +48 -0
  96. package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
  97. package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
  98. package/src/provider-registry.js +8 -0
  99. package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
  100. package/src/refactoring/boundary/boundary-detector.js +26 -596
  101. package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
  102. package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
  103. package/src/refactoring/boundary/detectors/class-detector.js +247 -0
  104. package/src/refactoring/boundary/detectors/config-detector.js +270 -0
  105. package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
  106. package/src/refactoring/boundary/detectors/function-detector.js +248 -0
  107. package/src/refactoring/boundary/detectors/module-detector.js +249 -0
  108. package/src/refactoring/boundary/detectors/object-detector.js +247 -0
  109. package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
  110. package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
  111. package/src/refactoring/circular-dependency-resolver-original.js +16 -76
  112. package/src/refactoring/code-mover-refactored.js +309 -0
  113. package/src/refactoring/code-mover.js +48 -355
  114. package/src/refactoring/execution-status.js +18 -0
  115. package/src/refactoring/execution-strategies.js +172 -0
  116. package/src/refactoring/file-splitter-core.js +568 -0
  117. package/src/refactoring/file-splitter-types.js +136 -0
  118. package/src/refactoring/file-splitter.js +2 -682
  119. package/src/refactoring/functionality-validator.js +11 -51
  120. package/src/refactoring/import-manager-refactored.js +385 -0
  121. package/src/refactoring/import-manager.js +112 -487
  122. package/src/refactoring/import-models.js +189 -0
  123. package/src/refactoring/import-parser.js +306 -0
  124. package/src/refactoring/move-executor.js +431 -0
  125. package/src/refactoring/move-utils.js +368 -0
  126. package/src/refactoring/operation-executor.js +76 -0
  127. package/src/refactoring/plan-creator.js +36 -0
  128. package/src/refactoring/plan-executor.js +143 -0
  129. package/src/refactoring/plan-validator.js +68 -0
  130. package/src/refactoring/refactoring-executor-result.js +70 -0
  131. package/src/refactoring/refactoring-executor.js +34 -569
  132. package/src/refactoring/refactoring-operation.js +94 -0
  133. package/src/refactoring/refactoring-plan.js +69 -0
  134. package/src/refactoring/refactoring-rollback.js +22 -527
  135. package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
  136. package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
  137. package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
  138. package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
  139. package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
  140. package/src/refactoring/test-validator.js +32 -448
  141. package/src/refactoring/validation/baseline-runner.js +71 -0
  142. package/src/refactoring/validation/report-generator.js +136 -0
  143. package/src/refactoring/validation/result-comparator.js +92 -0
  144. package/src/refactoring/validation/test-suite.js +59 -0
  145. package/src/refactoring/validation/test-validation-result.js +83 -0
  146. package/src/refactoring/validation/validation-runner.js +95 -0
  147. package/src/refactoring/validation/validation-status.js +18 -0
  148. package/src/rui/commands/AgentCommandParser.js +60 -369
  149. package/src/rui/commands/AgentResponseFormatter.js +7 -47
  150. package/src/rui/commands/parsers/CommandMapper.js +148 -0
  151. package/src/rui/commands/parsers/CommandValidator.js +228 -0
  152. package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
  153. package/src/rui/commands/parsers/TokenParser.js +69 -0
  154. package/src/rui/commands/parsers/tokenizer.js +153 -0
  155. package/src/utils/current-requirement-operations.js +50 -1
  156. package/src/utils/report-generator.js +18 -514
  157. package/src/utils/report-generators/analysis-generator.js +115 -0
  158. package/src/utils/report-generators/base-generator.js +141 -0
  159. package/src/utils/report-generators/compliance-generator.js +41 -0
  160. package/src/utils/report-generators/format-handlers.js +185 -0
  161. package/src/utils/report-generators/refactoring-generator.js +46 -0
  162. package/src/utils/report-generators/validation-generator.js +63 -0
  163. package/src/utils/requirement-enable-disable.js +265 -0
  164. package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
  165. package/src/utils/requirement-helpers/requirement-mover.js +88 -1
  166. package/src/utils/requirement-helpers.js +5 -2
  167. package/src/utils/smoke-test-cli.js +45 -8
  168. package/src/utils/specification-enable-disable.js +122 -0
  169. package/src/utils/specification-helpers.js +30 -4
  170. package/src/utils/specification-migration.js +5 -5
  171. package/src/utils/test-comparator.js +118 -0
  172. package/src/utils/test-config.js +54 -0
  173. package/src/utils/test-executor.js +133 -0
  174. package/src/utils/test-parser.js +215 -0
  175. package/src/utils/test-runner-baseline.js +63 -0
  176. package/src/utils/test-runner-core.js +98 -0
  177. package/src/utils/test-runner-report.js +39 -0
  178. package/src/utils/test-runner-validation.js +71 -0
  179. package/src/utils/test-runner.js +11 -535
  180. package/src/validation/comparison-analyzer.js +333 -0
  181. package/src/validation/compliance-reporter-new.js +282 -0
  182. package/src/validation/compliance-reporter-refactored.js +344 -0
  183. package/src/validation/compliance-reporter.js +278 -591
  184. package/src/validation/compliance-utils.js +278 -0
  185. package/src/validation/html-generator.js +446 -0
  186. package/src/validation/metrics/category-calculator.js +137 -0
  187. package/src/validation/metrics/metrics-helpers.js +155 -0
  188. package/src/validation/metrics/overview-calculator.js +85 -0
  189. package/src/validation/metrics/overview-metrics.js +41 -0
  190. package/src/validation/metrics/quality-calculator.js +166 -0
  191. package/src/validation/metrics/size-calculator.js +69 -0
  192. package/src/validation/metrics-calculator.js +27 -551
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Priority factor calculation functions.
3
+ * Each function adds one factor to the PriorityResult.
4
+ */
5
+
6
+ const { PRIORITY_FACTORS } = require('./priority-constants');
7
+ const { calculateComplexityScore, assessCouplingRisk, findTestFile } = require('./factor-helpers');
8
+
9
+ function calculateSizeViolationFactor(fileAnalysis, result, weights, config) {
10
+ const limits = config.limits;
11
+ let score = 0;
12
+ const details = {};
13
+ if (fileAnalysis.lineCount > limits.criticalThreshold) {
14
+ score = 1.0;
15
+ details.violation = 'critical';
16
+ details.excessLines = fileAnalysis.lineCount - limits.maxFileSize;
17
+ details.severity = 'critical';
18
+ } else if (fileAnalysis.lineCount > limits.maxFileSize) {
19
+ score = 0.8;
20
+ details.violation = 'major';
21
+ details.excessLines = fileAnalysis.lineCount - limits.maxFileSize;
22
+ details.severity = 'major';
23
+ } else if (fileAnalysis.lineCount > limits.warningThreshold) {
24
+ score = 0.6;
25
+ details.violation = 'minor';
26
+ details.excessLines = fileAnalysis.lineCount - limits.warningThreshold;
27
+ details.severity = 'minor';
28
+ } else if (fileAnalysis.lineCount > limits.mediumFileMax) {
29
+ score = 0.3;
30
+ details.violation = 'approaching';
31
+ details.excessLines = 0;
32
+ details.severity = 'low';
33
+ } else {
34
+ details.violation = 'none';
35
+ details.excessLines = 0;
36
+ details.severity = 'none';
37
+ }
38
+ details.lineCount = fileAnalysis.lineCount;
39
+ details.limit = limits.maxFileSize;
40
+ details.warningThreshold = limits.warningThreshold;
41
+ result.addFactor(PRIORITY_FACTORS.SIZE_VIOLATION, score, weights[PRIORITY_FACTORS.SIZE_VIOLATION], details);
42
+ }
43
+
44
+ function calculateComplexityFactor(fileAnalysis, result, weights, _config) {
45
+ const complexityScore = fileAnalysis.getComplexityScore
46
+ ? fileAnalysis.getComplexityScore()
47
+ : calculateComplexityScore(fileAnalysis);
48
+ let score = 0;
49
+ let level = 'very_low';
50
+ if (complexityScore >= 80) {
51
+ score = 1.0;
52
+ level = 'very_high';
53
+ } else if (complexityScore >= 60) {
54
+ score = 0.8;
55
+ level = 'high';
56
+ } else if (complexityScore >= 40) {
57
+ score = 0.6;
58
+ level = 'medium';
59
+ } else if (complexityScore >= 20) {
60
+ score = 0.3;
61
+ level = 'low';
62
+ }
63
+ const details = {
64
+ complexityScore,
65
+ cyclomaticComplexity: fileAnalysis.cyclomaticComplexity || 0,
66
+ nestingDepth: fileAnalysis.nestingDepth || 0,
67
+ functionCount: fileAnalysis.functionCount || 0,
68
+ classCount: fileAnalysis.classCount || 0,
69
+ level
70
+ };
71
+ result.addFactor(PRIORITY_FACTORS.COMPLEXITY, score, weights[PRIORITY_FACTORS.COMPLEXITY], details);
72
+ }
73
+
74
+ function calculateDependencyFactor(fileAnalysis, result, weights, _config) {
75
+ const dependencyCount = fileAnalysis.dependencyCount || fileAnalysis.imports?.length || 0;
76
+ const dependentCount = fileAnalysis.dependents?.length || 0;
77
+ const totalDependencies = dependencyCount + dependentCount;
78
+ let score = 0;
79
+ let level = 'very_low';
80
+ if (totalDependencies > 20) {
81
+ score = 1.0;
82
+ level = 'very_high';
83
+ } else if (totalDependencies > 15) {
84
+ score = 0.8;
85
+ level = 'high';
86
+ } else if (totalDependencies > 10) {
87
+ score = 0.6;
88
+ level = 'medium';
89
+ } else if (totalDependencies > 5) {
90
+ score = 0.3;
91
+ level = 'low';
92
+ }
93
+ const details = {
94
+ dependencyCount,
95
+ dependentCount,
96
+ totalDependencies,
97
+ couplingRisk: assessCouplingRisk(totalDependencies),
98
+ level
99
+ };
100
+ result.addFactor(PRIORITY_FACTORS.DEPENDENCY_COUNT, score, weights[PRIORITY_FACTORS.DEPENDENCY_COUNT], details);
101
+ }
102
+
103
+ function calculatePackageImportanceFactor(fileAnalysis, result, weights, _config) {
104
+ const packageName = fileAnalysis.package || 'root';
105
+ const packageImportance = {
106
+ core: 1.0, cli: 0.8, 'electron-app': 0.7, web: 0.6, 'api-server': 0.6,
107
+ 'chrome-extension': 0.5, mobile: 0.5, 'vscode-extension': 0.4, admin: 0.3, root: 0.2
108
+ };
109
+ const score = packageImportance[packageName] || 0.2;
110
+ const details = {
111
+ packageName,
112
+ importance: score >= 0.8 ? 'critical' : score >= 0.6 ? 'high' : score >= 0.4 ? 'medium' : 'low',
113
+ isCorePackage: packageName === 'core'
114
+ };
115
+ result.addFactor(PRIORITY_FACTORS.PACKAGE_IMPORTANCE, score, weights[PRIORITY_FACTORS.PACKAGE_IMPORTANCE], details);
116
+ }
117
+
118
+ function calculateChangeFrequencyFactor(fileAnalysis, result, weights, _config) {
119
+ const filePath = fileAnalysis.filePath;
120
+ const highFrequencyPatterns = [/config\//, /\/bin\//, /\/src\/main\//, /package\.json$/, /README\.md$/, /\.config\./];
121
+ const mediumFrequencyPatterns = [/\/src\/utils\//, /\/src\/helpers\//, /\/src\/services\//];
122
+ let score = 0.2;
123
+ let frequency = 'low';
124
+ if (highFrequencyPatterns.some(p => p.test(filePath))) {
125
+ score = 0.8;
126
+ frequency = 'high';
127
+ } else if (mediumFrequencyPatterns.some(p => p.test(filePath))) {
128
+ score = 0.5;
129
+ frequency = 'medium';
130
+ }
131
+ const details = { filePath, lastModified: fileAnalysis.lastModified, frequency };
132
+ if (fileAnalysis.lastModified) {
133
+ const daysSinceModified = (Date.now() - new Date(fileAnalysis.lastModified)) / (1000 * 60 * 60 * 24);
134
+ if (daysSinceModified < 7) {
135
+ score = Math.min(1.0, score + 0.2);
136
+ details.recentlyModified = true;
137
+ } else if (daysSinceModified < 30) {
138
+ score = Math.min(1.0, score + 0.1);
139
+ details.recentlyModified = false;
140
+ }
141
+ }
142
+ result.addFactor(PRIORITY_FACTORS.CHANGE_FREQUENCY, score, weights[PRIORITY_FACTORS.CHANGE_FREQUENCY], details);
143
+ }
144
+
145
+ function calculateTestCoverageFactor(fileAnalysis, result, weights, _config) {
146
+ const filePath = fileAnalysis.filePath;
147
+ const isTestFile = fileAnalysis.isTestFile || /test|spec/.test(filePath);
148
+ let score = 0;
149
+ const details = { filePath, isTestFile };
150
+ if (isTestFile) {
151
+ details.coverage = 'test_file';
152
+ } else {
153
+ const testFile = findTestFile(filePath);
154
+ if (testFile) {
155
+ score = 0.2;
156
+ details.coverage = 'good';
157
+ details.testFile = testFile;
158
+ } else {
159
+ score = 0.6;
160
+ details.coverage = 'poor';
161
+ details.testFile = null;
162
+ }
163
+ }
164
+ details.impact = score > 0.4 ? 'high_risk' : 'low_risk';
165
+ result.addFactor(PRIORITY_FACTORS.TEST_COVERAGE, score, weights[PRIORITY_FACTORS.TEST_COVERAGE], details);
166
+ }
167
+
168
+ function calculateBusinessImpactFactor(fileAnalysis, result, weights, _config) {
169
+ const filePath = fileAnalysis.filePath;
170
+ const criticalPatterns = [/\/bin\//, /\/src\/main\//, /\/src\/app\//, /\/src\/index\./, /\/server\./, /\/app\./];
171
+ const importantPatterns = [/\/src\/api\//, /\/src\/controllers\//, /\/src\/services\//, /\/src\/models\//];
172
+ let score = 0.2;
173
+ let impact = 'standard';
174
+ if (criticalPatterns.some(p => p.test(filePath))) {
175
+ score = 0.8;
176
+ impact = 'critical';
177
+ } else if (importantPatterns.some(p => p.test(filePath))) {
178
+ score = 0.5;
179
+ impact = 'important';
180
+ }
181
+ const details = { filePath, impact, isBusinessCritical: score >= 0.8 };
182
+ result.addFactor(PRIORITY_FACTORS.BUSINESS_IMPACT, score, weights[PRIORITY_FACTORS.BUSINESS_IMPACT], details);
183
+ }
184
+
185
+ function runAllFactors(fileAnalysis, result, weights, config) {
186
+ calculateSizeViolationFactor(fileAnalysis, result, weights, config);
187
+ calculateComplexityFactor(fileAnalysis, result, weights, config);
188
+ calculateDependencyFactor(fileAnalysis, result, weights, config);
189
+ calculatePackageImportanceFactor(fileAnalysis, result, weights, config);
190
+ calculateChangeFrequencyFactor(fileAnalysis, result, weights, config);
191
+ calculateTestCoverageFactor(fileAnalysis, result, weights, config);
192
+ calculateBusinessImpactFactor(fileAnalysis, result, weights, config);
193
+ }
194
+
195
+ module.exports = {
196
+ runAllFactors,
197
+ calculateSizeViolationFactor,
198
+ calculateComplexityFactor,
199
+ calculateDependencyFactor,
200
+ calculatePackageImportanceFactor,
201
+ calculateChangeFrequencyFactor,
202
+ calculateTestCoverageFactor,
203
+ calculateBusinessImpactFactor
204
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Helper functions used by priority factor calculators.
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ /**
9
+ * Calculate complexity score for a file (0-100)
10
+ */
11
+ function calculateComplexityScore(fileAnalysis) {
12
+ let score = 0;
13
+ if (fileAnalysis.lineCount > 1000) score += 30;
14
+ else if (fileAnalysis.lineCount > 555) score += 25;
15
+ else if (fileAnalysis.lineCount > 300) score += 15;
16
+ else if (fileAnalysis.lineCount > 100) score += 5;
17
+ const functionCount = fileAnalysis.functionCount || 0;
18
+ if (functionCount > 20) score += 20;
19
+ else if (functionCount > 10) score += 15;
20
+ else if (functionCount > 5) score += 10;
21
+ else if (functionCount > 2) score += 5;
22
+ const classCount = fileAnalysis.classCount || 0;
23
+ if (classCount > 5) score += 15;
24
+ else if (classCount > 3) score += 10;
25
+ else if (classCount > 1) score += 5;
26
+ const nestingDepth = fileAnalysis.nestingDepth || 0;
27
+ if (nestingDepth > 8) score += 15;
28
+ else if (nestingDepth > 5) score += 10;
29
+ else if (nestingDepth > 3) score += 5;
30
+ const dependencyCount = fileAnalysis.dependencyCount || 0;
31
+ if (dependencyCount > 20) score += 20;
32
+ else if (dependencyCount > 10) score += 15;
33
+ else if (dependencyCount > 5) score += 10;
34
+ else if (dependencyCount > 2) score += 5;
35
+ return Math.min(score, 100);
36
+ }
37
+
38
+ function assessCouplingRisk(dependencyCount) {
39
+ if (dependencyCount > 20) return 'very_high';
40
+ if (dependencyCount > 15) return 'high';
41
+ if (dependencyCount > 10) return 'medium';
42
+ if (dependencyCount > 5) return 'low';
43
+ return 'very_low';
44
+ }
45
+
46
+ function findTestFile(filePath) {
47
+ const dir = path.dirname(filePath);
48
+ const basename = path.basename(filePath, path.extname(filePath));
49
+ const testPatterns = [
50
+ path.join(dir, `${basename}.test.js`),
51
+ path.join(dir, `${basename}.spec.js`),
52
+ path.join(dir, `${basename}.test.ts`),
53
+ path.join(dir, `${basename}.spec.ts`),
54
+ path.join(dir, '__tests__', `${basename}.js`),
55
+ path.join(dir, '__tests__', `${basename}.ts`),
56
+ path.join(dir, 'test', `${basename}.js`),
57
+ path.join(dir, 'test', `${basename}.ts`),
58
+ path.join(dir, 'tests', `${basename}.js`),
59
+ path.join(dir, 'tests', `${basename}.ts`)
60
+ ];
61
+ for (const testPath of testPatterns) {
62
+ if (fs.existsSync(testPath)) return testPath;
63
+ }
64
+ return null;
65
+ }
66
+
67
+ module.exports = {
68
+ calculateComplexityScore,
69
+ assessCouplingRisk,
70
+ findTestFile
71
+ };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Priority constants and result model for refactoring priority calculation.
3
+ */
4
+
5
+ const PRIORITY_LEVELS = {
6
+ CRITICAL: 'critical',
7
+ HIGH: 'high',
8
+ MEDIUM: 'medium',
9
+ LOW: 'low',
10
+ NONE: 'none'
11
+ };
12
+
13
+ const PRIORITY_FACTORS = {
14
+ SIZE_VIOLATION: 'size_violation',
15
+ COMPLEXITY: 'complexity',
16
+ DEPENDENCY_COUNT: 'dependency_count',
17
+ CHANGE_FREQUENCY: 'change_frequency',
18
+ PACKAGE_IMPORTANCE: 'package_importance',
19
+ TEST_COVERAGE: 'test_coverage',
20
+ BUSINESS_IMPACT: 'business_impact'
21
+ };
22
+
23
+ class PriorityResult {
24
+ constructor(filePath) {
25
+ this.filePath = filePath;
26
+ this.priority = PRIORITY_LEVELS.NONE;
27
+ this.score = 0;
28
+ this.factors = {};
29
+ this.reasons = [];
30
+ this.recommendations = [];
31
+ this.metadata = {
32
+ calculatedAt: new Date().toISOString(),
33
+ version: '1.0.0'
34
+ };
35
+ }
36
+
37
+ addFactor(factorName, score, weight, details = {}) {
38
+ this.factors[factorName] = {
39
+ score,
40
+ weight,
41
+ weightedScore: score * weight,
42
+ details
43
+ };
44
+ }
45
+
46
+ addReason(reason) {
47
+ this.reasons.push(reason);
48
+ }
49
+
50
+ addRecommendation(recommendation) {
51
+ this.recommendations.push(recommendation);
52
+ }
53
+
54
+ setPriority(priority, score) {
55
+ this.priority = priority;
56
+ this.score = score;
57
+ }
58
+
59
+ getFactorScore(factorName) {
60
+ return this.factors[factorName]?.weightedScore || 0;
61
+ }
62
+
63
+ getTotalWeightedScore() {
64
+ return Object.values(this.factors)
65
+ .reduce((sum, factor) => sum + factor.weightedScore, 0);
66
+ }
67
+ }
68
+
69
+ module.exports = {
70
+ PRIORITY_LEVELS,
71
+ PRIORITY_FACTORS,
72
+ PriorityResult
73
+ };
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Priority factor calculation functions for refactoring priority.
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { PRIORITY_FACTORS } = require('./priority-constants');
8
+
9
+ function calculateComplexityScore(fileAnalysis) {
10
+ let score = 0;
11
+ if (fileAnalysis.lineCount > 1000) score += 30;
12
+ else if (fileAnalysis.lineCount > 555) score += 25;
13
+ else if (fileAnalysis.lineCount > 300) score += 15;
14
+ else if (fileAnalysis.lineCount > 100) score += 5;
15
+ const functionCount = fileAnalysis.functionCount || 0;
16
+ if (functionCount > 20) score += 20;
17
+ else if (functionCount > 10) score += 15;
18
+ else if (functionCount > 5) score += 10;
19
+ else if (functionCount > 2) score += 5;
20
+ const classCount = fileAnalysis.classCount || 0;
21
+ if (classCount > 5) score += 15;
22
+ else if (classCount > 3) score += 10;
23
+ else if (classCount > 1) score += 5;
24
+ const nestingDepth = fileAnalysis.nestingDepth || 0;
25
+ if (nestingDepth > 8) score += 15;
26
+ else if (nestingDepth > 5) score += 10;
27
+ else if (nestingDepth > 3) score += 5;
28
+ const dependencyCount = fileAnalysis.dependencyCount || 0;
29
+ if (dependencyCount > 20) score += 20;
30
+ else if (dependencyCount > 10) score += 15;
31
+ else if (dependencyCount > 5) score += 10;
32
+ else if (dependencyCount > 2) score += 5;
33
+ return Math.min(score, 100);
34
+ }
35
+
36
+ function assessCouplingRisk(dependencyCount) {
37
+ if (dependencyCount > 20) return 'very_high';
38
+ if (dependencyCount > 15) return 'high';
39
+ if (dependencyCount > 10) return 'medium';
40
+ if (dependencyCount > 5) return 'low';
41
+ return 'very_low';
42
+ }
43
+
44
+ function findTestFile(filePath) {
45
+ const dir = path.dirname(filePath);
46
+ const basename = path.basename(filePath, path.extname(filePath));
47
+ const testPatterns = [
48
+ path.join(dir, `${basename}.test.js`),
49
+ path.join(dir, `${basename}.spec.js`),
50
+ path.join(dir, `${basename}.test.ts`),
51
+ path.join(dir, `${basename}.spec.ts`),
52
+ path.join(dir, '__tests__', `${basename}.js`),
53
+ path.join(dir, '__tests__', `${basename}.ts`),
54
+ path.join(dir, 'test', `${basename}.js`),
55
+ path.join(dir, 'test', `${basename}.ts`),
56
+ path.join(dir, 'tests', `${basename}.js`),
57
+ path.join(dir, 'tests', `${basename}.ts`)
58
+ ];
59
+ for (const testPath of testPatterns) {
60
+ if (fs.existsSync(testPath)) return testPath;
61
+ }
62
+ return null;
63
+ }
64
+
65
+ function calculateSizeViolationFactor(fileAnalysis, result, weights, config) {
66
+ const limits = config.limits;
67
+ let score = 0;
68
+ const details = {};
69
+ if (fileAnalysis.lineCount > limits.criticalThreshold) {
70
+ score = 1.0;
71
+ details.violation = 'critical';
72
+ details.excessLines = fileAnalysis.lineCount - limits.maxFileSize;
73
+ details.severity = 'critical';
74
+ } else if (fileAnalysis.lineCount > limits.maxFileSize) {
75
+ score = 0.8;
76
+ details.violation = 'major';
77
+ details.excessLines = fileAnalysis.lineCount - limits.maxFileSize;
78
+ details.severity = 'major';
79
+ } else if (fileAnalysis.lineCount > limits.warningThreshold) {
80
+ score = 0.6;
81
+ details.violation = 'minor';
82
+ details.excessLines = fileAnalysis.lineCount - limits.warningThreshold;
83
+ details.severity = 'minor';
84
+ } else if (fileAnalysis.lineCount > limits.mediumFileMax) {
85
+ score = 0.3;
86
+ details.violation = 'approaching';
87
+ details.excessLines = 0;
88
+ details.severity = 'low';
89
+ } else {
90
+ score = 0.0;
91
+ details.violation = 'none';
92
+ details.excessLines = 0;
93
+ details.severity = 'none';
94
+ }
95
+ details.lineCount = fileAnalysis.lineCount;
96
+ details.limit = limits.maxFileSize;
97
+ details.warningThreshold = limits.warningThreshold;
98
+ result.addFactor(PRIORITY_FACTORS.SIZE_VIOLATION, score, weights[PRIORITY_FACTORS.SIZE_VIOLATION], details);
99
+ }
100
+
101
+ function calculateComplexityFactor(fileAnalysis, result, weights, calculateComplexityScoreFn) {
102
+ const complexityScore = fileAnalysis.getComplexityScore
103
+ ? fileAnalysis.getComplexityScore()
104
+ : calculateComplexityScoreFn(fileAnalysis);
105
+ let score = 0;
106
+ const details = {};
107
+ if (complexityScore >= 80) {
108
+ score = 1.0;
109
+ details.level = 'very_high';
110
+ } else if (complexityScore >= 60) {
111
+ score = 0.8;
112
+ details.level = 'high';
113
+ } else if (complexityScore >= 40) {
114
+ score = 0.6;
115
+ details.level = 'medium';
116
+ } else if (complexityScore >= 20) {
117
+ score = 0.3;
118
+ details.level = 'low';
119
+ } else {
120
+ score = 0.0;
121
+ details.level = 'very_low';
122
+ }
123
+ details.complexityScore = complexityScore;
124
+ details.cyclomaticComplexity = fileAnalysis.cyclomaticComplexity || 0;
125
+ details.nestingDepth = fileAnalysis.nestingDepth || 0;
126
+ details.functionCount = fileAnalysis.functionCount || 0;
127
+ details.classCount = fileAnalysis.classCount || 0;
128
+ result.addFactor(PRIORITY_FACTORS.COMPLEXITY, score, weights[PRIORITY_FACTORS.COMPLEXITY], details);
129
+ }
130
+
131
+ function calculateDependencyFactor(fileAnalysis, result, weights, assessCouplingRiskFn) {
132
+ const dependencyCount = fileAnalysis.dependencyCount || fileAnalysis.imports?.length || 0;
133
+ const dependentCount = fileAnalysis.dependents?.length || 0;
134
+ const totalDependencies = dependencyCount + dependentCount;
135
+ let score = 0;
136
+ const details = {};
137
+ if (totalDependencies > 20) {
138
+ score = 1.0;
139
+ details.level = 'very_high';
140
+ } else if (totalDependencies > 15) {
141
+ score = 0.8;
142
+ details.level = 'high';
143
+ } else if (totalDependencies > 10) {
144
+ score = 0.6;
145
+ details.level = 'medium';
146
+ } else if (totalDependencies > 5) {
147
+ score = 0.3;
148
+ details.level = 'low';
149
+ } else {
150
+ score = 0.0;
151
+ details.level = 'very_low';
152
+ }
153
+ details.dependencyCount = dependencyCount;
154
+ details.dependentCount = dependentCount;
155
+ details.totalDependencies = totalDependencies;
156
+ details.couplingRisk = assessCouplingRiskFn(totalDependencies);
157
+ result.addFactor(PRIORITY_FACTORS.DEPENDENCY_COUNT, score, weights[PRIORITY_FACTORS.DEPENDENCY_COUNT], details);
158
+ }
159
+
160
+ function calculatePackageImportanceFactor(fileAnalysis, result, weights) {
161
+ const packageName = fileAnalysis.package || 'root';
162
+ const packageImportance = {
163
+ core: 1.0,
164
+ cli: 0.8,
165
+ 'electron-app': 0.7,
166
+ web: 0.6,
167
+ 'api-server': 0.6,
168
+ 'chrome-extension': 0.5,
169
+ mobile: 0.5,
170
+ 'vscode-extension': 0.4,
171
+ admin: 0.3,
172
+ root: 0.2
173
+ };
174
+ const score = packageImportance[packageName] || 0.2;
175
+ const details = {
176
+ packageName,
177
+ importance: score >= 0.8 ? 'critical' : score >= 0.6 ? 'high' : score >= 0.4 ? 'medium' : 'low',
178
+ isCorePackage: packageName === 'core'
179
+ };
180
+ result.addFactor(PRIORITY_FACTORS.PACKAGE_IMPORTANCE, score, weights[PRIORITY_FACTORS.PACKAGE_IMPORTANCE], details);
181
+ }
182
+
183
+ function calculateChangeFrequencyFactor(fileAnalysis, result, weights) {
184
+ const filePath = fileAnalysis.filePath;
185
+ const highFrequencyPatterns = [/config\//, /\/bin\//, /\/src\/main\//, /package\.json$/, /README\.md$/, /\.config\./];
186
+ const mediumFrequencyPatterns = [/\/src\/utils\//, /\/src\/helpers\//, /\/src\/services\//];
187
+ let score = 0.2;
188
+ const details = { filePath, lastModified: fileAnalysis.lastModified };
189
+ if (highFrequencyPatterns.some(p => p.test(filePath))) {
190
+ score = 0.8;
191
+ details.frequency = 'high';
192
+ } else if (mediumFrequencyPatterns.some(p => p.test(filePath))) {
193
+ score = 0.5;
194
+ details.frequency = 'medium';
195
+ } else {
196
+ details.frequency = 'low';
197
+ }
198
+ if (fileAnalysis.lastModified) {
199
+ const daysSinceModified = (Date.now() - new Date(fileAnalysis.lastModified)) / (1000 * 60 * 60 * 24);
200
+ if (daysSinceModified < 7) {
201
+ score = Math.min(1.0, score + 0.2);
202
+ details.recentlyModified = true;
203
+ } else if (daysSinceModified < 30) {
204
+ score = Math.min(1.0, score + 0.1);
205
+ details.recentlyModified = false;
206
+ }
207
+ }
208
+ result.addFactor(PRIORITY_FACTORS.CHANGE_FREQUENCY, score, weights[PRIORITY_FACTORS.CHANGE_FREQUENCY], details);
209
+ }
210
+
211
+ function calculateTestCoverageFactor(fileAnalysis, result, weights, findTestFileFn) {
212
+ const filePath = fileAnalysis.filePath;
213
+ const isTestFile = fileAnalysis.isTestFile || /test|spec/.test(filePath);
214
+ let score = 0;
215
+ const details = { filePath, isTestFile };
216
+ if (isTestFile) {
217
+ score = 0.0;
218
+ details.coverage = 'test_file';
219
+ } else {
220
+ const testFile = findTestFileFn(filePath);
221
+ if (testFile) {
222
+ score = 0.2;
223
+ details.coverage = 'good';
224
+ details.testFile = testFile;
225
+ } else {
226
+ score = 0.6;
227
+ details.coverage = 'poor';
228
+ details.testFile = null;
229
+ }
230
+ }
231
+ details.impact = score > 0.4 ? 'high_risk' : 'low_risk';
232
+ result.addFactor(PRIORITY_FACTORS.TEST_COVERAGE, score, weights[PRIORITY_FACTORS.TEST_COVERAGE], details);
233
+ }
234
+
235
+ function calculateBusinessImpactFactor(fileAnalysis, result, weights) {
236
+ const filePath = fileAnalysis.filePath;
237
+ const criticalPatterns = [/\/bin\//, /\/src\/main\//, /\/src\/app\//, /\/src\/index\./, /\/server\./, /\/app\./];
238
+ const importantPatterns = [/\/src\/api\//, /\/src\/controllers\//, /\/src\/services\//, /\/src\/models\//];
239
+ let score = 0.2;
240
+ const details = { filePath, impact: 'standard' };
241
+ if (criticalPatterns.some(p => p.test(filePath))) {
242
+ score = 0.8;
243
+ details.impact = 'critical';
244
+ } else if (importantPatterns.some(p => p.test(filePath))) {
245
+ score = 0.5;
246
+ details.impact = 'important';
247
+ }
248
+ details.isBusinessCritical = score >= 0.8;
249
+ result.addFactor(PRIORITY_FACTORS.BUSINESS_IMPACT, score, weights[PRIORITY_FACTORS.BUSINESS_IMPACT], details);
250
+ }
251
+
252
+ function generateReasonsAndRecommendations(fileAnalysis, result) {
253
+ const reasons = [];
254
+ const recommendations = [];
255
+ const sizeFactor = result.factors[PRIORITY_FACTORS.SIZE_VIOLATION];
256
+ if (sizeFactor && sizeFactor.score > 0.6) {
257
+ reasons.push(`File has ${sizeFactor.details.excessLines} excess lines beyond limit`);
258
+ recommendations.push('Consider splitting large functions or extracting modules');
259
+ }
260
+ const complexityFactor = result.factors[PRIORITY_FACTORS.COMPLEXITY];
261
+ if (complexityFactor && complexityFactor.score > 0.6) {
262
+ reasons.push(`File has ${complexityFactor.details.level} complexity`);
263
+ recommendations.push('Reduce complexity through better organization and smaller functions');
264
+ }
265
+ const dependencyFactor = result.factors[PRIORITY_FACTORS.DEPENDENCY_COUNT];
266
+ if (dependencyFactor && dependencyFactor.score > 0.6) {
267
+ reasons.push(`File has ${dependencyFactor.details.totalDependencies} total dependencies`);
268
+ recommendations.push('Consider reducing dependencies through better separation of concerns');
269
+ }
270
+ const packageFactor = result.factors[PRIORITY_FACTORS.PACKAGE_IMPORTANCE];
271
+ if (packageFactor && packageFactor.score > 0.8) {
272
+ reasons.push(`File is in ${packageFactor.details.importance} package (${packageFactor.details.packageName})`);
273
+ recommendations.push('Ensure high code quality for critical package files');
274
+ }
275
+ const testFactor = result.factors[PRIORITY_FACTORS.TEST_COVERAGE];
276
+ if (testFactor && testFactor.score > 0.4) {
277
+ reasons.push('File has poor or no test coverage');
278
+ recommendations.push('Add test coverage before refactoring to ensure safety');
279
+ }
280
+ const businessFactor = result.factors[PRIORITY_FACTORS.BUSINESS_IMPACT];
281
+ if (businessFactor && businessFactor.score > 0.6) {
282
+ reasons.push(`File has ${businessFactor.details.impact} business impact`);
283
+ recommendations.push('Exercise extra caution when refactoring business-critical code');
284
+ }
285
+ result.reasons = reasons;
286
+ result.recommendations = recommendations;
287
+ }
288
+
289
+ module.exports = {
290
+ calculateComplexityScore,
291
+ assessCouplingRisk,
292
+ findTestFile,
293
+ calculateSizeViolationFactor,
294
+ calculateComplexityFactor,
295
+ calculateDependencyFactor,
296
+ calculatePackageImportanceFactor,
297
+ calculateChangeFrequencyFactor,
298
+ calculateTestCoverageFactor,
299
+ calculateBusinessImpactFactor,
300
+ generateReasonsAndRecommendations
301
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Generates reasons and recommendations for priority results.
3
+ */
4
+
5
+ const { PRIORITY_FACTORS } = require('./priority-constants');
6
+
7
+ function generateReasonsAndRecommendations(result) {
8
+ const reasons = [];
9
+ const recommendations = [];
10
+ const sizeFactor = result.factors[PRIORITY_FACTORS.SIZE_VIOLATION];
11
+ if (sizeFactor && sizeFactor.score > 0.6) {
12
+ reasons.push(`File has ${sizeFactor.details.excessLines} excess lines beyond limit`);
13
+ recommendations.push('Consider splitting large functions or extracting modules');
14
+ }
15
+ const complexityFactor = result.factors[PRIORITY_FACTORS.COMPLEXITY];
16
+ if (complexityFactor && complexityFactor.score > 0.6) {
17
+ reasons.push(`File has ${complexityFactor.details.level} complexity`);
18
+ recommendations.push('Reduce complexity through better organization and smaller functions');
19
+ }
20
+ const dependencyFactor = result.factors[PRIORITY_FACTORS.DEPENDENCY_COUNT];
21
+ if (dependencyFactor && dependencyFactor.score > 0.6) {
22
+ reasons.push(`File has ${dependencyFactor.details.totalDependencies} total dependencies`);
23
+ recommendations.push('Consider reducing dependencies through better separation of concerns');
24
+ }
25
+ const packageFactor = result.factors[PRIORITY_FACTORS.PACKAGE_IMPORTANCE];
26
+ if (packageFactor && packageFactor.score > 0.8) {
27
+ reasons.push(`File is in ${packageFactor.details.importance} package (${packageFactor.details.packageName})`);
28
+ recommendations.push('Ensure high code quality for critical package files');
29
+ }
30
+ const testFactor = result.factors[PRIORITY_FACTORS.TEST_COVERAGE];
31
+ if (testFactor && testFactor.score > 0.4) {
32
+ reasons.push('File has poor or no test coverage');
33
+ recommendations.push('Add test coverage before refactoring to ensure safety');
34
+ }
35
+ const businessFactor = result.factors[PRIORITY_FACTORS.BUSINESS_IMPACT];
36
+ if (businessFactor && businessFactor.score > 0.6) {
37
+ reasons.push(`File has ${businessFactor.details.impact} business impact`);
38
+ recommendations.push('Exercise extra caution when refactoring business-critical code');
39
+ }
40
+ result.reasons = reasons;
41
+ result.recommendations = recommendations;
42
+ }
43
+
44
+ module.exports = { generateReasonsAndRecommendations };