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
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boundary Detection - Analysis Engine
|
|
3
|
+
*
|
|
4
|
+
* Analysis and recommendation engine for boundary detection.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { BOUNDARY_TYPES } = require('./boundary-types');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Assess file complexity
|
|
11
|
+
* @param {Object} result - Detection result
|
|
12
|
+
* @returns {string} - Complexity level
|
|
13
|
+
*/
|
|
14
|
+
function assessComplexity(result) {
|
|
15
|
+
const boundaries = result.boundaries;
|
|
16
|
+
let totalComplexity = 0;
|
|
17
|
+
|
|
18
|
+
for (const boundary of boundaries) {
|
|
19
|
+
totalComplexity += boundary.complexity || 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const averageComplexity = totalComplexity / boundaries.length;
|
|
23
|
+
|
|
24
|
+
if (averageComplexity > 10) return 'high';
|
|
25
|
+
if (averageComplexity > 5) return 'medium';
|
|
26
|
+
return 'low';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Assess file cohesion
|
|
31
|
+
* @param {Object} result - Detection result
|
|
32
|
+
* @returns {string} - Cohesion level
|
|
33
|
+
*/
|
|
34
|
+
function assessCohesion(result) {
|
|
35
|
+
const functions = result.getBoundariesByType(BOUNDARY_TYPES.FUNCTION);
|
|
36
|
+
const classes = result.getBoundariesByType(BOUNDARY_TYPES.CLASS);
|
|
37
|
+
|
|
38
|
+
// Simple cohesion assessment based on related functionality
|
|
39
|
+
const totalBoundaries = functions.length + classes.length;
|
|
40
|
+
const relatedBoundaries = boundaries.filter(b =>
|
|
41
|
+
b.dependencies.length > 0 || b.exports.length > 0
|
|
42
|
+
).length;
|
|
43
|
+
|
|
44
|
+
const cohesionRatio = relatedBoundaries / totalBoundaries;
|
|
45
|
+
|
|
46
|
+
if (cohesionRatio > 0.8) return 'high';
|
|
47
|
+
if (cohesionRatio > 0.5) return 'medium';
|
|
48
|
+
return 'low';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Assess file coupling
|
|
53
|
+
* @param {Object} result - Detection result
|
|
54
|
+
* @returns {string} - Coupling level
|
|
55
|
+
*/
|
|
56
|
+
function assessCoupling(result) {
|
|
57
|
+
// Simple coupling assessment based on imports
|
|
58
|
+
const imports = result.getBoundariesByType(BOUNDARY_TYPES.IMPORT);
|
|
59
|
+
|
|
60
|
+
if (imports.length > 10) return 'high';
|
|
61
|
+
if (imports.length > 5) return 'medium';
|
|
62
|
+
return 'low';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get refactoring recommendations
|
|
67
|
+
* @param {Object} result - Detection result
|
|
68
|
+
* @returns {Array} - Recommendations
|
|
69
|
+
*/
|
|
70
|
+
function getRefactoringRecommendations(result) {
|
|
71
|
+
const recommendations = [];
|
|
72
|
+
|
|
73
|
+
// Large functions
|
|
74
|
+
const largeFunctions = result.getBoundariesByType(BOUNDARY_TYPES.FUNCTION)
|
|
75
|
+
.filter(f => f.lineCount > 50);
|
|
76
|
+
|
|
77
|
+
if (largeFunctions.length > 0) {
|
|
78
|
+
recommendations.push({
|
|
79
|
+
type: 'extract_functions',
|
|
80
|
+
priority: 'high',
|
|
81
|
+
description: `${largeFunctions.length} functions are too large and should be split`,
|
|
82
|
+
boundaries: largeFunctions.map(f => ({ name: f.name, lineCount: f.lineCount }))
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Large classes
|
|
87
|
+
const largeClasses = result.getBoundariesByType(BOUNDARY_TYPES.CLASS)
|
|
88
|
+
.filter(c => c.lineCount > 200);
|
|
89
|
+
|
|
90
|
+
if (largeClasses.length > 0) {
|
|
91
|
+
recommendations.push({
|
|
92
|
+
type: 'split_classes',
|
|
93
|
+
priority: 'medium',
|
|
94
|
+
description: `${largeClasses.length} classes are too large and should be split`,
|
|
95
|
+
boundaries: largeClasses.map(c => ({ name: c.name, lineCount: c.lineCount }))
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Utility extraction
|
|
100
|
+
const utilities = result.getBoundariesByType(BOUNDARY_TYPES.UTILITY);
|
|
101
|
+
if (utilities.length === 0 && result.metadata.totalBoundaries > 5) {
|
|
102
|
+
recommendations.push({
|
|
103
|
+
type: 'extract_utilities',
|
|
104
|
+
priority: 'low',
|
|
105
|
+
description: 'Consider extracting utility functions to separate modules',
|
|
106
|
+
boundaries: []
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// High complexity
|
|
111
|
+
const highComplexity = result.boundaries.filter(b => (b.complexity || 0) > 10);
|
|
112
|
+
if (highComplexity.length > 0) {
|
|
113
|
+
recommendations.push({
|
|
114
|
+
type: 'reduce_complexity',
|
|
115
|
+
priority: 'high',
|
|
116
|
+
description: `${highComplexity.length} boundaries have high complexity and should be simplified`,
|
|
117
|
+
boundaries: highComplexity.map(b => ({ name: b.name, complexity: b.complexity }))
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Low cohesion
|
|
122
|
+
if (result.metadata.cohesion === 'low') {
|
|
123
|
+
recommendations.push({
|
|
124
|
+
type: 'improve_cohesion',
|
|
125
|
+
priority: 'medium',
|
|
126
|
+
description: 'File has low cohesion, consider restructuring related functionality',
|
|
127
|
+
boundaries: []
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// High coupling
|
|
132
|
+
if (result.metadata.coupling === 'high') {
|
|
133
|
+
recommendations.push({
|
|
134
|
+
type: 'reduce_coupling',
|
|
135
|
+
priority: 'medium',
|
|
136
|
+
description: 'File has high coupling, consider dependency injection or interfaces',
|
|
137
|
+
boundaries: []
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return recommendations;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generate boundary summary
|
|
146
|
+
* @param {Object} result - Detection result
|
|
147
|
+
* @returns {Object} - Summary statistics
|
|
148
|
+
*/
|
|
149
|
+
function generateBoundarySummary(result) {
|
|
150
|
+
const summary = {
|
|
151
|
+
totalBoundaries: result.metadata.totalBoundaries,
|
|
152
|
+
byType: result.metadata.byType,
|
|
153
|
+
averageSize: 0,
|
|
154
|
+
largestBoundary: null,
|
|
155
|
+
smallestBoundary: null,
|
|
156
|
+
complexityDistribution: {
|
|
157
|
+
low: 0,
|
|
158
|
+
medium: 0,
|
|
159
|
+
high: 0
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
if (result.boundaries.length > 0) {
|
|
164
|
+
// Calculate average size
|
|
165
|
+
const totalSize = result.boundaries.reduce((sum, b) => sum + b.lineCount, 0);
|
|
166
|
+
summary.averageSize = Math.round(totalSize / result.boundaries.length);
|
|
167
|
+
|
|
168
|
+
// Find largest and smallest
|
|
169
|
+
summary.largestBoundary = result.boundaries.reduce((max, b) =>
|
|
170
|
+
b.lineCount > max.lineCount ? b : max, result.boundaries[0]);
|
|
171
|
+
summary.smallestBoundary = result.boundaries.reduce((min, b) =>
|
|
172
|
+
b.lineCount < min.lineCount ? b : min, result.boundaries[0]);
|
|
173
|
+
|
|
174
|
+
// Complexity distribution
|
|
175
|
+
for (const boundary of result.boundaries) {
|
|
176
|
+
const complexity = boundary.complexity || 0;
|
|
177
|
+
if (complexity <= 5) {
|
|
178
|
+
summary.complexityDistribution.low++;
|
|
179
|
+
} else if (complexity <= 10) {
|
|
180
|
+
summary.complexityDistribution.medium++;
|
|
181
|
+
} else {
|
|
182
|
+
summary.complexityDistribution.high++;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return summary;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Calculate refactoring score
|
|
192
|
+
* @param {Object} result - Detection result
|
|
193
|
+
* @returns {number} - Refactoring score (0-100)
|
|
194
|
+
*/
|
|
195
|
+
function calculateRefactoringScore(result) {
|
|
196
|
+
let score = 100; // Start with perfect score
|
|
197
|
+
|
|
198
|
+
// Penalize large boundaries
|
|
199
|
+
const largeBoundaries = result.boundaries.filter(b => b.lineCount > 100);
|
|
200
|
+
score -= largeBoundaries.length * 10;
|
|
201
|
+
|
|
202
|
+
// Penalize high complexity
|
|
203
|
+
const highComplexity = result.boundaries.filter(b => (b.complexity || 0) > 15);
|
|
204
|
+
score -= highComplexity.length * 15;
|
|
205
|
+
|
|
206
|
+
// Penalize low cohesion
|
|
207
|
+
if (result.metadata.cohesion === 'low') {
|
|
208
|
+
score -= 20;
|
|
209
|
+
} else if (result.metadata.cohesion === 'medium') {
|
|
210
|
+
score -= 10;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Penalize high coupling
|
|
214
|
+
if (result.metadata.coupling === 'high') {
|
|
215
|
+
score -= 15;
|
|
216
|
+
} else if (result.metadata.coupling === 'medium') {
|
|
217
|
+
score -= 5;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return Math.max(0, Math.min(100, score));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Generate refactoring priority
|
|
225
|
+
* @param {Object} result - Detection result
|
|
226
|
+
* @returns {string} - Priority level
|
|
227
|
+
*/
|
|
228
|
+
function generateRefactoringPriority(result) {
|
|
229
|
+
const score = calculateRefactoringScore(result);
|
|
230
|
+
|
|
231
|
+
if (score >= 80) return 'low';
|
|
232
|
+
if (score >= 60) return 'medium';
|
|
233
|
+
return 'high';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Analyze boundary patterns
|
|
238
|
+
* @param {Object} result - Detection result
|
|
239
|
+
* @returns {Object} - Pattern analysis
|
|
240
|
+
*/
|
|
241
|
+
function analyzeBoundaryPatterns(result) {
|
|
242
|
+
const patterns = {
|
|
243
|
+
functionPatterns: {},
|
|
244
|
+
classPatterns: {},
|
|
245
|
+
importPatterns: {},
|
|
246
|
+
complexityPatterns: {}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// Function patterns
|
|
250
|
+
const functions = result.getBoundariesByType(BOUNDARY_TYPES.FUNCTION);
|
|
251
|
+
if (functions.length > 0) {
|
|
252
|
+
patterns.functionPatterns = {
|
|
253
|
+
averageSize: Math.round(functions.reduce((sum, f) => sum + f.lineCount, 0) / functions.length),
|
|
254
|
+
largestFunction: functions.reduce((max, f) => f.lineCount > max.lineCount ? f : max, functions[0]),
|
|
255
|
+
complexityTrend: functions.map(f => f.complexity || 0)
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Class patterns
|
|
260
|
+
const classes = result.getBoundariesByType(BOUNDARY_TYPES.CLASS);
|
|
261
|
+
if (classes.length > 0) {
|
|
262
|
+
patterns.classPatterns = {
|
|
263
|
+
averageSize: Math.round(classes.reduce((sum, c) => sum + c.lineCount, 0) / classes.length),
|
|
264
|
+
largestClass: classes.reduce((max, c) => c.lineCount > max.lineCount ? c : max, classes[0]),
|
|
265
|
+
dependencyTrend: classes.map(c => c.dependencies.length)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Import patterns
|
|
270
|
+
const imports = result.getBoundariesByType(BOUNDARY_TYPES.IMPORT);
|
|
271
|
+
if (imports.length > 0) {
|
|
272
|
+
const importNames = imports.map(i => i.name);
|
|
273
|
+
patterns.importPatterns = {
|
|
274
|
+
totalImports: imports.length,
|
|
275
|
+
uniqueImports: [...new Set(importNames)].length,
|
|
276
|
+
duplicateImports: importNames.length - [...new Set(importNames)].length
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Complexity patterns
|
|
281
|
+
const complexities = result.boundaries.map(b => b.complexity || 0);
|
|
282
|
+
if (complexities.length > 0) {
|
|
283
|
+
patterns.complexityPatterns = {
|
|
284
|
+
averageComplexity: Math.round(complexities.reduce((sum, c) => sum + c, 0) / complexities.length),
|
|
285
|
+
maxComplexity: Math.max(...complexities),
|
|
286
|
+
minComplexity: Math.min(...complexities),
|
|
287
|
+
complexityVariance: calculateVariance(complexities)
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return patterns;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Calculate variance of numbers
|
|
296
|
+
* @param {Array} numbers - Array of numbers
|
|
297
|
+
* @returns {number} - Variance
|
|
298
|
+
*/
|
|
299
|
+
function calculateVariance(numbers) {
|
|
300
|
+
const mean = numbers.reduce((sum, num) => sum + num, 0) / numbers.length;
|
|
301
|
+
const squaredDiffs = numbers.map(num => Math.pow(num - mean, 2));
|
|
302
|
+
return squaredDiffs.reduce((sum, diff) => sum + diff, 0) / numbers.length;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
module.exports = {
|
|
306
|
+
assessComplexity,
|
|
307
|
+
assessCohesion,
|
|
308
|
+
assessCoupling,
|
|
309
|
+
getRefactoringRecommendations,
|
|
310
|
+
generateBoundarySummary,
|
|
311
|
+
calculateRefactoringScore,
|
|
312
|
+
generateRefactoringPriority,
|
|
313
|
+
analyzeBoundaryPatterns
|
|
314
|
+
};
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boundary Detection - AST Analyzer
|
|
3
|
+
*
|
|
4
|
+
* AST-based boundary detection utilities.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { BOUNDARY_TYPES, Boundary } = require('./boundary-types');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Find function boundary
|
|
11
|
+
* @param {Array} lines - File lines
|
|
12
|
+
* @param {number} startLine - Starting line index
|
|
13
|
+
* @param {string} name - Function name
|
|
14
|
+
* @returns {Boundary|null} - Function boundary or null
|
|
15
|
+
*/
|
|
16
|
+
function findMethodBoundary(lines, startLine, name) {
|
|
17
|
+
let braceCount = 0;
|
|
18
|
+
let foundBrace = false;
|
|
19
|
+
|
|
20
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
21
|
+
const line = lines[i];
|
|
22
|
+
|
|
23
|
+
for (let j = 0; j < line.length; j++) {
|
|
24
|
+
if (line[j] === '{') {
|
|
25
|
+
braceCount++;
|
|
26
|
+
foundBrace = true;
|
|
27
|
+
} else if (line[j] === '}') {
|
|
28
|
+
braceCount--;
|
|
29
|
+
if (foundBrace && braceCount === 0) {
|
|
30
|
+
const boundary = new Boundary(
|
|
31
|
+
BOUNDARY_TYPES.FUNCTION,
|
|
32
|
+
startLine,
|
|
33
|
+
i,
|
|
34
|
+
name
|
|
35
|
+
);
|
|
36
|
+
boundary.metadata.type = 'method';
|
|
37
|
+
return boundary;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Find class boundary
|
|
48
|
+
* @param {Array} lines - File lines
|
|
49
|
+
* @param {number} startLine - Starting line index
|
|
50
|
+
* @param {string} name - Class name
|
|
51
|
+
* @returns {Boundary|null} - Class boundary or null
|
|
52
|
+
*/
|
|
53
|
+
function findClassBoundary(lines, startLine, name) {
|
|
54
|
+
let braceCount = 0;
|
|
55
|
+
let foundBrace = false;
|
|
56
|
+
|
|
57
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
58
|
+
const line = lines[i];
|
|
59
|
+
|
|
60
|
+
for (let j = 0; j < line.length; j++) {
|
|
61
|
+
if (line[j] === '{') {
|
|
62
|
+
braceCount++;
|
|
63
|
+
foundBrace = true;
|
|
64
|
+
} else if (line[j] === '}') {
|
|
65
|
+
braceCount--;
|
|
66
|
+
if (foundBrace && braceCount === 0) {
|
|
67
|
+
return new Boundary(
|
|
68
|
+
BOUNDARY_TYPES.CLASS,
|
|
69
|
+
startLine,
|
|
70
|
+
i,
|
|
71
|
+
name
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Find module boundary
|
|
83
|
+
* @param {Array} lines - File lines
|
|
84
|
+
* @param {number} startLine - Starting line index
|
|
85
|
+
* @param {string} name - Module name
|
|
86
|
+
* @returns {Boundary|null} - Module boundary or null
|
|
87
|
+
*/
|
|
88
|
+
function findModuleBoundary(lines, startLine, name) {
|
|
89
|
+
let braceCount = 0;
|
|
90
|
+
let foundBrace = false;
|
|
91
|
+
|
|
92
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
93
|
+
const line = lines[i];
|
|
94
|
+
|
|
95
|
+
// Look for module.exports or similar patterns
|
|
96
|
+
if (line.includes('module.exports') || line.includes('export default')) {
|
|
97
|
+
if (foundBrace && braceCount === 0) {
|
|
98
|
+
const boundary = new Boundary(
|
|
99
|
+
BOUNDARY_TYPES.MODULE,
|
|
100
|
+
startLine,
|
|
101
|
+
i,
|
|
102
|
+
name
|
|
103
|
+
);
|
|
104
|
+
boundary.metadata.type = 'module';
|
|
105
|
+
return boundary;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
for (let j = 0; j < line.length; j++) {
|
|
110
|
+
if (line[j] === '{') {
|
|
111
|
+
braceCount++;
|
|
112
|
+
foundBrace = true;
|
|
113
|
+
} else if (line[j] === '}') {
|
|
114
|
+
braceCount--;
|
|
115
|
+
if (foundBrace && braceCount === 0) {
|
|
116
|
+
const boundary = new Boundary(
|
|
117
|
+
BOUNDARY_TYPES.MODULE,
|
|
118
|
+
startLine,
|
|
119
|
+
i,
|
|
120
|
+
name
|
|
121
|
+
);
|
|
122
|
+
boundary.metadata.type = 'module';
|
|
123
|
+
return boundary;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Find block boundary
|
|
134
|
+
* @param {Array} lines - File lines
|
|
135
|
+
* @param {number} startLine - Starting line index
|
|
136
|
+
* @param {string} name - Block name
|
|
137
|
+
* @returns {Boundary|null} - Block boundary or null
|
|
138
|
+
*/
|
|
139
|
+
function findBlockBoundary(lines, startLine, name) {
|
|
140
|
+
let braceCount = 0;
|
|
141
|
+
let foundBrace = false;
|
|
142
|
+
|
|
143
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
144
|
+
const line = lines[i];
|
|
145
|
+
|
|
146
|
+
for (let j = 0; j < line.length; j++) {
|
|
147
|
+
if (line[j] === '{') {
|
|
148
|
+
braceCount++;
|
|
149
|
+
foundBrace = true;
|
|
150
|
+
} else if (line[j] === '}') {
|
|
151
|
+
braceCount--;
|
|
152
|
+
if (foundBrace && braceCount === 0) {
|
|
153
|
+
const boundary = new Boundary(
|
|
154
|
+
BOUNDARY_TYPES.BLOCK,
|
|
155
|
+
startLine,
|
|
156
|
+
i,
|
|
157
|
+
name
|
|
158
|
+
);
|
|
159
|
+
boundary.metadata.type = 'block';
|
|
160
|
+
return boundary;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Extract function name from line
|
|
171
|
+
* @param {string} line - Source line
|
|
172
|
+
* @returns {string|null} - Function name or null
|
|
173
|
+
*/
|
|
174
|
+
function extractFunctionName(line) {
|
|
175
|
+
const patterns = [
|
|
176
|
+
/function\s+(\w+)\s*\(/, // function name()
|
|
177
|
+
/const\s+(\w+)\s*=\s*(async\s+)?/, // const name = async
|
|
178
|
+
/let\s+(\w+)\s*=\s*(async\s+)?/, // let name = async
|
|
179
|
+
/var\s+(\w+)\s*=\s*(async\s+)?/, // var name = async
|
|
180
|
+
/(\w+)\s*:\s*function\s*\(/, // name: function()
|
|
181
|
+
/(\w+)\s*=>\s*\(/ // arrow function
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
for (const pattern of patterns) {
|
|
185
|
+
const match = line.match(pattern);
|
|
186
|
+
if (match) {
|
|
187
|
+
return match[1];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Extract class name from line
|
|
196
|
+
* @param {string} line - Source line
|
|
197
|
+
* @returns {string|null} - Class name or null
|
|
198
|
+
*/
|
|
199
|
+
function extractClassName(line) {
|
|
200
|
+
const patterns = [
|
|
201
|
+
/class\s+(\w+)/, // class Name
|
|
202
|
+
/const\s+(\w+)\s*=\s*class\s+/, // const Name = class
|
|
203
|
+
/let\s+(\w+)\s*=\s*class\s+/, // let Name = class
|
|
204
|
+
/var\s+(\w+)\s*=\s*class\s+/, // var Name = class
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
for (const pattern of patterns) {
|
|
208
|
+
const match = line.match(pattern);
|
|
209
|
+
if (match) {
|
|
210
|
+
return match[1];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Extract module name from line
|
|
219
|
+
* @param {string} line - Source line
|
|
220
|
+
* @returns {string|null} - Module name or null
|
|
221
|
+
*/
|
|
222
|
+
function extractModuleName(line) {
|
|
223
|
+
const patterns = [
|
|
224
|
+
/module\.exports\s*=\s*(\w+)/, // module.exports = Name
|
|
225
|
+
/exports\.(\w+)\s*=/, // exports.Name =
|
|
226
|
+
/export\s+default\s+(\w+)/, // export default Name
|
|
227
|
+
/export\s+{\s*(\w+)\s*:/, // export { Name }:
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
for (const pattern of patterns) {
|
|
231
|
+
const match = line.match(pattern);
|
|
232
|
+
if (match) {
|
|
233
|
+
return match[1];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Calculate boundary complexity
|
|
242
|
+
* @param {Array} lines - Lines within boundary
|
|
243
|
+
* @param {string} boundaryType - Type of boundary
|
|
244
|
+
* @returns {number} - Complexity score
|
|
245
|
+
*/
|
|
246
|
+
function calculateBoundaryComplexity(lines, boundaryType) {
|
|
247
|
+
let complexity = 1; // Base complexity
|
|
248
|
+
|
|
249
|
+
for (const line of lines) {
|
|
250
|
+
// Add complexity for control structures
|
|
251
|
+
if (/\b(if|else|for|while|switch|case|try|catch|finally)\b/.test(line)) {
|
|
252
|
+
complexity += 0.5;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Add complexity for nested structures
|
|
256
|
+
const nestingLevel = (line.match(/\{/g) || []).length - (line.match(/\}/g) || []).length;
|
|
257
|
+
if (nestingLevel > 2) {
|
|
258
|
+
complexity += nestingLevel * 0.2;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Add complexity for logical operators
|
|
262
|
+
const logicalOperators = (line.match(/(&&|\|\||&&|\|\|)/g) || []).length;
|
|
263
|
+
if (logicalOperators > 2) {
|
|
264
|
+
complexity += logicalOperators * 0.1;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return Math.round(complexity);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Find dependencies in boundary
|
|
273
|
+
* @param {Array} lines - Lines within boundary
|
|
274
|
+
* @returns {Array} - Dependencies
|
|
275
|
+
*/
|
|
276
|
+
function findDependencies(lines) {
|
|
277
|
+
const dependencies = [];
|
|
278
|
+
const importPatterns = [
|
|
279
|
+
/require\s*\(\s*['"]([^'"]+)['"]\s*\)/,
|
|
280
|
+
/import\s+.*\s+from\s+['"]([^'"]+)['"]/,
|
|
281
|
+
/import\s*\(\s*['"]([^'"]+)['"]\s*\)/
|
|
282
|
+
];
|
|
283
|
+
|
|
284
|
+
for (const line of lines) {
|
|
285
|
+
for (const pattern of importPatterns) {
|
|
286
|
+
const match = line.match(pattern);
|
|
287
|
+
if (match) {
|
|
288
|
+
dependencies.push({
|
|
289
|
+
type: 'import',
|
|
290
|
+
name: match[1],
|
|
291
|
+
line: line
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return dependencies;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Find exports in boundary
|
|
302
|
+
* @param {Array} lines - Lines within boundary
|
|
303
|
+
* @returns {Array} - Exports
|
|
304
|
+
*/
|
|
305
|
+
function findExports(lines) {
|
|
306
|
+
const exports = [];
|
|
307
|
+
const exportPatterns = [
|
|
308
|
+
/module\.exports\.(\w+)\s*=/,
|
|
309
|
+
/exports\.(\w+)\s*=/,
|
|
310
|
+
/export\s+default\s+(\w+)/,
|
|
311
|
+
/export\s+{\s*(\w+)\s*[,}]/,
|
|
312
|
+
/export\s+{\s*(\w+)\s+as\s+(\w+)\s*[,}]/
|
|
313
|
+
];
|
|
314
|
+
|
|
315
|
+
for (const line of lines) {
|
|
316
|
+
for (const pattern of exportPatterns) {
|
|
317
|
+
const match = line.match(pattern);
|
|
318
|
+
if (match) {
|
|
319
|
+
exports.push({
|
|
320
|
+
type: 'export',
|
|
321
|
+
name: match[1] || match[2],
|
|
322
|
+
line: line
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return exports;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
module.exports = {
|
|
332
|
+
findMethodBoundary,
|
|
333
|
+
findClassBoundary,
|
|
334
|
+
findModuleBoundary,
|
|
335
|
+
findBlockBoundary,
|
|
336
|
+
extractFunctionName,
|
|
337
|
+
extractClassName,
|
|
338
|
+
extractModuleName,
|
|
339
|
+
calculateBoundaryComplexity,
|
|
340
|
+
findDependencies,
|
|
341
|
+
findExports
|
|
342
|
+
};
|