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,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boundary Analysis Logic
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { COHESION_LEVELS } = require('../boundary-types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Boundary analysis utilities
|
|
9
|
+
*/
|
|
10
|
+
class BoundaryAnalyzers {
|
|
11
|
+
/**
|
|
12
|
+
* Analyze a boundary and calculate metrics
|
|
13
|
+
* @param {Object} boundary - Boundary object
|
|
14
|
+
* @param {Array} lines - Source code lines
|
|
15
|
+
* @param {number} startLine - Start line number
|
|
16
|
+
* @param {number} endLine - End line number
|
|
17
|
+
*/
|
|
18
|
+
analyzeBoundary(boundary, lines, startLine, endLine) {
|
|
19
|
+
const boundaryLines = lines.slice(startLine, endLine + 1);
|
|
20
|
+
const sourceCode = boundaryLines.join('\n');
|
|
21
|
+
|
|
22
|
+
// Calculate complexity metrics
|
|
23
|
+
boundary.complexity = this.calculateComplexity(sourceCode);
|
|
24
|
+
boundary.maxNesting = this.calculateMaxNesting(sourceCode);
|
|
25
|
+
|
|
26
|
+
// Find dependencies and exports
|
|
27
|
+
boundary.dependencies = this.findDependencies(sourceCode);
|
|
28
|
+
boundary.exports = this.findExports(sourceCode, boundary.type);
|
|
29
|
+
|
|
30
|
+
// Calculate cohesion and extractability
|
|
31
|
+
boundary.cohesion = this.calculateCohesion(boundary, boundaryLines);
|
|
32
|
+
boundary.hasClearPurpose = this.hasClearPurpose(boundary, boundaryLines);
|
|
33
|
+
boundary.isExtractable = this.isExtractable(boundary, boundaryLines);
|
|
34
|
+
|
|
35
|
+
// Calculate confidence
|
|
36
|
+
boundary.confidence = this.calculateConfidence(boundary);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Calculate cyclomatic complexity
|
|
41
|
+
* @param {string} sourceCode - Source code
|
|
42
|
+
* @returns {number} Complexity score
|
|
43
|
+
*/
|
|
44
|
+
calculateComplexity(sourceCode) {
|
|
45
|
+
let complexity = 0;
|
|
46
|
+
|
|
47
|
+
// Cyclomatic complexity indicators
|
|
48
|
+
const complexityPatterns = [
|
|
49
|
+
/\bif\b/g,
|
|
50
|
+
/\belse\s+if\b/g,
|
|
51
|
+
/\bfor\b/g,
|
|
52
|
+
/\bwhile\b/g,
|
|
53
|
+
/\bdo\b/g,
|
|
54
|
+
/\bswitch\b/g,
|
|
55
|
+
/\bcase\b/g,
|
|
56
|
+
/\bcatch\b/g,
|
|
57
|
+
/\b&&\b/g,
|
|
58
|
+
/\|\|\|/g,
|
|
59
|
+
/\?/g
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
for (const pattern of complexityPatterns) {
|
|
63
|
+
const matches = sourceCode.match(pattern);
|
|
64
|
+
if (matches) {
|
|
65
|
+
complexity += matches.length;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Base complexity is 1
|
|
70
|
+
return complexity + 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Calculate maximum nesting level
|
|
75
|
+
* @param {string} sourceCode - Source code
|
|
76
|
+
* @returns {number} Maximum nesting level
|
|
77
|
+
*/
|
|
78
|
+
calculateMaxNesting(sourceCode) {
|
|
79
|
+
let maxNesting = 0;
|
|
80
|
+
let currentNesting = 0;
|
|
81
|
+
let inString = false;
|
|
82
|
+
let stringChar = '';
|
|
83
|
+
|
|
84
|
+
for (let i = 0; i < sourceCode.length; i++) {
|
|
85
|
+
const char = sourceCode[i];
|
|
86
|
+
|
|
87
|
+
if (!inString) {
|
|
88
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
89
|
+
inString = true;
|
|
90
|
+
stringChar = char;
|
|
91
|
+
} else if (char === '{') {
|
|
92
|
+
currentNesting++;
|
|
93
|
+
maxNesting = Math.max(maxNesting, currentNesting);
|
|
94
|
+
} else if (char === '}') {
|
|
95
|
+
currentNesting--;
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
if (char === stringChar) {
|
|
99
|
+
inString = false;
|
|
100
|
+
stringChar = '';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return maxNesting;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Find dependencies in source code
|
|
110
|
+
* @param {string} sourceCode - Source code
|
|
111
|
+
* @returns {Array} Array of dependencies
|
|
112
|
+
*/
|
|
113
|
+
findDependencies(sourceCode) {
|
|
114
|
+
const dependencies = [];
|
|
115
|
+
|
|
116
|
+
// Import statements
|
|
117
|
+
const importMatches = sourceCode.match(/import\s+.*?from\s+['"`]([^'"`]+)['"`]/g);
|
|
118
|
+
if (importMatches) {
|
|
119
|
+
for (const importStatement of importMatches) {
|
|
120
|
+
const match = importStatement.match(/from\s+['"`]([^'"`]+)['"`]/);
|
|
121
|
+
if (match) {
|
|
122
|
+
dependencies.push(match[1]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Require statements
|
|
128
|
+
const requireMatches = sourceCode.match(/require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g);
|
|
129
|
+
if (requireMatches) {
|
|
130
|
+
for (const requireStatement of requireMatches) {
|
|
131
|
+
const match = requireStatement.match(/require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/);
|
|
132
|
+
if (match) {
|
|
133
|
+
dependencies.push(match[1]);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return [...new Set(dependencies)]; // Remove duplicates
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Find exports in source code
|
|
143
|
+
* @param {string} sourceCode - Source code
|
|
144
|
+
* @param {string} type - Boundary type
|
|
145
|
+
* @returns {Array} Array of exports
|
|
146
|
+
*/
|
|
147
|
+
findExports(sourceCode, type) {
|
|
148
|
+
const exports = [];
|
|
149
|
+
|
|
150
|
+
if (type === 'function' || type === 'class') {
|
|
151
|
+
// Export statements
|
|
152
|
+
const exportMatches = sourceCode.match(/export\s+(?:default\s+)?(?:function|class|const|let|var)\s+(\w+)/g);
|
|
153
|
+
if (exportMatches) {
|
|
154
|
+
for (const exportStatement of exportMatches) {
|
|
155
|
+
const match = exportStatement.match(/(?:function|class|const|let|var)\s+(\w+)/);
|
|
156
|
+
if (match) {
|
|
157
|
+
exports.push(match[1]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return exports;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Calculate cohesion score
|
|
168
|
+
* @param {Object} boundary - Boundary object
|
|
169
|
+
* @param {Array} lines - Boundary lines
|
|
170
|
+
* @returns {string} Cohesion level
|
|
171
|
+
*/
|
|
172
|
+
calculateCohesion(boundary, lines) {
|
|
173
|
+
let cohesionScore = 0;
|
|
174
|
+
|
|
175
|
+
// Single responsibility (high cohesion)
|
|
176
|
+
if (boundary.lineCount < 50) {
|
|
177
|
+
cohesionScore += 2;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Low complexity (high cohesion)
|
|
181
|
+
if (boundary.complexity < 10) {
|
|
182
|
+
cohesionScore += 2;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Low nesting (high cohesion)
|
|
186
|
+
if (boundary.maxNesting < 3) {
|
|
187
|
+
cohesionScore += 2;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Clear purpose (high cohesion)
|
|
191
|
+
if (boundary.hasClearPurpose) {
|
|
192
|
+
cohesionScore += 2;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Few dependencies (high cohesion)
|
|
196
|
+
if (boundary.dependencies.length < 5) {
|
|
197
|
+
cohesionScore += 2;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Convert score to cohesion level
|
|
201
|
+
if (cohesionScore >= 8) {
|
|
202
|
+
return COHESION_LEVELS.HIGH;
|
|
203
|
+
} else if (cohesionScore >= 5) {
|
|
204
|
+
return COHESION_LEVELS.MEDIUM;
|
|
205
|
+
} else {
|
|
206
|
+
return COHESION_LEVELS.LOW;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Check if boundary has clear purpose
|
|
212
|
+
* @param {Object} boundary - Boundary object
|
|
213
|
+
* @param {Array} lines - Boundary lines
|
|
214
|
+
* @returns {boolean} Whether boundary has clear purpose
|
|
215
|
+
*/
|
|
216
|
+
hasClearPurpose(boundary, lines) {
|
|
217
|
+
const sourceCode = lines.join('\n');
|
|
218
|
+
|
|
219
|
+
// Check for comments explaining purpose
|
|
220
|
+
const hasComments = /\/\*\*[\s\S]*?\*\/|\/\/.*$/gm.test(sourceCode);
|
|
221
|
+
|
|
222
|
+
// Check for meaningful name
|
|
223
|
+
const hasMeaningfulName = boundary.name.length > 2 &&
|
|
224
|
+
!/^(temp|tmp|test|data|item|obj)/.test(boundary.name.toLowerCase());
|
|
225
|
+
|
|
226
|
+
// Check for single responsibility
|
|
227
|
+
const hasSingleResponsibility = boundary.complexity < 15 && boundary.lineCount < 100;
|
|
228
|
+
|
|
229
|
+
return hasComments || (hasMeaningfulName && hasSingleResponsibility);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Check if boundary is extractable
|
|
234
|
+
* @param {Object} boundary - Boundary object
|
|
235
|
+
* @param {Array} lines - Boundary lines
|
|
236
|
+
* @returns {boolean} Whether boundary is extractable
|
|
237
|
+
*/
|
|
238
|
+
isExtractable(boundary, lines) {
|
|
239
|
+
// Must have clear boundaries
|
|
240
|
+
if (boundary.lineCount < 5) return false;
|
|
241
|
+
|
|
242
|
+
// Must not be too complex
|
|
243
|
+
if (boundary.complexity > 20) return false;
|
|
244
|
+
|
|
245
|
+
// Must have clear purpose
|
|
246
|
+
if (!boundary.hasClearPurpose) return false;
|
|
247
|
+
|
|
248
|
+
// Must have reasonable dependencies
|
|
249
|
+
if (boundary.dependencies.length > 10) return false;
|
|
250
|
+
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Calculate confidence score
|
|
256
|
+
* @param {Object} boundary - Boundary object
|
|
257
|
+
* @returns {number} Confidence score (0-1)
|
|
258
|
+
*/
|
|
259
|
+
calculateConfidence(boundary) {
|
|
260
|
+
let confidence = 0.5; // Base confidence
|
|
261
|
+
|
|
262
|
+
// Increase confidence for clear boundaries
|
|
263
|
+
if (boundary.hasClearPurpose) {
|
|
264
|
+
confidence += 0.2;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Increase confidence for extractable boundaries
|
|
268
|
+
if (boundary.isExtractable) {
|
|
269
|
+
confidence += 0.2;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Increase confidence for high cohesion
|
|
273
|
+
if (boundary.cohesion === COHESION_LEVELS.HIGH) {
|
|
274
|
+
confidence += 0.1;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return Math.min(confidence, 1.0);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
module.exports = { BoundaryAnalyzers };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Boundary Detection Logic
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { BOUNDARY_TYPES, COHESION_LEVELS } = require('../boundary-types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Core boundary detector class with main detection logic
|
|
9
|
+
*/
|
|
10
|
+
class BoundaryCore {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.patterns = this.initializePatterns();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Initialize detection patterns
|
|
17
|
+
* @returns {Object} Detection patterns
|
|
18
|
+
*/
|
|
19
|
+
initializePatterns() {
|
|
20
|
+
return {
|
|
21
|
+
// Function patterns
|
|
22
|
+
function: {
|
|
23
|
+
declaration: /(?:function\s+(\w+)\s*\(|const\s+(\w+)\s*=\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))/g,
|
|
24
|
+
export: /(?:export\s+(?:default\s+)?(?:function|const|let|var)\s+(\w+))/g,
|
|
25
|
+
method: /(?:async\s+)?(\w+)\s*\([^)]*\)\s*{/g,
|
|
26
|
+
arrow: /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>/g
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Class patterns
|
|
30
|
+
class: {
|
|
31
|
+
declaration: /(?:class\s+(\w+)|export\s+(?:default\s+)?class\s+(\w+))/g,
|
|
32
|
+
method: /(?:async\s+)?(\w+)\s*\([^)]*\)\s*{/g,
|
|
33
|
+
property: /(\w+)\s*[=:]/g
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// Object patterns
|
|
37
|
+
object: {
|
|
38
|
+
declaration: /(?:const|let|var)\s+(\w+)\s*=\s*{/g,
|
|
39
|
+
property: /(\w+)\s*:/g,
|
|
40
|
+
method: /(\w+)\s*\([^)]*\)\s*{/g
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Module patterns
|
|
44
|
+
module: {
|
|
45
|
+
export: /export\s+(?:\{([^}]+)\}|(?:default\s+)?(?:const|let|var|function|class)\s+(\w+))/g,
|
|
46
|
+
import: /import\s+(?:\{([^}]+)\}|(?:\*\s+as)?(\w+))/g
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Detect all boundaries in source code
|
|
53
|
+
* @param {string} sourceCode - Source code to analyze
|
|
54
|
+
* @param {string} filePath - File path
|
|
55
|
+
* @returns {Array} Array of detected boundaries
|
|
56
|
+
*/
|
|
57
|
+
detectBoundaries(sourceCode, filePath) {
|
|
58
|
+
const lines = sourceCode.split('\n');
|
|
59
|
+
const boundaries = [];
|
|
60
|
+
|
|
61
|
+
// Detect different types of boundaries
|
|
62
|
+
boundaries.push(...this.detectFunctionBoundaries(lines, filePath));
|
|
63
|
+
boundaries.push(...this.detectClassBoundaries(lines, filePath));
|
|
64
|
+
boundaries.push(...this.detectObjectBoundaries(lines, filePath));
|
|
65
|
+
boundaries.push(...this.detectModuleBoundaries(lines, filePath));
|
|
66
|
+
boundaries.push(...this.detectUtilityBoundaries(lines, filePath));
|
|
67
|
+
boundaries.push(...this.detectConfigBoundaries(lines, filePath));
|
|
68
|
+
boundaries.push(...this.detectConstantBoundaries(lines, filePath));
|
|
69
|
+
|
|
70
|
+
return boundaries;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Create a boundary object
|
|
75
|
+
* @param {string} type - Boundary type
|
|
76
|
+
* @param {string} name - Boundary name
|
|
77
|
+
* @param {Array} lines - Source code lines
|
|
78
|
+
* @param {string} filePath - File path
|
|
79
|
+
* @param {number} startIndex - Start index in source
|
|
80
|
+
* @returns {Object|null} Boundary object or null
|
|
81
|
+
*/
|
|
82
|
+
createBoundary(type, name, lines, filePath, startIndex) {
|
|
83
|
+
const { startLine, endLine } = this.findBoundaryExtent(lines, startIndex, type);
|
|
84
|
+
|
|
85
|
+
if (startLine === -1 || endLine === -1) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const boundary = {
|
|
90
|
+
type,
|
|
91
|
+
name,
|
|
92
|
+
filePath,
|
|
93
|
+
startLine,
|
|
94
|
+
endLine,
|
|
95
|
+
lineCount: endLine - startLine + 1,
|
|
96
|
+
startIndex,
|
|
97
|
+
complexity: 0,
|
|
98
|
+
maxNesting: 0,
|
|
99
|
+
dependencies: [],
|
|
100
|
+
exports: [],
|
|
101
|
+
cohesion: COHESION_LEVELS.UNKNOWN,
|
|
102
|
+
hasClearPurpose: false,
|
|
103
|
+
isExtractable: false,
|
|
104
|
+
confidence: 0
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Analyze the boundary
|
|
108
|
+
this.analyzeBoundary(boundary, lines, startLine, endLine);
|
|
109
|
+
|
|
110
|
+
return boundary;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Find the extent of a boundary (start and end lines)
|
|
115
|
+
* @param {Array} lines - Source code lines
|
|
116
|
+
* @param {number} startIndex - Start index
|
|
117
|
+
* @param {string} type - Boundary type
|
|
118
|
+
* @returns {Object} Start and end line numbers
|
|
119
|
+
*/
|
|
120
|
+
findBoundaryExtent(lines, startIndex, type) {
|
|
121
|
+
let startLine = -1;
|
|
122
|
+
let endLine = -1;
|
|
123
|
+
let braceCount = 0;
|
|
124
|
+
let inString = false;
|
|
125
|
+
let stringChar = '';
|
|
126
|
+
|
|
127
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
128
|
+
const line = lines[i];
|
|
129
|
+
|
|
130
|
+
// Track string boundaries
|
|
131
|
+
for (let j = 0; j < line.length; j++) {
|
|
132
|
+
const char = line[j];
|
|
133
|
+
|
|
134
|
+
if (!inString) {
|
|
135
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
136
|
+
inString = true;
|
|
137
|
+
stringChar = char;
|
|
138
|
+
} else if (char === '{') {
|
|
139
|
+
braceCount++;
|
|
140
|
+
if (startLine === -1) {
|
|
141
|
+
startLine = i;
|
|
142
|
+
}
|
|
143
|
+
} else if (char === '}') {
|
|
144
|
+
braceCount--;
|
|
145
|
+
if (braceCount === 0 && startLine !== -1) {
|
|
146
|
+
endLine = i;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
if (char === stringChar) {
|
|
152
|
+
inString = false;
|
|
153
|
+
stringChar = '';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (endLine !== -1) {
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return { startLine, endLine };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = { BoundaryCore };
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class Boundary Detection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { BOUNDARY_TYPES } = require('../boundary-types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Class boundary detector
|
|
9
|
+
*/
|
|
10
|
+
class ClassDetector {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.patterns = this.initializePatterns();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Initialize detection patterns
|
|
17
|
+
* @returns {Object} Detection patterns
|
|
18
|
+
*/
|
|
19
|
+
initializePatterns() {
|
|
20
|
+
return {
|
|
21
|
+
declaration: /(?:class\s+(\w+)|export\s+(?:default\s+)?class\s+(\w+))/g,
|
|
22
|
+
method: /(?:async\s+)?(\w+)\s*\([^)]*\)\s*{/g,
|
|
23
|
+
property: /(\w+)\s*[=:]/g
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Detect class boundaries
|
|
29
|
+
* @param {Array} lines - Source code lines
|
|
30
|
+
* @param {string} filePath - File path
|
|
31
|
+
* @returns {Array} Array of class boundaries
|
|
32
|
+
*/
|
|
33
|
+
detectClassBoundaries(lines, filePath) {
|
|
34
|
+
const boundaries = [];
|
|
35
|
+
const sourceCode = lines.join('\n');
|
|
36
|
+
|
|
37
|
+
// Find class declarations
|
|
38
|
+
const matches = [...sourceCode.matchAll(this.patterns.declaration)];
|
|
39
|
+
|
|
40
|
+
for (const match of matches) {
|
|
41
|
+
const className = match[1] || match[2];
|
|
42
|
+
if (className) {
|
|
43
|
+
const boundary = this.createBoundary(
|
|
44
|
+
BOUNDARY_TYPES.CLASS,
|
|
45
|
+
className,
|
|
46
|
+
lines,
|
|
47
|
+
filePath,
|
|
48
|
+
match.index
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (boundary) {
|
|
52
|
+
boundaries.push(boundary);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return boundaries;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Create boundary from detection
|
|
62
|
+
* @param {string} type - Boundary type
|
|
63
|
+
* @param {string} name - Boundary name
|
|
64
|
+
* @param {Array} lines - Source code lines
|
|
65
|
+
* @param {string} filePath - File path
|
|
66
|
+
* @param {number} startIndex - Start index in source
|
|
67
|
+
* @returns {Object|null} Boundary object or null
|
|
68
|
+
*/
|
|
69
|
+
createBoundary(type, name, lines, filePath, startIndex) {
|
|
70
|
+
const { startLine, endLine } = this.findBoundaryExtent(lines, startIndex, type);
|
|
71
|
+
|
|
72
|
+
if (startLine === -1 || endLine === -1) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const { ModuleBoundary } = require('../boundary-types');
|
|
77
|
+
const boundary = new ModuleBoundary(type, name, startLine + 1, endLine + 1, filePath);
|
|
78
|
+
|
|
79
|
+
// Basic analysis
|
|
80
|
+
this.analyzeBoundary(boundary, lines, startLine, endLine);
|
|
81
|
+
|
|
82
|
+
return boundary;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Find extent of a boundary
|
|
87
|
+
* @param {Array} lines - Source code lines
|
|
88
|
+
* @param {number} startIndex - Start index
|
|
89
|
+
* @param {string} type - Boundary type
|
|
90
|
+
* @returns {Object} Start and end line numbers
|
|
91
|
+
*/
|
|
92
|
+
findBoundaryExtent(lines, startIndex, type) {
|
|
93
|
+
let startLine = -1;
|
|
94
|
+
let endLine = -1;
|
|
95
|
+
let braceCount = 0;
|
|
96
|
+
let inString = false;
|
|
97
|
+
let stringChar = null;
|
|
98
|
+
|
|
99
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
100
|
+
const line = lines[i];
|
|
101
|
+
|
|
102
|
+
// Track string literals
|
|
103
|
+
for (let j = 0; j < line.length; j++) {
|
|
104
|
+
const char = line[j];
|
|
105
|
+
|
|
106
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
107
|
+
inString = true;
|
|
108
|
+
stringChar = char;
|
|
109
|
+
} else if (inString && char === stringChar) {
|
|
110
|
+
inString = false;
|
|
111
|
+
stringChar = null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Skip lines inside strings
|
|
116
|
+
if (inString) continue;
|
|
117
|
+
|
|
118
|
+
// Count braces for block detection
|
|
119
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
120
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
121
|
+
|
|
122
|
+
braceCount += openBraces - closeBraces;
|
|
123
|
+
|
|
124
|
+
// Set start line on first detection
|
|
125
|
+
if (startLine === -1) {
|
|
126
|
+
startLine = i;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// End when braces are balanced and we're past start
|
|
130
|
+
if (braceCount <= 0 && i > startIndex) {
|
|
131
|
+
endLine = i;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { startLine, endLine };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Analyze boundary properties
|
|
141
|
+
* @param {Object} boundary - Boundary object
|
|
142
|
+
* @param {Array} lines - Source code lines
|
|
143
|
+
* @param {number} startLine - Start line number
|
|
144
|
+
* @param {number} endLine - End line number
|
|
145
|
+
*/
|
|
146
|
+
analyzeBoundary(boundary, lines, startLine, endLine) {
|
|
147
|
+
const boundaryLines = lines.slice(startLine, endLine + 1);
|
|
148
|
+
const sourceCode = boundaryLines.join('\n');
|
|
149
|
+
|
|
150
|
+
// Calculate complexity
|
|
151
|
+
const complexity = this.calculateComplexity(sourceCode);
|
|
152
|
+
boundary.setComplexity(complexity);
|
|
153
|
+
|
|
154
|
+
// Find dependencies
|
|
155
|
+
const dependencies = this.findDependencies(sourceCode);
|
|
156
|
+
for (const dep of dependencies) {
|
|
157
|
+
boundary.addDependency(dep);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Find exports
|
|
161
|
+
const exports = this.findExports(sourceCode, boundary.type);
|
|
162
|
+
for (const exp of exports) {
|
|
163
|
+
boundary.addExport(exp);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Calculate complexity score
|
|
169
|
+
* @param {string} sourceCode - Source code
|
|
170
|
+
* @returns {number} Complexity score
|
|
171
|
+
*/
|
|
172
|
+
calculateComplexity(sourceCode) {
|
|
173
|
+
let complexity = 0;
|
|
174
|
+
|
|
175
|
+
// Cyclomatic complexity indicators
|
|
176
|
+
complexity += (sourceCode.match(/if\s*\(/g) || []).length * 1;
|
|
177
|
+
complexity += (sourceCode.match(/else\s+if/g) || []).length * 1;
|
|
178
|
+
complexity += (sourceCode.match(/while\s*\(/g) || []).length * 2;
|
|
179
|
+
complexity += (sourceCode.match(/for\s*\(/g) || []).length * 2;
|
|
180
|
+
complexity += (sourceCode.match(/switch\s*\(/g) || []).length * 2;
|
|
181
|
+
complexity += (sourceCode.match(/catch\s*\(/g) || []).length * 2;
|
|
182
|
+
complexity += (sourceCode.match(/&&/g) || []).length * 1;
|
|
183
|
+
complexity += (sourceCode.match(/\|\|/g) || []).length * 1;
|
|
184
|
+
|
|
185
|
+
// Length complexity
|
|
186
|
+
const lineCount = sourceCode.split('\n').length;
|
|
187
|
+
if (lineCount > 50) complexity += 5;
|
|
188
|
+
if (lineCount > 100) complexity += 10;
|
|
189
|
+
if (lineCount > 200) complexity += 20;
|
|
190
|
+
|
|
191
|
+
return Math.min(100, complexity);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Find dependencies in boundary
|
|
196
|
+
* @param {string} sourceCode - Source code
|
|
197
|
+
* @returns {Array} Array of dependencies
|
|
198
|
+
*/
|
|
199
|
+
findDependencies(sourceCode) {
|
|
200
|
+
const dependencies = [];
|
|
201
|
+
|
|
202
|
+
// Import statements
|
|
203
|
+
const importMatches = sourceCode.match(/import\s+.+from\s+['"]([^'"]+)['"]/g);
|
|
204
|
+
if (importMatches) {
|
|
205
|
+
for (const match of importMatches) {
|
|
206
|
+
dependencies.push(match[1]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Require statements
|
|
211
|
+
const requireMatches = sourceCode.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
|
|
212
|
+
if (requireMatches) {
|
|
213
|
+
for (const match of requireMatches) {
|
|
214
|
+
dependencies.push(match[1]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return [...new Set(dependencies)];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Find exports in boundary
|
|
223
|
+
* @param {string} sourceCode - Source code
|
|
224
|
+
* @param {string} type - Boundary type
|
|
225
|
+
* @returns {Array} Array of exports
|
|
226
|
+
*/
|
|
227
|
+
findExports(sourceCode, type) {
|
|
228
|
+
const exports = [];
|
|
229
|
+
|
|
230
|
+
if (type === BOUNDARY_TYPES.CLASS) {
|
|
231
|
+
// Look for explicit exports
|
|
232
|
+
const exportMatches = sourceCode.match(/export\s+(?:default\s+)?(?:\w+|\{[^}]+\})/g);
|
|
233
|
+
if (exportMatches) {
|
|
234
|
+
for (const match of exportMatches) {
|
|
235
|
+
const exportName = match.replace(/export\s+(?:default\s+)?/, '').trim();
|
|
236
|
+
if (exportName && exportName !== '{' && exportName !== '}') {
|
|
237
|
+
exports.push(exportName);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return exports;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
module.exports = ClassDetector;
|