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,712 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logical Boundary Detector
|
|
3
|
+
*
|
|
4
|
+
* Uses AST analysis to detect logical boundaries in files for refactoring.
|
|
5
|
+
* Identifies functions, classes, modules, and other logical segments.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Boundary types
|
|
13
|
+
*/
|
|
14
|
+
const BOUNDARY_TYPES = {
|
|
15
|
+
FUNCTION: 'function',
|
|
16
|
+
CLASS: 'class',
|
|
17
|
+
MODULE: 'module',
|
|
18
|
+
BLOCK: 'block',
|
|
19
|
+
IMPORT: 'import',
|
|
20
|
+
EXPORT: 'export',
|
|
21
|
+
COMMENT: 'comment',
|
|
22
|
+
UTILITY: 'utility',
|
|
23
|
+
CONSTANT: 'constant'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Boundary detection result class
|
|
28
|
+
*/
|
|
29
|
+
class BoundaryDetectionResult {
|
|
30
|
+
constructor(filePath) {
|
|
31
|
+
this.filePath = filePath;
|
|
32
|
+
this.boundaries = [];
|
|
33
|
+
this.metadata = {
|
|
34
|
+
totalBoundaries: 0,
|
|
35
|
+
byType: {},
|
|
36
|
+
complexity: 'unknown',
|
|
37
|
+
cohesion: 'unknown',
|
|
38
|
+
coupling: 'unknown'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
addBoundary(boundary) {
|
|
43
|
+
this.boundaries.push(boundary);
|
|
44
|
+
this.metadata.totalBoundaries++;
|
|
45
|
+
|
|
46
|
+
if (!this.metadata.byType[boundary.type]) {
|
|
47
|
+
this.metadata.byType[boundary.type] = 0;
|
|
48
|
+
}
|
|
49
|
+
this.metadata.byType[boundary.type]++;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getBoundariesByType(type) {
|
|
53
|
+
return this.boundaries.filter(b => b.type === type);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getLargestBoundaries(count = 5) {
|
|
57
|
+
return this.boundaries
|
|
58
|
+
.sort((a, b) => b.lineCount - a.lineCount)
|
|
59
|
+
.slice(0, count);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getRefactoringCandidates() {
|
|
63
|
+
return this.boundaries.filter(b =>
|
|
64
|
+
b.lineCount > 50 && // Reasonable size
|
|
65
|
+
(b.type === BOUNDARY_TYPES.FUNCTION || b.type === BOUNDARY_TYPES.CLASS)
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Boundary class
|
|
72
|
+
*/
|
|
73
|
+
class Boundary {
|
|
74
|
+
constructor(type, startLine, endLine, name = '') {
|
|
75
|
+
this.type = type;
|
|
76
|
+
this.startLine = startLine;
|
|
77
|
+
this.endLine = endLine;
|
|
78
|
+
this.name = name;
|
|
79
|
+
this.lineCount = endLine - startLine + 1;
|
|
80
|
+
this.complexity = 0;
|
|
81
|
+
this.dependencies = [];
|
|
82
|
+
this.exports = [];
|
|
83
|
+
this.comments = [];
|
|
84
|
+
this.metadata = {};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
addDependency(dependency) {
|
|
88
|
+
this.dependencies.push(dependency);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
addExport(exportName) {
|
|
92
|
+
this.exports.push(exportName);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
addComment(comment) {
|
|
96
|
+
this.comments.push(comment);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setComplexity(complexity) {
|
|
100
|
+
this.complexity = complexity;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
canExtract() {
|
|
104
|
+
// Basic criteria for extraction
|
|
105
|
+
return this.lineCount >= 10 &&
|
|
106
|
+
this.name !== '' &&
|
|
107
|
+
(this.type === BOUNDARY_TYPES.FUNCTION || this.type === BOUNDARY_TYPES.CLASS);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Logical boundary detector class
|
|
113
|
+
*/
|
|
114
|
+
class BoundaryDetector {
|
|
115
|
+
constructor(options = {}) {
|
|
116
|
+
this.options = {
|
|
117
|
+
minFunctionSize: 5,
|
|
118
|
+
minClassSize: 10,
|
|
119
|
+
detectComments: true,
|
|
120
|
+
detectUtilities: true,
|
|
121
|
+
...options
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Detect boundaries in a file
|
|
127
|
+
*/
|
|
128
|
+
async detectBoundaries(filePath) {
|
|
129
|
+
const result = new BoundaryDetectionResult(filePath);
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
133
|
+
const lines = content.split('\n');
|
|
134
|
+
|
|
135
|
+
// Detect based on file type
|
|
136
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
137
|
+
|
|
138
|
+
if (['.js', '.jsx', '.ts', '.tsx'].includes(ext)) {
|
|
139
|
+
await this.detectJavaScriptBoundaries(content, lines, result);
|
|
140
|
+
} else if (ext === '.md') {
|
|
141
|
+
await this.detectMarkdownBoundaries(content, lines, result);
|
|
142
|
+
} else {
|
|
143
|
+
await this.detectTextBoundaries(content, lines, result);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Analyze overall structure
|
|
147
|
+
this.analyzeStructure(result);
|
|
148
|
+
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error(`Error detecting boundaries in ${filePath}: ${error.message}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Detect boundaries in JavaScript/TypeScript files
|
|
158
|
+
*/
|
|
159
|
+
async detectJavaScriptBoundaries(content, lines, result) {
|
|
160
|
+
// Detect imports
|
|
161
|
+
this.detectImports(lines, result);
|
|
162
|
+
|
|
163
|
+
// Detect exports
|
|
164
|
+
this.detectExports(lines, result);
|
|
165
|
+
|
|
166
|
+
// Detect functions
|
|
167
|
+
this.detectFunctions(lines, result);
|
|
168
|
+
|
|
169
|
+
// Detect classes
|
|
170
|
+
this.detectClasses(lines, result);
|
|
171
|
+
|
|
172
|
+
// Detect utility sections
|
|
173
|
+
if (this.options.detectUtilities) {
|
|
174
|
+
this.detectUtilities(lines, result);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Detect comment blocks
|
|
178
|
+
if (this.options.detectComments) {
|
|
179
|
+
this.detectCommentBlocks(lines, result);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Detect import statements
|
|
185
|
+
*/
|
|
186
|
+
detectImports(lines, result) {
|
|
187
|
+
let currentImport = null;
|
|
188
|
+
|
|
189
|
+
for (let i = 0; i < lines.length; i++) {
|
|
190
|
+
const line = lines[i].trim();
|
|
191
|
+
|
|
192
|
+
if (line.startsWith('import ')) {
|
|
193
|
+
if (currentImport) {
|
|
194
|
+
// Close previous import
|
|
195
|
+
currentImport.endLine = i - 1;
|
|
196
|
+
currentImport.lineCount = currentImport.endLine - currentImport.startLine + 1;
|
|
197
|
+
result.addBoundary(currentImport);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Start new import
|
|
201
|
+
const match = line.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
|
|
202
|
+
currentImport = new Boundary(
|
|
203
|
+
BOUNDARY_TYPES.IMPORT,
|
|
204
|
+
i,
|
|
205
|
+
i,
|
|
206
|
+
match ? match[1] : 'import'
|
|
207
|
+
);
|
|
208
|
+
} else if (currentImport && (line.startsWith('from ') || line.endsWith(';'))) {
|
|
209
|
+
// End of import statement
|
|
210
|
+
currentImport.endLine = i;
|
|
211
|
+
currentImport.lineCount = currentImport.endLine - currentImport.startLine + 1;
|
|
212
|
+
result.addBoundary(currentImport);
|
|
213
|
+
currentImport = null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Handle unclosed import
|
|
218
|
+
if (currentImport) {
|
|
219
|
+
currentImport.endLine = lines.length - 1;
|
|
220
|
+
currentImport.lineCount = currentImport.endLine - currentImport.startLine + 1;
|
|
221
|
+
result.addBoundary(currentImport);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Detect export statements
|
|
227
|
+
*/
|
|
228
|
+
detectExports(lines, result) {
|
|
229
|
+
for (let i = 0; i < lines.length; i++) {
|
|
230
|
+
const line = lines[i].trim();
|
|
231
|
+
|
|
232
|
+
if (line.startsWith('export ')) {
|
|
233
|
+
const match = line.match(/export\s+(?:default\s+)?(?:function|class|const|let|var)\s+(\w+)/);
|
|
234
|
+
const name = match ? match[1] : 'export';
|
|
235
|
+
|
|
236
|
+
const boundary = new Boundary(
|
|
237
|
+
BOUNDARY_TYPES.EXPORT,
|
|
238
|
+
i,
|
|
239
|
+
i,
|
|
240
|
+
name
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
result.addBoundary(boundary);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Detect function boundaries
|
|
250
|
+
*/
|
|
251
|
+
detectFunctions(lines, result) {
|
|
252
|
+
for (let i = 0; i < lines.length; i++) {
|
|
253
|
+
const line = lines[i].trim();
|
|
254
|
+
|
|
255
|
+
// Function declarations
|
|
256
|
+
const funcMatch = line.match(/^(?:async\s+)?function\s+(\w+)/);
|
|
257
|
+
if (funcMatch) {
|
|
258
|
+
const boundary = this.findFunctionBoundary(lines, i, funcMatch[1], 'declaration');
|
|
259
|
+
if (boundary) result.addBoundary(boundary);
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Function expressions
|
|
264
|
+
const exprMatch = line.match(/^(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?function/);
|
|
265
|
+
if (exprMatch) {
|
|
266
|
+
const boundary = this.findFunctionBoundary(lines, i, exprMatch[1], 'expression');
|
|
267
|
+
if (boundary) result.addBoundary(boundary);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Arrow functions
|
|
272
|
+
const arrowMatch = line.match(/^(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(/);
|
|
273
|
+
if (arrowMatch) {
|
|
274
|
+
const boundary = this.findArrowFunctionBoundary(lines, i, arrowMatch[1]);
|
|
275
|
+
if (boundary) result.addBoundary(boundary);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Method definitions in classes
|
|
280
|
+
const methodMatch = line.match(/^(\w+)\s*\(/);
|
|
281
|
+
if (methodMatch && this.isInClass(lines, i)) {
|
|
282
|
+
const boundary = this.findMethodBoundary(lines, i, methodMatch[1]);
|
|
283
|
+
if (boundary) result.addBoundary(boundary);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Find function boundary
|
|
290
|
+
*/
|
|
291
|
+
findFunctionBoundary(lines, startLine, name, type) {
|
|
292
|
+
let braceCount = 0;
|
|
293
|
+
let foundBrace = false;
|
|
294
|
+
|
|
295
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
296
|
+
const line = lines[i];
|
|
297
|
+
|
|
298
|
+
for (let j = 0; j < line.length; j++) {
|
|
299
|
+
if (line[j] === '{') {
|
|
300
|
+
braceCount++;
|
|
301
|
+
foundBrace = true;
|
|
302
|
+
} else if (line[j] === '}') {
|
|
303
|
+
braceCount--;
|
|
304
|
+
if (foundBrace && braceCount === 0) {
|
|
305
|
+
const boundary = new Boundary(
|
|
306
|
+
BOUNDARY_TYPES.FUNCTION,
|
|
307
|
+
startLine,
|
|
308
|
+
i,
|
|
309
|
+
name
|
|
310
|
+
);
|
|
311
|
+
boundary.metadata.type = type;
|
|
312
|
+
return boundary;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Find arrow function boundary
|
|
323
|
+
*/
|
|
324
|
+
findArrowFunctionBoundary(lines, startLine, name) {
|
|
325
|
+
let braceCount = 0;
|
|
326
|
+
let foundBrace = false;
|
|
327
|
+
let foundArrow = false;
|
|
328
|
+
|
|
329
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
330
|
+
const line = lines[i];
|
|
331
|
+
|
|
332
|
+
if (line.includes('=>')) {
|
|
333
|
+
foundArrow = true;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
for (let j = 0; j < line.length; j++) {
|
|
337
|
+
if (line[j] === '{') {
|
|
338
|
+
braceCount++;
|
|
339
|
+
foundBrace = true;
|
|
340
|
+
} else if (line[j] === '}') {
|
|
341
|
+
braceCount--;
|
|
342
|
+
if (foundBrace && foundArrow && braceCount === 0) {
|
|
343
|
+
const boundary = new Boundary(
|
|
344
|
+
BOUNDARY_TYPES.FUNCTION,
|
|
345
|
+
startLine,
|
|
346
|
+
i,
|
|
347
|
+
name
|
|
348
|
+
);
|
|
349
|
+
boundary.metadata.type = 'arrow';
|
|
350
|
+
return boundary;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Find method boundary
|
|
361
|
+
*/
|
|
362
|
+
findMethodBoundary(lines, startLine, name) {
|
|
363
|
+
let braceCount = 0;
|
|
364
|
+
let foundBrace = false;
|
|
365
|
+
|
|
366
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
367
|
+
const line = lines[i];
|
|
368
|
+
|
|
369
|
+
for (let j = 0; j < line.length; j++) {
|
|
370
|
+
if (line[j] === '{') {
|
|
371
|
+
braceCount++;
|
|
372
|
+
foundBrace = true;
|
|
373
|
+
} else if (line[j] === '}') {
|
|
374
|
+
braceCount--;
|
|
375
|
+
if (foundBrace && braceCount === 0) {
|
|
376
|
+
const boundary = new Boundary(
|
|
377
|
+
BOUNDARY_TYPES.FUNCTION,
|
|
378
|
+
startLine,
|
|
379
|
+
i,
|
|
380
|
+
name
|
|
381
|
+
);
|
|
382
|
+
boundary.metadata.type = 'method';
|
|
383
|
+
return boundary;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Detect class boundaries
|
|
394
|
+
*/
|
|
395
|
+
detectClasses(lines, result) {
|
|
396
|
+
for (let i = 0; i < lines.length; i++) {
|
|
397
|
+
const line = lines[i].trim();
|
|
398
|
+
|
|
399
|
+
const classMatch = line.match(/^class\s+(\w+)/);
|
|
400
|
+
if (classMatch) {
|
|
401
|
+
const boundary = this.findClassBoundary(lines, i, classMatch[1]);
|
|
402
|
+
if (boundary) result.addBoundary(boundary);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Find class boundary
|
|
409
|
+
*/
|
|
410
|
+
findClassBoundary(lines, startLine, name) {
|
|
411
|
+
let braceCount = 0;
|
|
412
|
+
let foundBrace = false;
|
|
413
|
+
|
|
414
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
415
|
+
const line = lines[i];
|
|
416
|
+
|
|
417
|
+
for (let j = 0; j < line.length; j++) {
|
|
418
|
+
if (line[j] === '{') {
|
|
419
|
+
braceCount++;
|
|
420
|
+
foundBrace = true;
|
|
421
|
+
} else if (line[j] === '}') {
|
|
422
|
+
braceCount--;
|
|
423
|
+
if (foundBrace && braceCount === 0) {
|
|
424
|
+
return new Boundary(
|
|
425
|
+
BOUNDARY_TYPES.CLASS,
|
|
426
|
+
startLine,
|
|
427
|
+
i,
|
|
428
|
+
name
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Detect utility sections
|
|
440
|
+
*/
|
|
441
|
+
detectUtilities(lines, result) {
|
|
442
|
+
// Look for sections with utility functions
|
|
443
|
+
let utilityStart = null;
|
|
444
|
+
let utilityName = null;
|
|
445
|
+
|
|
446
|
+
for (let i = 0; i < lines.length; i++) {
|
|
447
|
+
const line = lines[i].trim();
|
|
448
|
+
|
|
449
|
+
// Detect utility section comments
|
|
450
|
+
if (line.startsWith('//') && (line.includes('utility') || line.includes('helper'))) {
|
|
451
|
+
if (utilityStart) {
|
|
452
|
+
// Close previous utility section
|
|
453
|
+
const boundary = new Boundary(
|
|
454
|
+
BOUNDARY_TYPES.UTILITY,
|
|
455
|
+
utilityStart,
|
|
456
|
+
i - 1,
|
|
457
|
+
utilityName || 'utilities'
|
|
458
|
+
);
|
|
459
|
+
result.addBoundary(boundary);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
utilityStart = i;
|
|
463
|
+
utilityName = line.replace('//', '').trim();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Close final utility section
|
|
468
|
+
if (utilityStart) {
|
|
469
|
+
const boundary = new Boundary(
|
|
470
|
+
BOUNDARY_TYPES.UTILITY,
|
|
471
|
+
utilityStart,
|
|
472
|
+
lines.length - 1,
|
|
473
|
+
utilityName || 'utilities'
|
|
474
|
+
);
|
|
475
|
+
result.addBoundary(boundary);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Detect comment blocks
|
|
481
|
+
*/
|
|
482
|
+
detectCommentBlocks(lines, result) {
|
|
483
|
+
let commentStart = null;
|
|
484
|
+
let commentType = null;
|
|
485
|
+
|
|
486
|
+
for (let i = 0; i < lines.length; i++) {
|
|
487
|
+
const line = lines[i].trim();
|
|
488
|
+
|
|
489
|
+
if (line.startsWith('/*')) {
|
|
490
|
+
commentStart = i;
|
|
491
|
+
commentType = 'block';
|
|
492
|
+
} else if (line.startsWith('//')) {
|
|
493
|
+
// Single line comment
|
|
494
|
+
const boundary = new Boundary(
|
|
495
|
+
BOUNDARY_TYPES.COMMENT,
|
|
496
|
+
i,
|
|
497
|
+
i,
|
|
498
|
+
'single-line-comment'
|
|
499
|
+
);
|
|
500
|
+
result.addBoundary(boundary);
|
|
501
|
+
} else if (commentStart && line.endsWith('*/')) {
|
|
502
|
+
// End of block comment
|
|
503
|
+
const boundary = new Boundary(
|
|
504
|
+
BOUNDARY_TYPES.COMMENT,
|
|
505
|
+
commentStart,
|
|
506
|
+
i,
|
|
507
|
+
'block-comment'
|
|
508
|
+
);
|
|
509
|
+
result.addBoundary(boundary);
|
|
510
|
+
commentStart = null;
|
|
511
|
+
commentType = null;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Detect boundaries in Markdown files
|
|
518
|
+
*/
|
|
519
|
+
async detectMarkdownBoundaries(content, lines, result) {
|
|
520
|
+
for (let i = 0; i < lines.length; i++) {
|
|
521
|
+
const line = lines[i];
|
|
522
|
+
|
|
523
|
+
// Headers
|
|
524
|
+
const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
525
|
+
if (headerMatch) {
|
|
526
|
+
const level = headerMatch[1].length;
|
|
527
|
+
const title = headerMatch[2];
|
|
528
|
+
|
|
529
|
+
const boundary = new Boundary(
|
|
530
|
+
BOUNDARY_TYPES.MODULE,
|
|
531
|
+
i,
|
|
532
|
+
i,
|
|
533
|
+
title
|
|
534
|
+
);
|
|
535
|
+
boundary.metadata.level = level;
|
|
536
|
+
result.addBoundary(boundary);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Code blocks
|
|
540
|
+
if (line.startsWith('```')) {
|
|
541
|
+
const boundary = new Boundary(
|
|
542
|
+
BOUNDARY_TYPES.BLOCK,
|
|
543
|
+
i,
|
|
544
|
+
i,
|
|
545
|
+
'code-block'
|
|
546
|
+
);
|
|
547
|
+
result.addBoundary(boundary);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Detect boundaries in text files
|
|
554
|
+
*/
|
|
555
|
+
async detectTextBoundaries(content, lines, result) {
|
|
556
|
+
// Simple paragraph detection
|
|
557
|
+
let paragraphStart = null;
|
|
558
|
+
|
|
559
|
+
for (let i = 0; i < lines.length; i++) {
|
|
560
|
+
const line = lines[i].trim();
|
|
561
|
+
|
|
562
|
+
if (line !== '') {
|
|
563
|
+
if (paragraphStart === null) {
|
|
564
|
+
paragraphStart = i;
|
|
565
|
+
}
|
|
566
|
+
} else {
|
|
567
|
+
if (paragraphStart !== null) {
|
|
568
|
+
const boundary = new Boundary(
|
|
569
|
+
BOUNDARY_TYPES.BLOCK,
|
|
570
|
+
paragraphStart,
|
|
571
|
+
i - 1,
|
|
572
|
+
'paragraph'
|
|
573
|
+
);
|
|
574
|
+
result.addBoundary(boundary);
|
|
575
|
+
paragraphStart = null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Handle final paragraph
|
|
581
|
+
if (paragraphStart !== null) {
|
|
582
|
+
const boundary = new Boundary(
|
|
583
|
+
BOUNDARY_TYPES.BLOCK,
|
|
584
|
+
paragraphStart,
|
|
585
|
+
lines.length - 1,
|
|
586
|
+
'paragraph'
|
|
587
|
+
);
|
|
588
|
+
result.addBoundary(boundary);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Check if line is inside a class
|
|
594
|
+
*/
|
|
595
|
+
isInClass(lines, lineIndex) {
|
|
596
|
+
// Simple check - look backwards for class declaration
|
|
597
|
+
for (let i = lineIndex - 1; i >= 0; i--) {
|
|
598
|
+
const line = lines[i].trim();
|
|
599
|
+
if (line.startsWith('class ')) {
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
if (line.startsWith('function ') || line.startsWith('const ')) {
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Analyze overall structure
|
|
611
|
+
*/
|
|
612
|
+
analyzeStructure(result) {
|
|
613
|
+
// Calculate complexity metrics
|
|
614
|
+
const functions = result.getBoundariesByType(BOUNDARY_TYPES.FUNCTION);
|
|
615
|
+
const classes = result.getBoundariesByType(BOUNDARY_TYPES.CLASS);
|
|
616
|
+
|
|
617
|
+
let totalComplexity = 0;
|
|
618
|
+
let totalSize = 0;
|
|
619
|
+
|
|
620
|
+
for (const boundary of [...functions, ...classes]) {
|
|
621
|
+
// Simple complexity estimation based on size
|
|
622
|
+
boundary.complexity = Math.min(10, Math.ceil(boundary.lineCount / 20));
|
|
623
|
+
totalComplexity += boundary.complexity;
|
|
624
|
+
totalSize += boundary.lineCount;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
result.metadata.complexity = totalComplexity > 20 ? 'high' :
|
|
628
|
+
totalComplexity > 10 ? 'medium' : 'low';
|
|
629
|
+
|
|
630
|
+
result.metadata.cohesion = this.assessCohesion(result);
|
|
631
|
+
result.metadata.coupling = this.assessCoupling(result);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Assess cohesion
|
|
636
|
+
*/
|
|
637
|
+
assessCohesion(result) {
|
|
638
|
+
// Simple cohesion assessment based on boundary distribution
|
|
639
|
+
const functions = result.getBoundariesByType(BOUNDARY_TYPES.FUNCTION);
|
|
640
|
+
const avgFunctionSize = functions.length > 0 ?
|
|
641
|
+
functions.reduce((sum, f) => sum + f.lineCount, 0) / functions.length : 0;
|
|
642
|
+
|
|
643
|
+
if (avgFunctionSize > 100) return 'low';
|
|
644
|
+
if (avgFunctionSize > 50) return 'medium';
|
|
645
|
+
return 'high';
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Assess coupling
|
|
650
|
+
*/
|
|
651
|
+
assessCoupling(result) {
|
|
652
|
+
// Simple coupling assessment based on imports
|
|
653
|
+
const imports = result.getBoundariesByType(BOUNDARY_TYPES.IMPORT);
|
|
654
|
+
|
|
655
|
+
if (imports.length > 10) return 'high';
|
|
656
|
+
if (imports.length > 5) return 'medium';
|
|
657
|
+
return 'low';
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Get refactoring recommendations
|
|
662
|
+
*/
|
|
663
|
+
getRefactoringRecommendations(result) {
|
|
664
|
+
const recommendations = [];
|
|
665
|
+
|
|
666
|
+
// Large functions
|
|
667
|
+
const largeFunctions = result.getBoundariesByType(BOUNDARY_TYPES.FUNCTION)
|
|
668
|
+
.filter(f => f.lineCount > 50);
|
|
669
|
+
|
|
670
|
+
if (largeFunctions.length > 0) {
|
|
671
|
+
recommendations.push({
|
|
672
|
+
type: 'extract_functions',
|
|
673
|
+
priority: 'high',
|
|
674
|
+
description: `${largeFunctions.length} functions are too large and should be split`,
|
|
675
|
+
boundaries: largeFunctions.map(f => ({ name: f.name, lineCount: f.lineCount }))
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Large classes
|
|
680
|
+
const largeClasses = result.getBoundariesByType(BOUNDARY_TYPES.CLASS)
|
|
681
|
+
.filter(c => c.lineCount > 200);
|
|
682
|
+
|
|
683
|
+
if (largeClasses.length > 0) {
|
|
684
|
+
recommendations.push({
|
|
685
|
+
type: 'split_classes',
|
|
686
|
+
priority: 'medium',
|
|
687
|
+
description: `${largeClasses.length} classes are too large and should be split`,
|
|
688
|
+
boundaries: largeClasses.map(c => ({ name: c.name, lineCount: c.lineCount }))
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// Utility extraction
|
|
693
|
+
const utilities = result.getBoundariesByType(BOUNDARY_TYPES.UTILITY);
|
|
694
|
+
if (utilities.length === 0 && result.metadata.totalBoundaries > 5) {
|
|
695
|
+
recommendations.push({
|
|
696
|
+
type: 'extract_utilities',
|
|
697
|
+
priority: 'low',
|
|
698
|
+
description: 'Consider extracting utility functions to separate modules',
|
|
699
|
+
boundaries: []
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
return recommendations;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
module.exports = {
|
|
708
|
+
BoundaryDetector,
|
|
709
|
+
BoundaryDetectionResult,
|
|
710
|
+
Boundary,
|
|
711
|
+
BOUNDARY_TYPES
|
|
712
|
+
};
|