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,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extraction Strategies
|
|
3
|
+
*
|
|
4
|
+
* Different strategies for extracting boundaries from code.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { BOUNDARY_TYPES } = require('./module-boundary');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Base extraction strategy
|
|
11
|
+
*/
|
|
12
|
+
class ExtractionStrategy {
|
|
13
|
+
constructor(name) {
|
|
14
|
+
this.name = name;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Extract boundaries from code
|
|
19
|
+
*/
|
|
20
|
+
extract(code, filePath) {
|
|
21
|
+
throw new Error('extract method must be implemented by subclass');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Check if strategy can handle the code
|
|
26
|
+
*/
|
|
27
|
+
canHandle(code) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Function extraction strategy
|
|
34
|
+
*/
|
|
35
|
+
class FunctionExtractionStrategy extends ExtractionStrategy {
|
|
36
|
+
constructor() {
|
|
37
|
+
super('function');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
extract(code, filePath) {
|
|
41
|
+
const boundaries = [];
|
|
42
|
+
const lines = code.split('\n');
|
|
43
|
+
|
|
44
|
+
// Function patterns
|
|
45
|
+
const patterns = [
|
|
46
|
+
/function\s+(\w+)\s*\([^)]*\)\s*{/g,
|
|
47
|
+
/const\s+(\w+)\s*=\s*(?:async\s+)?function\s*\([^)]*\)\s*{/g,
|
|
48
|
+
/const\s+(\w+)\s*=\s*\([^)]*\)\s*=>\s*{/g,
|
|
49
|
+
/(\w+)\s*:\s*(?:async\s+)?function\s*\([^)]*\)\s*{/g,
|
|
50
|
+
/async\s+function\s+(\w+)\s*\([^)]*\)\s*{/g
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
for (const pattern of patterns) {
|
|
54
|
+
let match;
|
|
55
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
56
|
+
const functionName = match[1];
|
|
57
|
+
const startIndex = match.index;
|
|
58
|
+
const startLine = this.getLineNumber(code, startIndex);
|
|
59
|
+
|
|
60
|
+
// Find function end
|
|
61
|
+
const endIndex = this.findFunctionEnd(code, startIndex);
|
|
62
|
+
const endLine = this.getLineNumber(code, endIndex);
|
|
63
|
+
|
|
64
|
+
if (endIndex > startIndex) {
|
|
65
|
+
const boundary = {
|
|
66
|
+
type: BOUNDARY_TYPES.FUNCTION,
|
|
67
|
+
name: functionName,
|
|
68
|
+
startLine,
|
|
69
|
+
endLine,
|
|
70
|
+
confidence: this.calculateConfidence(match[0])
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
boundaries.push(boundary);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return boundaries;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
findFunctionEnd(code, startIndex) {
|
|
82
|
+
let braceCount = 0;
|
|
83
|
+
let inString = false;
|
|
84
|
+
let stringChar = '';
|
|
85
|
+
let i = startIndex;
|
|
86
|
+
|
|
87
|
+
for (; i < code.length; i++) {
|
|
88
|
+
const char = code[i];
|
|
89
|
+
|
|
90
|
+
// Handle strings
|
|
91
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
92
|
+
inString = true;
|
|
93
|
+
stringChar = char;
|
|
94
|
+
} else if (inString && char === stringChar && code[i-1] !== '\\') {
|
|
95
|
+
inString = false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Count braces when not in strings
|
|
99
|
+
if (!inString) {
|
|
100
|
+
if (char === '{') braceCount++;
|
|
101
|
+
else if (char === '}') {
|
|
102
|
+
braceCount--;
|
|
103
|
+
if (braceCount === 0) break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return i + 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
calculateConfidence(match) {
|
|
112
|
+
// Higher confidence for more explicit function declarations
|
|
113
|
+
if (match.startsWith('function')) return 0.9;
|
|
114
|
+
if (match.includes('function')) return 0.8;
|
|
115
|
+
if (match.includes('=>')) return 0.7;
|
|
116
|
+
return 0.6;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getLineNumber(code, index) {
|
|
120
|
+
const before = code.substring(0, index);
|
|
121
|
+
return before.split('\n').length;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
canHandle(code) {
|
|
125
|
+
return /function|=>/.test(code);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Class extraction strategy
|
|
131
|
+
*/
|
|
132
|
+
class ClassExtractionStrategy extends ExtractionStrategy {
|
|
133
|
+
constructor() {
|
|
134
|
+
super('class');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
extract(code, filePath) {
|
|
138
|
+
const boundaries = [];
|
|
139
|
+
const lines = code.split('\n');
|
|
140
|
+
|
|
141
|
+
// Class patterns
|
|
142
|
+
const patterns = [
|
|
143
|
+
/class\s+(\w+)/g,
|
|
144
|
+
/class\s+(\w+)\s+extends\s+\w+/g
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
for (const pattern of patterns) {
|
|
148
|
+
let match;
|
|
149
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
150
|
+
const className = match[1];
|
|
151
|
+
const startIndex = match.index;
|
|
152
|
+
const startLine = this.getLineNumber(code, startIndex);
|
|
153
|
+
|
|
154
|
+
// Find class end
|
|
155
|
+
const endIndex = this.findClassEnd(code, startIndex);
|
|
156
|
+
const endLine = this.getLineNumber(code, endIndex);
|
|
157
|
+
|
|
158
|
+
if (endIndex > startIndex) {
|
|
159
|
+
const boundary = {
|
|
160
|
+
type: BOUNDARY_TYPES.CLASS,
|
|
161
|
+
name: className,
|
|
162
|
+
startLine,
|
|
163
|
+
endLine,
|
|
164
|
+
confidence: 0.9
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
boundaries.push(boundary);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return boundaries;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
findClassEnd(code, startIndex) {
|
|
176
|
+
let braceCount = 0;
|
|
177
|
+
let inString = false;
|
|
178
|
+
let stringChar = '';
|
|
179
|
+
let i = startIndex;
|
|
180
|
+
|
|
181
|
+
for (; i < code.length; i++) {
|
|
182
|
+
const char = code[i];
|
|
183
|
+
|
|
184
|
+
// Handle strings
|
|
185
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
186
|
+
inString = true;
|
|
187
|
+
stringChar = char;
|
|
188
|
+
} else if (inString && char === stringChar && code[i-1] !== '\\') {
|
|
189
|
+
inString = false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Count braces when not in strings
|
|
193
|
+
if (!inString) {
|
|
194
|
+
if (char === '{') braceCount++;
|
|
195
|
+
else if (char === '}') {
|
|
196
|
+
braceCount--;
|
|
197
|
+
if (braceCount === 0) break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return i + 1;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
getLineNumber(code, index) {
|
|
206
|
+
const before = code.substring(0, index);
|
|
207
|
+
return before.split('\n').length;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
canHandle(code) {
|
|
211
|
+
return /class/.test(code);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Object extraction strategy
|
|
217
|
+
*/
|
|
218
|
+
class ObjectExtractionStrategy extends ExtractionStrategy {
|
|
219
|
+
constructor() {
|
|
220
|
+
super('object');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
extract(code, filePath) {
|
|
224
|
+
const boundaries = [];
|
|
225
|
+
const lines = code.split('\n');
|
|
226
|
+
|
|
227
|
+
// Object patterns
|
|
228
|
+
const patterns = [
|
|
229
|
+
/(?:const|let|var)\s+(\w+)\s*=\s*\{/g,
|
|
230
|
+
/(\w+)\s*:\s*\{/g
|
|
231
|
+
];
|
|
232
|
+
|
|
233
|
+
for (const pattern of patterns) {
|
|
234
|
+
let match;
|
|
235
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
236
|
+
const objectName = match[1];
|
|
237
|
+
const startIndex = match.index;
|
|
238
|
+
const startLine = this.getLineNumber(code, startIndex);
|
|
239
|
+
|
|
240
|
+
// Find object end
|
|
241
|
+
const endIndex = this.findObjectEnd(code, startIndex);
|
|
242
|
+
const endLine = this.getLineNumber(code, endIndex);
|
|
243
|
+
|
|
244
|
+
if (endIndex > startIndex && endIndex - startIndex > 50) { // Only significant objects
|
|
245
|
+
const boundary = {
|
|
246
|
+
type: BOUNDARY_TYPES.OBJECT,
|
|
247
|
+
name: objectName,
|
|
248
|
+
startLine,
|
|
249
|
+
endLine,
|
|
250
|
+
confidence: 0.7
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
boundaries.push(boundary);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return boundaries;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
findObjectEnd(code, startIndex) {
|
|
262
|
+
let braceCount = 0;
|
|
263
|
+
let inString = false;
|
|
264
|
+
let stringChar = '';
|
|
265
|
+
let i = startIndex;
|
|
266
|
+
|
|
267
|
+
for (; i < code.length; i++) {
|
|
268
|
+
const char = code[i];
|
|
269
|
+
|
|
270
|
+
// Handle strings
|
|
271
|
+
if (!inString && (char === '"' || char === "'" || char === '`')) {
|
|
272
|
+
inString = true;
|
|
273
|
+
stringChar = char;
|
|
274
|
+
} else if (inString && char === stringChar && code[i-1] !== '\\') {
|
|
275
|
+
inString = false;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Count braces when not in strings
|
|
279
|
+
if (!inString) {
|
|
280
|
+
if (char === '{') braceCount++;
|
|
281
|
+
else if (char === '}') {
|
|
282
|
+
braceCount--;
|
|
283
|
+
if (braceCount === 0) break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return i + 1;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
getLineNumber(code, index) {
|
|
292
|
+
const before = code.substring(0, index);
|
|
293
|
+
return before.split('\n').length;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
canHandle(code) {
|
|
297
|
+
return /\{.*\}/.test(code);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Utility extraction strategy
|
|
303
|
+
*/
|
|
304
|
+
class UtilityExtractionStrategy extends ExtractionStrategy {
|
|
305
|
+
constructor() {
|
|
306
|
+
super('utility');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
extract(code, filePath) {
|
|
310
|
+
const boundaries = [];
|
|
311
|
+
const lines = code.split('\n');
|
|
312
|
+
|
|
313
|
+
// Look for utility function patterns
|
|
314
|
+
const utilityPatterns = [
|
|
315
|
+
/(?:const|let|var)\s+(is|has|can|should|get|set|parse|format|validate|calculate|compute)\w*\s*=\s*\(/g,
|
|
316
|
+
/(?:const|let|var)\s+\w*Helper\s*=\s*\(/g,
|
|
317
|
+
/(?:const|let|var)\s+\w*Utils\s*=\s*\{/g
|
|
318
|
+
];
|
|
319
|
+
|
|
320
|
+
for (const pattern of utilityPatterns) {
|
|
321
|
+
let match;
|
|
322
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
323
|
+
const utilityName = match[1] || match[0].split('=')[0].trim().split(' ').pop();
|
|
324
|
+
const startIndex = match.index;
|
|
325
|
+
const startLine = this.getLineNumber(code, startIndex);
|
|
326
|
+
|
|
327
|
+
// Find end (simplified for utilities)
|
|
328
|
+
const endIndex = this.findUtilityEnd(code, startIndex);
|
|
329
|
+
const endLine = this.getLineNumber(code, endIndex);
|
|
330
|
+
|
|
331
|
+
if (endIndex > startIndex) {
|
|
332
|
+
const boundary = {
|
|
333
|
+
type: BOUNDARY_TYPES.UTILITY,
|
|
334
|
+
name: utilityName,
|
|
335
|
+
startLine,
|
|
336
|
+
endLine,
|
|
337
|
+
confidence: 0.8
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
boundaries.push(boundary);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return boundaries;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
findUtilityEnd(code, startIndex) {
|
|
349
|
+
// Simple heuristic: find next major construct or end of file
|
|
350
|
+
const lines = code.substring(startIndex).split('\n');
|
|
351
|
+
let lineCount = 0;
|
|
352
|
+
let braceCount = 0;
|
|
353
|
+
|
|
354
|
+
for (let i = 0; i < lines.length; i++) {
|
|
355
|
+
const line = lines[i];
|
|
356
|
+
lineCount++;
|
|
357
|
+
|
|
358
|
+
// Count braces
|
|
359
|
+
for (const char of line) {
|
|
360
|
+
if (char === '{') braceCount++;
|
|
361
|
+
else if (char === '}') braceCount--;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// End when braces balance and we have some content
|
|
365
|
+
if (braceCount <= 0 && lineCount > 1) {
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Safety limit
|
|
370
|
+
if (lineCount > 50) break;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return startIndex + lines.slice(0, lineCount).join('\n').length;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
getLineNumber(code, index) {
|
|
377
|
+
const before = code.substring(0, index);
|
|
378
|
+
return before.split('\n').length;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
canHandle(code) {
|
|
382
|
+
return /(?:is|has|can|should|get|set|parse|format|validate|calculate|compute|Helper|Utils)/.test(code);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
module.exports = {
|
|
387
|
+
ExtractionStrategy,
|
|
388
|
+
FunctionExtractionStrategy,
|
|
389
|
+
ClassExtractionStrategy,
|
|
390
|
+
ObjectExtractionStrategy,
|
|
391
|
+
UtilityExtractionStrategy
|
|
392
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Boundary
|
|
3
|
+
*
|
|
4
|
+
* Represents a logical boundary within code that can be extracted.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const COHESION_LEVELS = {
|
|
8
|
+
HIGH: 'high',
|
|
9
|
+
MEDIUM: 'medium',
|
|
10
|
+
LOW: 'low',
|
|
11
|
+
NONE: 'none'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const BOUNDARY_TYPES = {
|
|
15
|
+
FUNCTION: 'function',
|
|
16
|
+
CLASS: 'class',
|
|
17
|
+
OBJECT: 'object',
|
|
18
|
+
MODULE: 'module',
|
|
19
|
+
UTILITY: 'utility',
|
|
20
|
+
CONFIG: 'config',
|
|
21
|
+
CONSTANT: 'constant'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Module boundary class
|
|
26
|
+
*/
|
|
27
|
+
class ModuleBoundary {
|
|
28
|
+
constructor(type, name, startLine, endLine, filePath) {
|
|
29
|
+
this.id = this.generateId();
|
|
30
|
+
this.type = type;
|
|
31
|
+
this.name = name;
|
|
32
|
+
this.startLine = startLine;
|
|
33
|
+
this.endLine = endLine;
|
|
34
|
+
this.filePath = filePath;
|
|
35
|
+
this.lineCount = endLine - startLine + 1;
|
|
36
|
+
this.cohesion = COHESION_LEVELS.NONE;
|
|
37
|
+
this.complexity = 0;
|
|
38
|
+
this.dependencies = [];
|
|
39
|
+
this.exports = [];
|
|
40
|
+
this.internalReferences = [];
|
|
41
|
+
this.metadata = {
|
|
42
|
+
extractedAt: null,
|
|
43
|
+
targetFile: null,
|
|
44
|
+
extractionStatus: 'pending'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
generateId() {
|
|
49
|
+
return `boundary_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Set cohesion level
|
|
54
|
+
*/
|
|
55
|
+
setCohesion(level) {
|
|
56
|
+
if (Object.values(COHESION_LEVELS).includes(level)) {
|
|
57
|
+
this.cohesion = level;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Set complexity score
|
|
63
|
+
*/
|
|
64
|
+
setComplexity(score) {
|
|
65
|
+
this.complexity = Math.max(0, score);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Add dependency
|
|
70
|
+
*/
|
|
71
|
+
addDependency(dependency) {
|
|
72
|
+
if (!this.dependencies.includes(dependency)) {
|
|
73
|
+
this.dependencies.push(dependency);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Add export
|
|
79
|
+
*/
|
|
80
|
+
addExport(exportName) {
|
|
81
|
+
if (!this.exports.includes(exportName)) {
|
|
82
|
+
this.exports.push(exportName);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Add internal reference
|
|
88
|
+
*/
|
|
89
|
+
addInternalReference(reference) {
|
|
90
|
+
if (!this.internalReferences.includes(reference)) {
|
|
91
|
+
this.internalReferences.push(reference);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if boundary is extractable
|
|
97
|
+
*/
|
|
98
|
+
isExtractable() {
|
|
99
|
+
return this.lineCount >= 5 &&
|
|
100
|
+
this.cohesion !== COHESION_LEVELS.NONE &&
|
|
101
|
+
this.name.length > 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Check if boundary has high cohesion
|
|
106
|
+
*/
|
|
107
|
+
hasHighCohesion() {
|
|
108
|
+
return this.cohesion === COHESION_LEVELS.HIGH;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get extraction priority
|
|
113
|
+
*/
|
|
114
|
+
getExtractionPriority() {
|
|
115
|
+
if (!this.isExtractable()) return 0;
|
|
116
|
+
|
|
117
|
+
let priority = 1;
|
|
118
|
+
|
|
119
|
+
// Larger boundaries get higher priority
|
|
120
|
+
if (this.lineCount > 50) priority += 2;
|
|
121
|
+
else if (this.lineCount > 20) priority += 1;
|
|
122
|
+
|
|
123
|
+
// High cohesion gets higher priority
|
|
124
|
+
if (this.hasHighCohesion()) priority += 2;
|
|
125
|
+
else if (this.cohesion === COHESION_LEVELS.MEDIUM) priority += 1;
|
|
126
|
+
|
|
127
|
+
// More dependencies increase priority (they're harder to move)
|
|
128
|
+
priority += Math.min(this.dependencies.length, 3);
|
|
129
|
+
|
|
130
|
+
return priority;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Get suggested filename for extraction
|
|
135
|
+
*/
|
|
136
|
+
getSuggestedFilename() {
|
|
137
|
+
const baseName = this.name.toLowerCase().replace(/[^a-z0-9]/g, '-');
|
|
138
|
+
const suffix = this.getTypeSuffix();
|
|
139
|
+
|
|
140
|
+
return `${baseName}${suffix}.js`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
getTypeSuffix() {
|
|
144
|
+
switch (this.type) {
|
|
145
|
+
case BOUNDARY_TYPES.CLASS:
|
|
146
|
+
return '.class';
|
|
147
|
+
case BOUNDARY_TYPES.FUNCTION:
|
|
148
|
+
return '.func';
|
|
149
|
+
case BOUNDARY_TYPES.UTILITY:
|
|
150
|
+
return '.utils';
|
|
151
|
+
case BOUNDARY_TYPES.CONFIG:
|
|
152
|
+
return '.config';
|
|
153
|
+
case BOUNDARY_TYPES.CONSTANT:
|
|
154
|
+
return '.constants';
|
|
155
|
+
default:
|
|
156
|
+
return '';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Mark as extracted
|
|
162
|
+
*/
|
|
163
|
+
markAsExtracted(targetFile) {
|
|
164
|
+
this.metadata.extractedAt = new Date().toISOString();
|
|
165
|
+
this.metadata.targetFile = targetFile;
|
|
166
|
+
this.metadata.extractionStatus = 'extracted';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get boundary summary
|
|
171
|
+
*/
|
|
172
|
+
getSummary() {
|
|
173
|
+
return {
|
|
174
|
+
id: this.id,
|
|
175
|
+
type: this.type,
|
|
176
|
+
name: this.name,
|
|
177
|
+
lineCount: this.lineCount,
|
|
178
|
+
cohesion: this.cohesion,
|
|
179
|
+
complexity: this.complexity,
|
|
180
|
+
extractable: this.isExtractable(),
|
|
181
|
+
priority: this.getExtractionPriority(),
|
|
182
|
+
suggestedFilename: this.getSuggestedFilename()
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
toJSON() {
|
|
187
|
+
return {
|
|
188
|
+
id: this.id,
|
|
189
|
+
type: this.type,
|
|
190
|
+
name: this.name,
|
|
191
|
+
startLine: this.startLine,
|
|
192
|
+
endLine: this.endLine,
|
|
193
|
+
filePath: this.filePath,
|
|
194
|
+
lineCount: this.lineCount,
|
|
195
|
+
cohesion: this.cohesion,
|
|
196
|
+
complexity: this.complexity,
|
|
197
|
+
dependencies: this.dependencies,
|
|
198
|
+
exports: this.exports,
|
|
199
|
+
internalReferences: this.internalReferences,
|
|
200
|
+
metadata: this.metadata
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = {
|
|
206
|
+
ModuleBoundary,
|
|
207
|
+
BOUNDARY_TYPES,
|
|
208
|
+
COHESION_LEVELS
|
|
209
|
+
};
|