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.
- package/package.json +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- package/src/validation/metrics-calculator.js +27 -551
|
@@ -1,88 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Priority Calculator
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Calculates refactoring priorities based on multiple factors.
|
|
5
|
-
*
|
|
5
|
+
* Factor logic lives in analysis/priority/ (factor-calculators, reasons-generator).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const RefactoringConfig = require('../config/refactoring-config');
|
|
9
|
+
const { PRIORITY_LEVELS, PRIORITY_FACTORS, PriorityResult } = require('./priority/priority-constants');
|
|
10
|
+
const { runAllFactors } = require('./priority/factor-calculators');
|
|
11
|
+
const { generateReasonsAndRecommendations } = require('./priority/reasons-generator');
|
|
9
12
|
|
|
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
13
|
class PriorityCalculator {
|
|
87
14
|
constructor(config = RefactoringConfig) {
|
|
88
15
|
this.config = config;
|
|
@@ -90,9 +17,6 @@ class PriorityCalculator {
|
|
|
90
17
|
this.thresholds = this.getDefaultThresholds();
|
|
91
18
|
}
|
|
92
19
|
|
|
93
|
-
/**
|
|
94
|
-
* Get default factor weights
|
|
95
|
-
*/
|
|
96
20
|
getDefaultWeights() {
|
|
97
21
|
return {
|
|
98
22
|
[PRIORITY_FACTORS.SIZE_VIOLATION]: 0.4,
|
|
@@ -105,9 +29,6 @@ class PriorityCalculator {
|
|
|
105
29
|
};
|
|
106
30
|
}
|
|
107
31
|
|
|
108
|
-
/**
|
|
109
|
-
* Get default priority thresholds
|
|
110
|
-
*/
|
|
111
32
|
getDefaultThresholds() {
|
|
112
33
|
return {
|
|
113
34
|
[PRIORITY_LEVELS.CRITICAL]: 0.8,
|
|
@@ -118,499 +39,28 @@ class PriorityCalculator {
|
|
|
118
39
|
};
|
|
119
40
|
}
|
|
120
41
|
|
|
121
|
-
/**
|
|
122
|
-
* Calculate priority for a file analysis
|
|
123
|
-
*/
|
|
124
42
|
calculatePriority(fileAnalysis) {
|
|
125
43
|
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
|
|
44
|
+
runAllFactors(fileAnalysis, result, this.weights, this.config);
|
|
137
45
|
const totalScore = result.getTotalWeightedScore();
|
|
138
|
-
|
|
139
|
-
// Determine priority based on thresholds
|
|
140
46
|
const priority = this.determinePriority(totalScore);
|
|
141
|
-
|
|
142
47
|
result.setPriority(priority, totalScore);
|
|
143
|
-
|
|
144
|
-
|
|
48
|
+
generateReasonsAndRecommendations(result);
|
|
145
49
|
return result;
|
|
146
50
|
}
|
|
147
51
|
|
|
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
52
|
determinePriority(score) {
|
|
440
|
-
if (score >= this.thresholds[PRIORITY_LEVELS.CRITICAL])
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
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
|
-
}
|
|
53
|
+
if (score >= this.thresholds[PRIORITY_LEVELS.CRITICAL]) return PRIORITY_LEVELS.CRITICAL;
|
|
54
|
+
if (score >= this.thresholds[PRIORITY_LEVELS.HIGH]) return PRIORITY_LEVELS.HIGH;
|
|
55
|
+
if (score >= this.thresholds[PRIORITY_LEVELS.MEDIUM]) return PRIORITY_LEVELS.MEDIUM;
|
|
56
|
+
if (score >= this.thresholds[PRIORITY_LEVELS.LOW]) return PRIORITY_LEVELS.LOW;
|
|
449
57
|
return PRIORITY_LEVELS.NONE;
|
|
450
58
|
}
|
|
451
59
|
|
|
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
60
|
calculatePriorities(fileAnalyses) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
for (const fileAnalysis of fileAnalyses) {
|
|
604
|
-
const result = this.calculatePriority(fileAnalysis);
|
|
605
|
-
results.push(result);
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
return results;
|
|
61
|
+
return fileAnalyses.map(fa => this.calculatePriority(fa));
|
|
609
62
|
}
|
|
610
63
|
|
|
611
|
-
/**
|
|
612
|
-
* Get priority summary
|
|
613
|
-
*/
|
|
614
64
|
getPrioritySummary(priorityResults) {
|
|
615
65
|
const summary = {
|
|
616
66
|
total: priorityResults.length,
|
|
@@ -625,24 +75,17 @@ class PriorityCalculator {
|
|
|
625
75
|
highestScore: 0,
|
|
626
76
|
lowestScore: 100
|
|
627
77
|
};
|
|
628
|
-
|
|
629
78
|
let totalScore = 0;
|
|
630
|
-
|
|
631
79
|
for (const result of priorityResults) {
|
|
632
80
|
summary.byPriority[result.priority]++;
|
|
633
81
|
totalScore += result.score;
|
|
634
82
|
summary.highestScore = Math.max(summary.highestScore, result.score);
|
|
635
83
|
summary.lowestScore = Math.min(summary.lowestScore, result.score);
|
|
636
84
|
}
|
|
637
|
-
|
|
638
85
|
summary.averageScore = summary.total > 0 ? totalScore / summary.total : 0;
|
|
639
|
-
|
|
640
86
|
return summary;
|
|
641
87
|
}
|
|
642
88
|
|
|
643
|
-
/**
|
|
644
|
-
* Sort files by priority
|
|
645
|
-
*/
|
|
646
89
|
sortByPriority(priorityResults, descending = true) {
|
|
647
90
|
const priorityOrder = {
|
|
648
91
|
[PRIORITY_LEVELS.CRITICAL]: 0,
|
|
@@ -651,23 +94,15 @@ class PriorityCalculator {
|
|
|
651
94
|
[PRIORITY_LEVELS.LOW]: 3,
|
|
652
95
|
[PRIORITY_LEVELS.NONE]: 4
|
|
653
96
|
};
|
|
654
|
-
|
|
655
97
|
return [...priorityResults].sort((a, b) => {
|
|
656
|
-
const
|
|
657
|
-
if (
|
|
658
|
-
return priorityDiff;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// If same priority, sort by score
|
|
98
|
+
const diff = priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
99
|
+
if (diff !== 0) return diff;
|
|
662
100
|
return descending ? b.score - a.score : a.score - b.score;
|
|
663
101
|
});
|
|
664
102
|
}
|
|
665
103
|
|
|
666
|
-
/**
|
|
667
|
-
* Get files by priority level
|
|
668
|
-
*/
|
|
669
104
|
getFilesByPriority(priorityResults, priorityLevel) {
|
|
670
|
-
return priorityResults.filter(
|
|
105
|
+
return priorityResults.filter(r => r.priority === priorityLevel);
|
|
671
106
|
}
|
|
672
107
|
}
|
|
673
108
|
|