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,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function Boundary Detection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { BOUNDARY_TYPES } = require('../boundary-types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Function boundary detector
|
|
9
|
+
*/
|
|
10
|
+
class FunctionDetector {
|
|
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: /(?:function\s+(\w+)\s*\(|const\s+(\w+)\s*=\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>)/g,
|
|
22
|
+
export: /(?:export\s+(?:default\s+)?(?:function|const|let|var)\s+(\w+))/g,
|
|
23
|
+
method: /(?:async\s+)?(\w+)\s*\([^)]*\)\s*{/g,
|
|
24
|
+
arrow: /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>/g
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Detect function boundaries
|
|
30
|
+
* @param {Array} lines - Source code lines
|
|
31
|
+
* @param {string} filePath - File path
|
|
32
|
+
* @returns {Array} Array of function boundaries
|
|
33
|
+
*/
|
|
34
|
+
detectFunctionBoundaries(lines, filePath) {
|
|
35
|
+
const boundaries = [];
|
|
36
|
+
const sourceCode = lines.join('\n');
|
|
37
|
+
|
|
38
|
+
// Find function declarations
|
|
39
|
+
const matches = [...sourceCode.matchAll(this.patterns.declaration)];
|
|
40
|
+
|
|
41
|
+
for (const match of matches) {
|
|
42
|
+
const functionName = match[1] || match[2];
|
|
43
|
+
if (functionName) {
|
|
44
|
+
const boundary = this.createBoundary(
|
|
45
|
+
BOUNDARY_TYPES.FUNCTION,
|
|
46
|
+
functionName,
|
|
47
|
+
lines,
|
|
48
|
+
filePath,
|
|
49
|
+
match.index
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (boundary) {
|
|
53
|
+
boundaries.push(boundary);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return boundaries;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Create boundary from detection
|
|
63
|
+
* @param {string} type - Boundary type
|
|
64
|
+
* @param {string} name - Boundary name
|
|
65
|
+
* @param {Array} lines - Source code lines
|
|
66
|
+
* @param {string} filePath - File path
|
|
67
|
+
* @param {number} startIndex - Start index in source
|
|
68
|
+
* @returns {Object|null} Boundary object or null
|
|
69
|
+
*/
|
|
70
|
+
createBoundary(type, name, lines, filePath, startIndex) {
|
|
71
|
+
const { startLine, endLine } = this.findBoundaryExtent(lines, startIndex, type);
|
|
72
|
+
|
|
73
|
+
if (startLine === -1 || endLine === -1) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const { ModuleBoundary } = require('../boundary-types');
|
|
78
|
+
const boundary = new ModuleBoundary(type, name, startLine + 1, endLine + 1, filePath);
|
|
79
|
+
|
|
80
|
+
// Basic analysis
|
|
81
|
+
this.analyzeBoundary(boundary, lines, startLine, endLine);
|
|
82
|
+
|
|
83
|
+
return boundary;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Find extent of a boundary
|
|
88
|
+
* @param {Array} lines - Source code lines
|
|
89
|
+
* @param {number} startIndex - Start index
|
|
90
|
+
* @param {string} type - Boundary type
|
|
91
|
+
* @returns {Object} Start and end line numbers
|
|
92
|
+
*/
|
|
93
|
+
findBoundaryExtent(lines, startIndex, type) {
|
|
94
|
+
let startLine = -1;
|
|
95
|
+
let endLine = -1;
|
|
96
|
+
let braceCount = 0;
|
|
97
|
+
let inString = false;
|
|
98
|
+
let stringChar = null;
|
|
99
|
+
|
|
100
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
101
|
+
const line = lines[i];
|
|
102
|
+
|
|
103
|
+
// Track string literals
|
|
104
|
+
for (let j = 0; j < line.length; j++) {
|
|
105
|
+
const char = line[j];
|
|
106
|
+
|
|
107
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
108
|
+
inString = true;
|
|
109
|
+
stringChar = char;
|
|
110
|
+
} else if (inString && char === stringChar) {
|
|
111
|
+
inString = false;
|
|
112
|
+
stringChar = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Skip lines inside strings
|
|
117
|
+
if (inString) continue;
|
|
118
|
+
|
|
119
|
+
// Count braces for block detection
|
|
120
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
121
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
122
|
+
|
|
123
|
+
braceCount += openBraces - closeBraces;
|
|
124
|
+
|
|
125
|
+
// Set start line on first detection
|
|
126
|
+
if (startLine === -1) {
|
|
127
|
+
startLine = i;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// End when braces are balanced and we're past start
|
|
131
|
+
if (braceCount <= 0 && i > startIndex) {
|
|
132
|
+
endLine = i;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { startLine, endLine };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Analyze boundary properties
|
|
142
|
+
* @param {Object} boundary - Boundary object
|
|
143
|
+
* @param {Array} lines - Source code lines
|
|
144
|
+
* @param {number} startLine - Start line number
|
|
145
|
+
* @param {number} endLine - End line number
|
|
146
|
+
*/
|
|
147
|
+
analyzeBoundary(boundary, lines, startLine, endLine) {
|
|
148
|
+
const boundaryLines = lines.slice(startLine, endLine + 1);
|
|
149
|
+
const sourceCode = boundaryLines.join('\n');
|
|
150
|
+
|
|
151
|
+
// Calculate complexity
|
|
152
|
+
const complexity = this.calculateComplexity(sourceCode);
|
|
153
|
+
boundary.setComplexity(complexity);
|
|
154
|
+
|
|
155
|
+
// Find dependencies
|
|
156
|
+
const dependencies = this.findDependencies(sourceCode);
|
|
157
|
+
for (const dep of dependencies) {
|
|
158
|
+
boundary.addDependency(dep);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Find exports
|
|
162
|
+
const exports = this.findExports(sourceCode, boundary.type);
|
|
163
|
+
for (const exp of exports) {
|
|
164
|
+
boundary.addExport(exp);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Calculate complexity score
|
|
170
|
+
* @param {string} sourceCode - Source code
|
|
171
|
+
* @returns {number} Complexity score
|
|
172
|
+
*/
|
|
173
|
+
calculateComplexity(sourceCode) {
|
|
174
|
+
let complexity = 0;
|
|
175
|
+
|
|
176
|
+
// Cyclomatic complexity indicators
|
|
177
|
+
complexity += (sourceCode.match(/if\s*\(/g) || []).length * 1;
|
|
178
|
+
complexity += (sourceCode.match(/else\s+if/g) || []).length * 1;
|
|
179
|
+
complexity += (sourceCode.match(/while\s*\(/g) || []).length * 2;
|
|
180
|
+
complexity += (sourceCode.match(/for\s*\(/g) || []).length * 2;
|
|
181
|
+
complexity += (sourceCode.match(/switch\s*\(/g) || []).length * 2;
|
|
182
|
+
complexity += (sourceCode.match(/catch\s*\(/g) || []).length * 2;
|
|
183
|
+
complexity += (sourceCode.match(/&&/g) || []).length * 1;
|
|
184
|
+
complexity += (sourceCode.match(/\|\|/g) || []).length * 1;
|
|
185
|
+
|
|
186
|
+
// Length complexity
|
|
187
|
+
const lineCount = sourceCode.split('\n').length;
|
|
188
|
+
if (lineCount > 50) complexity += 5;
|
|
189
|
+
if (lineCount > 100) complexity += 10;
|
|
190
|
+
if (lineCount > 200) complexity += 20;
|
|
191
|
+
|
|
192
|
+
return Math.min(100, complexity);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Find dependencies in boundary
|
|
197
|
+
* @param {string} sourceCode - Source code
|
|
198
|
+
* @returns {Array} Array of dependencies
|
|
199
|
+
*/
|
|
200
|
+
findDependencies(sourceCode) {
|
|
201
|
+
const dependencies = [];
|
|
202
|
+
|
|
203
|
+
// Import statements
|
|
204
|
+
const importMatches = sourceCode.match(/import\s+.+from\s+['"]([^'"]+)['"]/g);
|
|
205
|
+
if (importMatches) {
|
|
206
|
+
for (const match of importMatches) {
|
|
207
|
+
dependencies.push(match[1]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Require statements
|
|
212
|
+
const requireMatches = sourceCode.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
|
|
213
|
+
if (requireMatches) {
|
|
214
|
+
for (const match of requireMatches) {
|
|
215
|
+
dependencies.push(match[1]);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return [...new Set(dependencies)];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Find exports in boundary
|
|
224
|
+
* @param {string} sourceCode - Source code
|
|
225
|
+
* @param {string} type - Boundary type
|
|
226
|
+
* @returns {Array} Array of exports
|
|
227
|
+
*/
|
|
228
|
+
findExports(sourceCode, type) {
|
|
229
|
+
const exports = [];
|
|
230
|
+
|
|
231
|
+
if (type === BOUNDARY_TYPES.FUNCTION) {
|
|
232
|
+
// Look for explicit exports
|
|
233
|
+
const exportMatches = sourceCode.match(/export\s+(?:default\s+)?(?:\w+|\{[^}]+\})/g);
|
|
234
|
+
if (exportMatches) {
|
|
235
|
+
for (const match of exportMatches) {
|
|
236
|
+
const exportName = match.replace(/export\s+(?:default\s+)?/, '').trim();
|
|
237
|
+
if (exportName && exportName !== '{' && exportName !== '}') {
|
|
238
|
+
exports.push(exportName);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return exports;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
module.exports = FunctionDetector;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Boundary Detection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { BOUNDARY_TYPES } = require('../boundary-types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Module boundary detector
|
|
9
|
+
*/
|
|
10
|
+
class ModuleDetector {
|
|
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
|
+
export: /export\s+(?:\{([^}]+)\}|(?:default\s+)?(?:const|let|var|function|class)\s+(\w+))/g,
|
|
22
|
+
import: /import\s+(?:\{([^}]+)\}|(?:\*\s+as)?(\w+))/g
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Detect module boundaries
|
|
28
|
+
* @param {Array} lines - Source code lines
|
|
29
|
+
* @param {string} filePath - File path
|
|
30
|
+
* @returns {Array} Array of module boundaries
|
|
31
|
+
*/
|
|
32
|
+
detectModuleBoundaries(lines, filePath) {
|
|
33
|
+
const boundaries = [];
|
|
34
|
+
const sourceCode = lines.join('\n');
|
|
35
|
+
|
|
36
|
+
// Find export statements
|
|
37
|
+
const matches = [...sourceCode.matchAll(this.patterns.export)];
|
|
38
|
+
|
|
39
|
+
for (const match of matches) {
|
|
40
|
+
const exportNames = match[1] ? match[1].split(',').map(s => s.trim()) : [match[2]];
|
|
41
|
+
|
|
42
|
+
for (const exportName of exportNames) {
|
|
43
|
+
if (exportName && exportName !== 'default') {
|
|
44
|
+
const boundary = this.createBoundary(
|
|
45
|
+
BOUNDARY_TYPES.MODULE,
|
|
46
|
+
exportName,
|
|
47
|
+
lines,
|
|
48
|
+
filePath,
|
|
49
|
+
match.index
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (boundary) {
|
|
53
|
+
boundaries.push(boundary);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return boundaries;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create boundary from detection
|
|
64
|
+
* @param {string} type - Boundary type
|
|
65
|
+
* @param {string} name - Boundary name
|
|
66
|
+
* @param {Array} lines - Source code lines
|
|
67
|
+
* @param {string} filePath - File path
|
|
68
|
+
* @param {number} startIndex - Start index in source
|
|
69
|
+
* @returns {Object|null} Boundary object or null
|
|
70
|
+
*/
|
|
71
|
+
createBoundary(type, name, lines, filePath, startIndex) {
|
|
72
|
+
const { startLine, endLine } = this.findBoundaryExtent(lines, startIndex, type);
|
|
73
|
+
|
|
74
|
+
if (startLine === -1 || endLine === -1) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const { ModuleBoundary } = require('../boundary-types');
|
|
79
|
+
const boundary = new ModuleBoundary(type, name, startLine + 1, endLine + 1, filePath);
|
|
80
|
+
|
|
81
|
+
// Basic analysis
|
|
82
|
+
this.analyzeBoundary(boundary, lines, startLine, endLine);
|
|
83
|
+
|
|
84
|
+
return boundary;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Find extent of a boundary
|
|
89
|
+
* @param {Array} lines - Source code lines
|
|
90
|
+
* @param {number} startIndex - Start index
|
|
91
|
+
* @param {string} type - Boundary type
|
|
92
|
+
* @returns {Object} Start and end line numbers
|
|
93
|
+
*/
|
|
94
|
+
findBoundaryExtent(lines, startIndex, type) {
|
|
95
|
+
let startLine = -1;
|
|
96
|
+
let endLine = -1;
|
|
97
|
+
let braceCount = 0;
|
|
98
|
+
let inString = false;
|
|
99
|
+
let stringChar = null;
|
|
100
|
+
|
|
101
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
102
|
+
const line = lines[i];
|
|
103
|
+
|
|
104
|
+
// Track string literals
|
|
105
|
+
for (let j = 0; j < line.length; j++) {
|
|
106
|
+
const char = line[j];
|
|
107
|
+
|
|
108
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
109
|
+
inString = true;
|
|
110
|
+
stringChar = char;
|
|
111
|
+
} else if (inString && char === stringChar) {
|
|
112
|
+
inString = false;
|
|
113
|
+
stringChar = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Skip lines inside strings
|
|
118
|
+
if (inString) continue;
|
|
119
|
+
|
|
120
|
+
// Count braces for block detection
|
|
121
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
122
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
123
|
+
|
|
124
|
+
braceCount += openBraces - closeBraces;
|
|
125
|
+
|
|
126
|
+
// Set start line on first detection
|
|
127
|
+
if (startLine === -1) {
|
|
128
|
+
startLine = i;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// End when braces are balanced and we're past start
|
|
132
|
+
if (braceCount <= 0 && i > startIndex) {
|
|
133
|
+
endLine = i;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return { startLine, endLine };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Analyze boundary properties
|
|
143
|
+
* @param {Object} boundary - Boundary object
|
|
144
|
+
* @param {Array} lines - Source code lines
|
|
145
|
+
* @param {number} startLine - Start line number
|
|
146
|
+
* @param {number} endLine - End line number
|
|
147
|
+
*/
|
|
148
|
+
analyzeBoundary(boundary, lines, startLine, endLine) {
|
|
149
|
+
const boundaryLines = lines.slice(startLine, endLine + 1);
|
|
150
|
+
const sourceCode = boundaryLines.join('\n');
|
|
151
|
+
|
|
152
|
+
// Calculate complexity
|
|
153
|
+
const complexity = this.calculateComplexity(sourceCode);
|
|
154
|
+
boundary.setComplexity(complexity);
|
|
155
|
+
|
|
156
|
+
// Find dependencies
|
|
157
|
+
const dependencies = this.findDependencies(sourceCode);
|
|
158
|
+
for (const dep of dependencies) {
|
|
159
|
+
boundary.addDependency(dep);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Find exports
|
|
163
|
+
const exports = this.findExports(sourceCode, boundary.type);
|
|
164
|
+
for (const exp of exports) {
|
|
165
|
+
boundary.addExport(exp);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Calculate complexity score
|
|
171
|
+
* @param {string} sourceCode - Source code
|
|
172
|
+
* @returns {number} Complexity score
|
|
173
|
+
*/
|
|
174
|
+
calculateComplexity(sourceCode) {
|
|
175
|
+
let complexity = 0;
|
|
176
|
+
|
|
177
|
+
// Cyclomatic complexity indicators
|
|
178
|
+
complexity += (sourceCode.match(/if\s*\(/g) || []).length * 1;
|
|
179
|
+
complexity += (sourceCode.match(/else\s+if/g) || []).length * 1;
|
|
180
|
+
complexity += (sourceCode.match(/while\s*\(/g) || []).length * 2;
|
|
181
|
+
complexity += (sourceCode.match(/for\s*\(/g) || []).length * 2;
|
|
182
|
+
complexity += (sourceCode.match(/switch\s*\(/g) || []).length * 2;
|
|
183
|
+
complexity += (sourceCode.match(/catch\s*\(/g) || []).length * 2;
|
|
184
|
+
complexity += (sourceCode.match(/&&/g) || []).length * 1;
|
|
185
|
+
complexity += (sourceCode.match(/\|\|/g) || []).length * 1;
|
|
186
|
+
|
|
187
|
+
// Length complexity
|
|
188
|
+
const lineCount = sourceCode.split('\n').length;
|
|
189
|
+
if (lineCount > 50) complexity += 5;
|
|
190
|
+
if (lineCount > 100) complexity += 10;
|
|
191
|
+
if (lineCount > 200) complexity += 20;
|
|
192
|
+
|
|
193
|
+
return Math.min(100, complexity);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Find dependencies in boundary
|
|
198
|
+
* @param {string} sourceCode - Source code
|
|
199
|
+
* @returns {Array} Array of dependencies
|
|
200
|
+
*/
|
|
201
|
+
findDependencies(sourceCode) {
|
|
202
|
+
const dependencies = [];
|
|
203
|
+
|
|
204
|
+
// Import statements
|
|
205
|
+
const importMatches = sourceCode.match(/import\s+.+from\s+['"]([^'"]+)['"]/g);
|
|
206
|
+
if (importMatches) {
|
|
207
|
+
for (const match of importMatches) {
|
|
208
|
+
dependencies.push(match[1]);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Require statements
|
|
213
|
+
const requireMatches = sourceCode.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
|
|
214
|
+
if (requireMatches) {
|
|
215
|
+
for (const match of requireMatches) {
|
|
216
|
+
dependencies.push(match[1]);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return [...new Set(dependencies)];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Find exports in boundary
|
|
225
|
+
* @param {string} sourceCode - Source code
|
|
226
|
+
* @param {string} type - Boundary type
|
|
227
|
+
* @returns {Array} Array of exports
|
|
228
|
+
*/
|
|
229
|
+
findExports(sourceCode, type) {
|
|
230
|
+
const exports = [];
|
|
231
|
+
|
|
232
|
+
if (type === BOUNDARY_TYPES.MODULE) {
|
|
233
|
+
// Look for explicit exports
|
|
234
|
+
const exportMatches = sourceCode.match(/export\s+(?:default\s+)?(?:\w+|\{[^}]+\})/g);
|
|
235
|
+
if (exportMatches) {
|
|
236
|
+
for (const match of exportMatches) {
|
|
237
|
+
const exportName = match.replace(/export\s+(?:default\s+)?/, '').trim();
|
|
238
|
+
if (exportName && exportName !== '{' && exportName !== '}') {
|
|
239
|
+
exports.push(exportName);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return exports;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
module.exports = ModuleDetector;
|