vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642
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/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,741 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boundary Detection Algorithms
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { BOUNDARY_TYPES, COHESION_LEVELS } = require('./boundary-types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Boundary detector class
|
|
9
|
+
*/
|
|
10
|
+
class BoundaryDetector {
|
|
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 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 function boundaries
|
|
62
|
+
boundaries.push(...this.detectFunctionBoundaries(lines, filePath));
|
|
63
|
+
|
|
64
|
+
// Detect class boundaries
|
|
65
|
+
boundaries.push(...this.detectClassBoundaries(lines, filePath));
|
|
66
|
+
|
|
67
|
+
// Detect object boundaries
|
|
68
|
+
boundaries.push(...this.detectObjectBoundaries(lines, filePath));
|
|
69
|
+
|
|
70
|
+
// Detect module boundaries
|
|
71
|
+
boundaries.push(...this.detectModuleBoundaries(lines, filePath));
|
|
72
|
+
|
|
73
|
+
// Detect utility boundaries
|
|
74
|
+
boundaries.push(...this.detectUtilityBoundaries(lines, filePath));
|
|
75
|
+
|
|
76
|
+
// Detect config boundaries
|
|
77
|
+
boundaries.push(...this.detectConfigBoundaries(lines, filePath));
|
|
78
|
+
|
|
79
|
+
// Detect constant boundaries
|
|
80
|
+
boundaries.push(...this.detectConstantBoundaries(lines, filePath));
|
|
81
|
+
|
|
82
|
+
return boundaries;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Detect function boundaries
|
|
87
|
+
* @param {Array} lines - Source code lines
|
|
88
|
+
* @param {string} filePath - File path
|
|
89
|
+
* @returns {Array} Array of function boundaries
|
|
90
|
+
*/
|
|
91
|
+
detectFunctionBoundaries(lines, filePath) {
|
|
92
|
+
const boundaries = [];
|
|
93
|
+
const sourceCode = lines.join('\n');
|
|
94
|
+
|
|
95
|
+
// Find function declarations
|
|
96
|
+
const matches = [...sourceCode.matchAll(this.patterns.function.declaration)];
|
|
97
|
+
|
|
98
|
+
for (const match of matches) {
|
|
99
|
+
const functionName = match[1] || match[2];
|
|
100
|
+
if (functionName) {
|
|
101
|
+
const boundary = this.createBoundary(
|
|
102
|
+
BOUNDARY_TYPES.FUNCTION,
|
|
103
|
+
functionName,
|
|
104
|
+
lines,
|
|
105
|
+
filePath,
|
|
106
|
+
match.index
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (boundary) {
|
|
110
|
+
boundaries.push(boundary);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return boundaries;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Detect class boundaries
|
|
120
|
+
* @param {Array} lines - Source code lines
|
|
121
|
+
* @param {string} filePath - File path
|
|
122
|
+
* @returns {Array} Array of class boundaries
|
|
123
|
+
*/
|
|
124
|
+
detectClassBoundaries(lines, filePath) {
|
|
125
|
+
const boundaries = [];
|
|
126
|
+
const sourceCode = lines.join('\n');
|
|
127
|
+
|
|
128
|
+
// Find class declarations
|
|
129
|
+
const matches = [...sourceCode.matchAll(this.patterns.class.declaration)];
|
|
130
|
+
|
|
131
|
+
for (const match of matches) {
|
|
132
|
+
const className = match[1] || match[2];
|
|
133
|
+
if (className) {
|
|
134
|
+
const boundary = this.createBoundary(
|
|
135
|
+
BOUNDARY_TYPES.CLASS,
|
|
136
|
+
className,
|
|
137
|
+
lines,
|
|
138
|
+
filePath,
|
|
139
|
+
match.index
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
if (boundary) {
|
|
143
|
+
boundaries.push(boundary);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return boundaries;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Detect object boundaries
|
|
153
|
+
* @param {Array} lines - Source code lines
|
|
154
|
+
* @param {string} filePath - File path
|
|
155
|
+
* @returns {Array} Array of object boundaries
|
|
156
|
+
*/
|
|
157
|
+
detectObjectBoundaries(lines, filePath) {
|
|
158
|
+
const boundaries = [];
|
|
159
|
+
const sourceCode = lines.join('\n');
|
|
160
|
+
|
|
161
|
+
// Find object declarations
|
|
162
|
+
const matches = [...sourceCode.matchAll(this.patterns.object.declaration)];
|
|
163
|
+
|
|
164
|
+
for (const match of matches) {
|
|
165
|
+
const objectName = match[1];
|
|
166
|
+
if (objectName) {
|
|
167
|
+
const boundary = this.createBoundary(
|
|
168
|
+
BOUNDARY_TYPES.OBJECT,
|
|
169
|
+
objectName,
|
|
170
|
+
lines,
|
|
171
|
+
filePath,
|
|
172
|
+
match.index
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
if (boundary) {
|
|
176
|
+
boundaries.push(boundary);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return boundaries;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Detect module boundaries
|
|
186
|
+
* @param {Array} lines - Source code lines
|
|
187
|
+
* @param {string} filePath - File path
|
|
188
|
+
* @returns {Array} Array of module boundaries
|
|
189
|
+
*/
|
|
190
|
+
detectModuleBoundaries(lines, filePath) {
|
|
191
|
+
const boundaries = [];
|
|
192
|
+
const sourceCode = lines.join('\n');
|
|
193
|
+
|
|
194
|
+
// Find export statements
|
|
195
|
+
const matches = [...sourceCode.matchAll(this.patterns.module.export)];
|
|
196
|
+
|
|
197
|
+
for (const match of matches) {
|
|
198
|
+
const exportNames = match[1] ? match[1].split(',').map(s => s.trim()) : [match[2]];
|
|
199
|
+
|
|
200
|
+
for (const exportName of exportNames) {
|
|
201
|
+
if (exportName && exportName !== 'default') {
|
|
202
|
+
const boundary = this.createBoundary(
|
|
203
|
+
BOUNDARY_TYPES.MODULE,
|
|
204
|
+
exportName,
|
|
205
|
+
lines,
|
|
206
|
+
filePath,
|
|
207
|
+
match.index
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
if (boundary) {
|
|
211
|
+
boundaries.push(boundary);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return boundaries;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Detect utility boundaries
|
|
222
|
+
* @param {Array} lines - Source code lines
|
|
223
|
+
* @param {string} filePath - File path
|
|
224
|
+
* @returns {Array} Array of utility boundaries
|
|
225
|
+
*/
|
|
226
|
+
detectUtilityBoundaries(lines, filePath) {
|
|
227
|
+
const boundaries = [];
|
|
228
|
+
|
|
229
|
+
// Look for utility function patterns
|
|
230
|
+
for (let i = 0; i < lines.length; i++) {
|
|
231
|
+
const line = lines[i].trim();
|
|
232
|
+
|
|
233
|
+
// Helper function patterns
|
|
234
|
+
if (this.isUtilityFunction(line)) {
|
|
235
|
+
const functionName = this.extractUtilityFunctionName(line);
|
|
236
|
+
if (functionName) {
|
|
237
|
+
const boundary = this.createBoundary(
|
|
238
|
+
BOUNDARY_TYPES.UTILITY,
|
|
239
|
+
functionName,
|
|
240
|
+
lines,
|
|
241
|
+
filePath,
|
|
242
|
+
i
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
if (boundary) {
|
|
246
|
+
boundaries.push(boundary);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return boundaries;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Detect config boundaries
|
|
257
|
+
* @param {Array} lines - Source code lines
|
|
258
|
+
* @param {string} filePath - File path
|
|
259
|
+
* @returns {Array} Array of config boundaries
|
|
260
|
+
*/
|
|
261
|
+
detectConfigBoundaries(lines, filePath) {
|
|
262
|
+
const boundaries = [];
|
|
263
|
+
|
|
264
|
+
// Look for config object patterns
|
|
265
|
+
for (let i = 0; i < lines.length; i++) {
|
|
266
|
+
const line = lines[i].trim();
|
|
267
|
+
|
|
268
|
+
// Config object patterns
|
|
269
|
+
if (this.isConfigObject(line)) {
|
|
270
|
+
const configName = this.extractConfigObjectName(line);
|
|
271
|
+
if (configName) {
|
|
272
|
+
const boundary = this.createBoundary(
|
|
273
|
+
BOUNDARY_TYPES.CONFIG,
|
|
274
|
+
configName,
|
|
275
|
+
lines,
|
|
276
|
+
filePath,
|
|
277
|
+
i
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
if (boundary) {
|
|
281
|
+
boundaries.push(boundary);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return boundaries;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Detect constant boundaries
|
|
292
|
+
* @param {Array} lines - Source code lines
|
|
293
|
+
* @param {string} filePath - File path
|
|
294
|
+
* @returns {Array} Array of constant boundaries
|
|
295
|
+
*/
|
|
296
|
+
detectConstantBoundaries(lines, filePath) {
|
|
297
|
+
const boundaries = [];
|
|
298
|
+
|
|
299
|
+
// Look for constant patterns
|
|
300
|
+
for (let i = 0; i < lines.length; i++) {
|
|
301
|
+
const line = lines[i].trim();
|
|
302
|
+
|
|
303
|
+
// Constant patterns
|
|
304
|
+
if (this.isConstantDeclaration(line)) {
|
|
305
|
+
const constantName = this.extractConstantName(line);
|
|
306
|
+
if (constantName) {
|
|
307
|
+
const boundary = this.createBoundary(
|
|
308
|
+
BOUNDARY_TYPES.CONSTANT,
|
|
309
|
+
constantName,
|
|
310
|
+
lines,
|
|
311
|
+
filePath,
|
|
312
|
+
i
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
if (boundary) {
|
|
316
|
+
boundaries.push(boundary);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return boundaries;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Create boundary from detection
|
|
327
|
+
* @param {string} type - Boundary type
|
|
328
|
+
* @param {string} name - Boundary name
|
|
329
|
+
* @param {Array} lines - Source code lines
|
|
330
|
+
* @param {string} filePath - File path
|
|
331
|
+
* @param {number} startIndex - Start index in source
|
|
332
|
+
* @returns {Object|null} Boundary object or null
|
|
333
|
+
*/
|
|
334
|
+
createBoundary(type, name, lines, filePath, startIndex) {
|
|
335
|
+
const { startLine, endLine } = this.findBoundaryExtent(lines, startIndex, type);
|
|
336
|
+
|
|
337
|
+
if (startLine === -1 || endLine === -1) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const { ModuleBoundary } = require('./boundary-types');
|
|
342
|
+
const boundary = new ModuleBoundary(type, name, startLine + 1, endLine + 1, filePath);
|
|
343
|
+
|
|
344
|
+
// Analyze boundary properties
|
|
345
|
+
this.analyzeBoundary(boundary, lines, startLine, endLine);
|
|
346
|
+
|
|
347
|
+
return boundary;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Find the extent of a boundary
|
|
352
|
+
* @param {Array} lines - Source code lines
|
|
353
|
+
* @param {number} startIndex - Start index
|
|
354
|
+
* @param {string} type - Boundary type
|
|
355
|
+
* @returns {Object} Start and end line numbers
|
|
356
|
+
*/
|
|
357
|
+
findBoundaryExtent(lines, startIndex, type) {
|
|
358
|
+
let startLine = -1;
|
|
359
|
+
let endLine = -1;
|
|
360
|
+
let braceCount = 0;
|
|
361
|
+
let inString = false;
|
|
362
|
+
let stringChar = null;
|
|
363
|
+
|
|
364
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
365
|
+
const line = lines[i];
|
|
366
|
+
|
|
367
|
+
// Track string literals
|
|
368
|
+
for (let j = 0; j < line.length; j++) {
|
|
369
|
+
const char = line[j];
|
|
370
|
+
|
|
371
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
372
|
+
inString = true;
|
|
373
|
+
stringChar = char;
|
|
374
|
+
} else if (inString && char === stringChar) {
|
|
375
|
+
inString = false;
|
|
376
|
+
stringChar = null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Skip lines inside strings
|
|
381
|
+
if (inString) continue;
|
|
382
|
+
|
|
383
|
+
// Count braces for block detection
|
|
384
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
385
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
386
|
+
|
|
387
|
+
braceCount += openBraces - closeBraces;
|
|
388
|
+
|
|
389
|
+
// Set start line on first detection
|
|
390
|
+
if (startLine === -1) {
|
|
391
|
+
startLine = i;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// End when braces are balanced and we're past the start
|
|
395
|
+
if (braceCount <= 0 && i > startIndex) {
|
|
396
|
+
endLine = i;
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return { startLine, endLine };
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Analyze boundary properties
|
|
406
|
+
* @param {Object} boundary - Boundary object
|
|
407
|
+
* @param {Array} lines - Source code lines
|
|
408
|
+
* @param {number} startLine - Start line number
|
|
409
|
+
* @param {number} endLine - End line number
|
|
410
|
+
*/
|
|
411
|
+
analyzeBoundary(boundary, lines, startLine, endLine) {
|
|
412
|
+
const boundaryLines = lines.slice(startLine, endLine + 1);
|
|
413
|
+
const sourceCode = boundaryLines.join('\n');
|
|
414
|
+
|
|
415
|
+
// Calculate complexity
|
|
416
|
+
const complexity = this.calculateComplexity(sourceCode);
|
|
417
|
+
boundary.setComplexity(complexity);
|
|
418
|
+
|
|
419
|
+
// Find dependencies
|
|
420
|
+
const dependencies = this.findDependencies(sourceCode);
|
|
421
|
+
for (const dep of dependencies) {
|
|
422
|
+
boundary.addDependency(dep);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Find exports
|
|
426
|
+
const exports = this.findExports(sourceCode, boundary.type);
|
|
427
|
+
for (const exp of exports) {
|
|
428
|
+
boundary.addExport(exp);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Calculate cohesion
|
|
432
|
+
const cohesion = this.calculateCohesion(boundary, boundaryLines);
|
|
433
|
+
boundary.setCohesion(cohesion);
|
|
434
|
+
|
|
435
|
+
// Determine extractability
|
|
436
|
+
const extractable = this.isExtractable(boundary, boundaryLines);
|
|
437
|
+
boundary.setExtractable(extractable);
|
|
438
|
+
|
|
439
|
+
// Set confidence based on analysis
|
|
440
|
+
const confidence = this.calculateConfidence(boundary);
|
|
441
|
+
boundary.setConfidence(confidence);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Calculate complexity score
|
|
446
|
+
* @param {string} sourceCode - Source code
|
|
447
|
+
* @returns {number} Complexity score
|
|
448
|
+
*/
|
|
449
|
+
calculateComplexity(sourceCode) {
|
|
450
|
+
let complexity = 0;
|
|
451
|
+
|
|
452
|
+
// Cyclomatic complexity indicators
|
|
453
|
+
complexity += (sourceCode.match(/if\s*\(/g) || []).length * 1;
|
|
454
|
+
complexity += (sourceCode.match(/else\s+if/g) || []).length * 1;
|
|
455
|
+
complexity += (sourceCode.match(/while\s*\(/g) || []).length * 2;
|
|
456
|
+
complexity += (sourceCode.match(/for\s*\(/g) || []).length * 2;
|
|
457
|
+
complexity += (sourceCode.match(/switch\s*\(/g) || []).length * 2;
|
|
458
|
+
complexity += (sourceCode.match(/catch\s*\(/g) || []).length * 2;
|
|
459
|
+
complexity += (sourceCode.match(/&&/g) || []).length * 1;
|
|
460
|
+
complexity += (sourceCode.match(/\|\|/g) || []).length * 1;
|
|
461
|
+
|
|
462
|
+
// Nesting complexity
|
|
463
|
+
const maxNesting = this.calculateMaxNesting(sourceCode);
|
|
464
|
+
complexity += maxNesting * 2;
|
|
465
|
+
|
|
466
|
+
// Length complexity
|
|
467
|
+
const lineCount = sourceCode.split('\n').length;
|
|
468
|
+
if (lineCount > 50) complexity += 5;
|
|
469
|
+
if (lineCount > 100) complexity += 10;
|
|
470
|
+
if (lineCount > 200) complexity += 20;
|
|
471
|
+
|
|
472
|
+
return Math.min(100, complexity);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Calculate maximum nesting level
|
|
477
|
+
* @param {string} sourceCode - Source code
|
|
478
|
+
* @returns {number} Maximum nesting level
|
|
479
|
+
*/
|
|
480
|
+
calculateMaxNesting(sourceCode) {
|
|
481
|
+
let maxNesting = 0;
|
|
482
|
+
let currentNesting = 0;
|
|
483
|
+
let inString = false;
|
|
484
|
+
let stringChar = null;
|
|
485
|
+
|
|
486
|
+
for (const char of sourceCode) {
|
|
487
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
488
|
+
inString = true;
|
|
489
|
+
stringChar = char;
|
|
490
|
+
} else if (inString && char === stringChar) {
|
|
491
|
+
inString = false;
|
|
492
|
+
stringChar = null;
|
|
493
|
+
} else if (!inString) {
|
|
494
|
+
if (char === '{') {
|
|
495
|
+
currentNesting++;
|
|
496
|
+
maxNesting = Math.max(maxNesting, currentNesting);
|
|
497
|
+
} else if (char === '}') {
|
|
498
|
+
currentNesting--;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return maxNesting;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Find dependencies in boundary
|
|
508
|
+
* @param {string} sourceCode - Source code
|
|
509
|
+
* @returns {Array} Array of dependencies
|
|
510
|
+
*/
|
|
511
|
+
findDependencies(sourceCode) {
|
|
512
|
+
const dependencies = [];
|
|
513
|
+
|
|
514
|
+
// Import statements
|
|
515
|
+
const importMatches = sourceCode.match(/import\s+.+from\s+['"]([^'"]+)['"]/g);
|
|
516
|
+
if (importMatches) {
|
|
517
|
+
for (const match of importMatches) {
|
|
518
|
+
dependencies.push(match[1]);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Require statements
|
|
523
|
+
const requireMatches = sourceCode.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
|
|
524
|
+
if (requireMatches) {
|
|
525
|
+
for (const match of requireMatches) {
|
|
526
|
+
dependencies.push(match[1]);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return [...new Set(dependencies)];
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Find exports in boundary
|
|
535
|
+
* @param {string} sourceCode - Source code
|
|
536
|
+
* @param {string} type - Boundary type
|
|
537
|
+
* @returns {Array} Array of exports
|
|
538
|
+
*/
|
|
539
|
+
findExports(sourceCode, type) {
|
|
540
|
+
const exports = [];
|
|
541
|
+
|
|
542
|
+
if (type === BOUNDARY_TYPES.FUNCTION || type === BOUNDARY_TYPES.CLASS) {
|
|
543
|
+
// Look for explicit exports
|
|
544
|
+
const exportMatches = sourceCode.match(/export\s+(?:default\s+)?(?:\w+|\{[^}]+\})/g);
|
|
545
|
+
if (exportMatches) {
|
|
546
|
+
for (const match of exportMatches) {
|
|
547
|
+
const exportName = match.replace(/export\s+(?:default\s+)?/, '').trim();
|
|
548
|
+
if (exportName && exportName !== '{' && exportName !== '}') {
|
|
549
|
+
exports.push(exportName);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return exports;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Calculate cohesion level
|
|
560
|
+
* @param {Object} boundary - Boundary object
|
|
561
|
+
* @param {Array} lines - Boundary lines
|
|
562
|
+
* @returns {string} Cohesion level
|
|
563
|
+
*/
|
|
564
|
+
calculateCohesion(boundary, lines) {
|
|
565
|
+
let cohesionScore = 0;
|
|
566
|
+
|
|
567
|
+
// Single responsibility (high cohesion)
|
|
568
|
+
if (boundary.type === BOUNDARY_TYPES.FUNCTION || boundary.type === BOUNDARY_TYPES.CLASS) {
|
|
569
|
+
cohesionScore += 40;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Limited dependencies (medium cohesion)
|
|
573
|
+
if (boundary.dependencies.length <= 3) {
|
|
574
|
+
cohesionScore += 30;
|
|
575
|
+
} else if (boundary.dependencies.length <= 5) {
|
|
576
|
+
cohesionScore += 20;
|
|
577
|
+
} else {
|
|
578
|
+
cohesionScore += 10;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Clear purpose (high cohesion)
|
|
582
|
+
if (this.hasClearPurpose(boundary, lines)) {
|
|
583
|
+
cohesionScore += 30;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Convert to cohesion level
|
|
587
|
+
if (cohesionScore >= 80) return COHESION_LEVELS.HIGH;
|
|
588
|
+
if (cohesionScore >= 60) return COHESION_LEVELS.MEDIUM;
|
|
589
|
+
if (cohesionScore >= 40) return COHESION_LEVELS.LOW;
|
|
590
|
+
return COHESION_LEVELS.NONE;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Check if boundary has clear purpose
|
|
595
|
+
* @param {Object} boundary - Boundary object
|
|
596
|
+
* @param {Array} lines - Boundary lines
|
|
597
|
+
* @returns {boolean} Whether boundary has clear purpose
|
|
598
|
+
*/
|
|
599
|
+
hasClearPurpose(boundary, lines) {
|
|
600
|
+
const sourceCode = lines.join('\n');
|
|
601
|
+
|
|
602
|
+
// Check for comments explaining purpose
|
|
603
|
+
const hasComments = /\/\*\*[\s\S]*?\*\/|\/\/.*/.test(sourceCode);
|
|
604
|
+
|
|
605
|
+
// Check for meaningful name
|
|
606
|
+
const hasMeaningfulName = boundary.name &&
|
|
607
|
+
boundary.name.length > 2 &&
|
|
608
|
+
!/^(temp|tmp|test|dummy|helper|util)/.test(boundary.name.toLowerCase());
|
|
609
|
+
|
|
610
|
+
// Check for implementation
|
|
611
|
+
const hasImplementation = sourceCode.includes('{') && sourceCode.includes('}');
|
|
612
|
+
|
|
613
|
+
return hasComments || hasMeaningfulName || hasImplementation;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Determine if boundary is extractable
|
|
618
|
+
* @param {Object} boundary - Boundary object
|
|
619
|
+
* @param {Array} lines - Boundary lines
|
|
620
|
+
* @returns {boolean} Whether boundary is extractable
|
|
621
|
+
*/
|
|
622
|
+
isExtractable(boundary, lines) {
|
|
623
|
+
// Must have clear boundaries
|
|
624
|
+
if (boundary.lineCount < 5) return false;
|
|
625
|
+
|
|
626
|
+
// Must have reasonable cohesion
|
|
627
|
+
if (boundary.cohesion === COHESION_LEVELS.NONE) return false;
|
|
628
|
+
|
|
629
|
+
// Must not be too complex
|
|
630
|
+
if (boundary.complexity > 70) return false;
|
|
631
|
+
|
|
632
|
+
// Must have reasonable dependencies
|
|
633
|
+
if (boundary.dependencies.length > 10) return false;
|
|
634
|
+
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Calculate confidence score
|
|
640
|
+
* @param {Object} boundary - Boundary object
|
|
641
|
+
* @returns {number} Confidence score (0-1)
|
|
642
|
+
*/
|
|
643
|
+
calculateConfidence(boundary) {
|
|
644
|
+
let confidence = 0.5; // Base confidence
|
|
645
|
+
|
|
646
|
+
// Increase confidence for clear boundaries
|
|
647
|
+
if (boundary.lineCount >= 10 && boundary.lineCount <= 200) {
|
|
648
|
+
confidence += 0.2;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Increase confidence for high cohesion
|
|
652
|
+
if (boundary.cohesion === COHESION_LEVELS.HIGH) {
|
|
653
|
+
confidence += 0.2;
|
|
654
|
+
} else if (boundary.cohesion === COHESION_LEVELS.MEDIUM) {
|
|
655
|
+
confidence += 0.1;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Increase confidence for extractable boundaries
|
|
659
|
+
if (boundary.isExtractable()) {
|
|
660
|
+
confidence += 0.1;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return Math.min(1.0, confidence);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Check if line is a utility function
|
|
668
|
+
* @param {string} line - Code line
|
|
669
|
+
* @returns {boolean} Whether line is utility function
|
|
670
|
+
*/
|
|
671
|
+
isUtilityFunction(line) {
|
|
672
|
+
const utilityPatterns = [
|
|
673
|
+
/(?:const|let|var)\s+\w+\s*=\s*\([^)]*\)\s*=>/,
|
|
674
|
+
/function\s+(?:is|has|get|set|calculate|compute|parse|format|validate|check)/,
|
|
675
|
+
/(?:is|has|get|set|calculate|compute|parse|format|validate|check)\w+\s*\(/
|
|
676
|
+
];
|
|
677
|
+
|
|
678
|
+
return utilityPatterns.some(pattern => pattern.test(line));
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Extract utility function name
|
|
683
|
+
* @param {string} line - Code line
|
|
684
|
+
* @returns {string|null} Function name
|
|
685
|
+
*/
|
|
686
|
+
extractUtilityFunctionName(line) {
|
|
687
|
+
const match = line.match(/(?:const|let|var)\s+(\w+)\s*=|function\s+(\w+)/);
|
|
688
|
+
return match ? match[1] || match[2] : null;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Check if line is config object
|
|
693
|
+
* @param {string} line - Code line
|
|
694
|
+
* @returns {boolean} Whether line is config object
|
|
695
|
+
*/
|
|
696
|
+
isConfigObject(line) {
|
|
697
|
+
const configPatterns = [
|
|
698
|
+
/(?:const|let|var)\s+\w*config\w*\s*=/,
|
|
699
|
+
/(?:const|let|var)\s+\w*Config\w*\s*=/,
|
|
700
|
+
/(?:const|let|var)\s+\w*Settings\w*\s*=/
|
|
701
|
+
];
|
|
702
|
+
|
|
703
|
+
return configPatterns.some(pattern => pattern.test(line));
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Extract config object name
|
|
708
|
+
* @param {string} line - Code line
|
|
709
|
+
* @returns {string|null} Config name
|
|
710
|
+
*/
|
|
711
|
+
extractConfigObjectName(line) {
|
|
712
|
+
const match = line.match(/(?:const|let|var)\s+(\w*config\w*|\w*Config\w*|\w*Settings\w*)\s*=/);
|
|
713
|
+
return match ? match[1] : null;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Check if line is constant declaration
|
|
718
|
+
* @param {string} line - Code line
|
|
719
|
+
* @returns {boolean} Whether line is constant declaration
|
|
720
|
+
*/
|
|
721
|
+
isConstantDeclaration(line) {
|
|
722
|
+
const constantPatterns = [
|
|
723
|
+
/const\s+[A-Z_][A-Z0-9_]*\s*=/,
|
|
724
|
+
/(?:const|let|var)\s+[A-Z_][A-Z0-9_]*\s*=/
|
|
725
|
+
];
|
|
726
|
+
|
|
727
|
+
return constantPatterns.some(pattern => pattern.test(line));
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Extract constant name
|
|
732
|
+
* @param {string} line - Code line
|
|
733
|
+
* @returns {string|null} Constant name
|
|
734
|
+
*/
|
|
735
|
+
extractConstantName(line) {
|
|
736
|
+
const match = line.match(/(?:const|let|var)\s+([A-Z_][A-Z0-9_]*)\s*=/);
|
|
737
|
+
return match ? match[1] : null;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
module.exports = BoundaryDetector;
|