vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- package/src/validation/metrics-calculator.js +27 -551
|
@@ -7,24 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
|
+
const BoundaryScanner = require('./boundary-scanner');
|
|
11
|
+
const {
|
|
12
|
+
BOUNDARY_TYPES,
|
|
13
|
+
groupBoundariesByType,
|
|
14
|
+
findBoundaryRelationships,
|
|
15
|
+
generateBoundaryRecommendations
|
|
16
|
+
} = require('./boundary-utils');
|
|
10
17
|
|
|
11
18
|
/**
|
|
12
|
-
* Boundary
|
|
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
|
|
19
|
+
* Boundary Detection Result class
|
|
28
20
|
*/
|
|
29
21
|
class BoundaryDetectionResult {
|
|
30
22
|
constructor(filePath) {
|
|
@@ -49,664 +41,269 @@ class BoundaryDetectionResult {
|
|
|
49
41
|
this.metadata.byType[boundary.type]++;
|
|
50
42
|
}
|
|
51
43
|
|
|
52
|
-
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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);
|
|
44
|
+
getSummary() {
|
|
45
|
+
return {
|
|
46
|
+
filePath: this.filePath,
|
|
47
|
+
totalBoundaries: this.metadata.totalBoundaries,
|
|
48
|
+
byType: this.metadata.byType,
|
|
49
|
+
averageSize: this.boundaries.length > 0 ?
|
|
50
|
+
this.boundaries.reduce((sum, b) => sum + b.size, 0) / this.boundaries.length : 0,
|
|
51
|
+
complexity: this.metadata.complexity,
|
|
52
|
+
cohesion: this.metadata.cohesion,
|
|
53
|
+
coupling: this.metadata.coupling
|
|
54
|
+
};
|
|
108
55
|
}
|
|
109
56
|
}
|
|
110
57
|
|
|
111
58
|
/**
|
|
112
|
-
*
|
|
59
|
+
* Boundary Detector class
|
|
113
60
|
*/
|
|
114
61
|
class BoundaryDetector {
|
|
115
62
|
constructor(options = {}) {
|
|
116
63
|
this.options = {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
64
|
+
includeComments: options.includeComments !== false,
|
|
65
|
+
includeImports: options.includeImports !== false,
|
|
66
|
+
includeExports: options.includeExports !== false,
|
|
67
|
+
minBoundarySize: options.minBoundarySize || 5,
|
|
68
|
+
analysisDepth: options.analysisDepth || 'standard',
|
|
121
69
|
...options
|
|
122
70
|
};
|
|
71
|
+
|
|
72
|
+
this.scanner = new BoundaryScanner(this.options);
|
|
123
73
|
}
|
|
124
74
|
|
|
125
|
-
/**
|
|
126
|
-
* Detect boundaries in a file
|
|
127
|
-
*/
|
|
128
75
|
async detectBoundaries(filePath) {
|
|
129
|
-
const result = new BoundaryDetectionResult(filePath);
|
|
130
|
-
|
|
131
76
|
try {
|
|
132
|
-
const content = fs.
|
|
133
|
-
const
|
|
77
|
+
const content = await fs.promises.readFile(filePath, 'utf8');
|
|
78
|
+
const scanResult = this.scanner.scanFile(content, filePath);
|
|
134
79
|
|
|
135
|
-
|
|
136
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
80
|
+
const result = new BoundaryDetectionResult(filePath);
|
|
137
81
|
|
|
138
|
-
|
|
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
|
-
|
|
82
|
+
scanResult.boundaries.forEach(boundary => {
|
|
243
83
|
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();
|
|
84
|
+
});
|
|
254
85
|
|
|
255
|
-
|
|
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
|
-
}
|
|
86
|
+
const relationships = findBoundaryRelationships(result.boundaries);
|
|
262
87
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const boundary = this.findFunctionBoundary(lines, i, exprMatch[1], 'expression');
|
|
267
|
-
if (boundary) result.addBoundary(boundary);
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
88
|
+
result.metadata.complexity = this.calculateOverallComplexity(result.boundaries);
|
|
89
|
+
result.metadata.cohesion = this.calculateOverallCohesion(result.boundaries);
|
|
90
|
+
result.metadata.coupling = this.calculateOverallCoupling(result.boundaries, relationships);
|
|
270
91
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (arrowMatch) {
|
|
274
|
-
const boundary = this.findArrowFunctionBoundary(lines, i, arrowMatch[1]);
|
|
275
|
-
if (boundary) result.addBoundary(boundary);
|
|
276
|
-
continue;
|
|
277
|
-
}
|
|
92
|
+
result.metadata.scanMetadata = scanResult.metadata;
|
|
93
|
+
result.metadata.relationships = relationships;
|
|
278
94
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
95
|
+
return result;
|
|
96
|
+
|
|
97
|
+
} catch (error) {
|
|
98
|
+
const result = new BoundaryDetectionResult(filePath);
|
|
99
|
+
result.metadata.error = error.message;
|
|
100
|
+
return result;
|
|
285
101
|
}
|
|
286
102
|
}
|
|
287
103
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
*/
|
|
291
|
-
findFunctionBoundary(lines, startLine, name, type) {
|
|
292
|
-
let braceCount = 0;
|
|
293
|
-
let foundBrace = false;
|
|
104
|
+
async detectBoundariesInFiles(filePaths) {
|
|
105
|
+
const results = [];
|
|
294
106
|
|
|
295
|
-
for (
|
|
296
|
-
const
|
|
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
|
-
}
|
|
107
|
+
for (const filePath of filePaths) {
|
|
108
|
+
const result = await this.detectBoundaries(filePath);
|
|
109
|
+
results.push(result);
|
|
316
110
|
}
|
|
317
111
|
|
|
318
|
-
return
|
|
112
|
+
return results;
|
|
319
113
|
}
|
|
320
114
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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
|
-
}
|
|
115
|
+
async detectBoundariesInDirectory(dirPath, options = {}) {
|
|
116
|
+
const scanOptions = {
|
|
117
|
+
recursive: options.recursive !== false,
|
|
118
|
+
extensions: options.extensions || ['.js', '.ts', '.jsx', '.tsx'],
|
|
119
|
+
exclude: options.exclude || ['node_modules', '.git', 'dist'],
|
|
120
|
+
...options
|
|
121
|
+
};
|
|
355
122
|
|
|
356
|
-
|
|
123
|
+
const filePaths = await this.getFilePaths(dirPath, scanOptions);
|
|
124
|
+
return this.detectBoundariesInFiles(filePaths);
|
|
357
125
|
}
|
|
358
126
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
*/
|
|
362
|
-
findMethodBoundary(lines, startLine, name) {
|
|
363
|
-
let braceCount = 0;
|
|
364
|
-
let foundBrace = false;
|
|
127
|
+
async getFilePaths(dirPath, options) {
|
|
128
|
+
const filePaths = [];
|
|
365
129
|
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
}
|
|
130
|
+
const scanDirectory = async (currentPath, depth = 0) => {
|
|
131
|
+
if (depth > (options.maxDepth || 10)) {
|
|
132
|
+
return;
|
|
386
133
|
}
|
|
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
134
|
|
|
399
|
-
const
|
|
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];
|
|
135
|
+
const entries = await fs.promises.readdir(currentPath, { withFileTypes: true });
|
|
416
136
|
|
|
417
|
-
for (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
);
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const fullPath = path.join(currentPath, entry.name);
|
|
139
|
+
|
|
140
|
+
if (entry.isDirectory()) {
|
|
141
|
+
if (options.exclude && !options.exclude.some(exclude => entry.name.includes(exclude))) {
|
|
142
|
+
if (options.recursive) {
|
|
143
|
+
await scanDirectory(fullPath, depth + 1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} else if (entry.isFile()) {
|
|
147
|
+
const ext = path.extname(entry.name);
|
|
148
|
+
if (options.extensions.includes(ext)) {
|
|
149
|
+
filePaths.push(fullPath);
|
|
430
150
|
}
|
|
431
151
|
}
|
|
432
152
|
}
|
|
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;
|
|
153
|
+
};
|
|
485
154
|
|
|
486
|
-
|
|
487
|
-
|
|
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
|
-
}
|
|
155
|
+
await scanDirectory(dirPath);
|
|
156
|
+
return filePaths;
|
|
550
157
|
}
|
|
551
158
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
*/
|
|
555
|
-
async detectTextBoundaries(content, lines, result) {
|
|
556
|
-
// Simple paragraph detection
|
|
557
|
-
let paragraphStart = null;
|
|
159
|
+
calculateOverallComplexity(boundaries) {
|
|
160
|
+
if (boundaries.length === 0) return 'unknown';
|
|
558
161
|
|
|
559
|
-
|
|
560
|
-
|
|
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
|
-
}
|
|
162
|
+
const complexities = boundaries.map(b => b.complexity || 1);
|
|
163
|
+
const avgComplexity = complexities.reduce((sum, c) => sum + c, 0) / complexities.length;
|
|
579
164
|
|
|
580
|
-
|
|
581
|
-
if (
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
lines.length - 1,
|
|
586
|
-
'paragraph'
|
|
587
|
-
);
|
|
588
|
-
result.addBoundary(boundary);
|
|
589
|
-
}
|
|
165
|
+
if (avgComplexity > 7) return 'very_high';
|
|
166
|
+
if (avgComplexity > 5) return 'high';
|
|
167
|
+
if (avgComplexity > 3) return 'medium';
|
|
168
|
+
if (avgComplexity > 2) return 'low';
|
|
169
|
+
return 'very_low';
|
|
590
170
|
}
|
|
591
171
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
return
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
return
|
|
172
|
+
calculateOverallCohesion(boundaries) {
|
|
173
|
+
if (boundaries.length === 0) return 'unknown';
|
|
174
|
+
|
|
175
|
+
const cohesions = boundaries.map(b => b.cohesion || 'medium');
|
|
176
|
+
const cohesionScores = cohesions.map(c => {
|
|
177
|
+
switch (c) {
|
|
178
|
+
case 'very_low': return 1;
|
|
179
|
+
case 'low': return 2;
|
|
180
|
+
case 'medium': return 3;
|
|
181
|
+
case 'high': return 4;
|
|
182
|
+
case 'very_high': return 5;
|
|
183
|
+
default: return 3;
|
|
604
184
|
}
|
|
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;
|
|
185
|
+
});
|
|
619
186
|
|
|
620
|
-
|
|
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
|
-
}
|
|
187
|
+
const avgCohesion = cohesionScores.reduce((sum, c) => sum + c, 0) / cohesionScores.length;
|
|
626
188
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
189
|
+
if (avgCohesion > 4.5) return 'very_high';
|
|
190
|
+
if (avgCohesion > 3.5) return 'high';
|
|
191
|
+
if (avgCohesion > 2.5) return 'medium';
|
|
192
|
+
if (avgCohesion > 1.5) return 'low';
|
|
193
|
+
return 'very_low';
|
|
632
194
|
}
|
|
633
195
|
|
|
634
|
-
|
|
635
|
-
|
|
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;
|
|
196
|
+
calculateOverallCoupling(boundaries, relationships) {
|
|
197
|
+
if (boundaries.length === 0) return 'unknown';
|
|
642
198
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
199
|
+
const couplingScores = boundaries.map(b => {
|
|
200
|
+
const boundaryRelationships = relationships.filter(r => r.source === b.name);
|
|
201
|
+
if (boundaryRelationships.length === 0) return 5;
|
|
202
|
+
|
|
203
|
+
const avgStrength = boundaryRelationships.reduce((sum, r) => sum + r.strength, 0) / boundaryRelationships.length;
|
|
204
|
+
|
|
205
|
+
if (avgStrength > 4) return 1;
|
|
206
|
+
if (avgStrength > 3) return 2;
|
|
207
|
+
if (avgStrength > 2) return 3;
|
|
208
|
+
if (avgStrength > 1) return 4;
|
|
209
|
+
return 5;
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const avgCoupling = couplingScores.reduce((sum, c) => sum + c, 0) / couplingScores.length;
|
|
213
|
+
|
|
214
|
+
if (avgCoupling > 4.5) return 'very_low';
|
|
215
|
+
if (avgCoupling > 3.5) return 'low';
|
|
216
|
+
if (avgCoupling > 2.5) return 'medium';
|
|
217
|
+
if (avgCoupling > 1.5) return 'high';
|
|
218
|
+
return 'very_high';
|
|
658
219
|
}
|
|
659
220
|
|
|
660
|
-
|
|
661
|
-
* Get refactoring recommendations
|
|
662
|
-
*/
|
|
663
|
-
getRefactoringRecommendations(result) {
|
|
221
|
+
generateRefactoringRecommendations(result) {
|
|
664
222
|
const recommendations = [];
|
|
665
223
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
.filter(f => f.lineCount > 50);
|
|
224
|
+
const boundaryRecommendations = generateBoundaryRecommendations(result.boundaries);
|
|
225
|
+
recommendations.push(...boundaryRecommendations);
|
|
669
226
|
|
|
670
|
-
if (
|
|
227
|
+
if (result.metadata.totalBoundaries > 20) {
|
|
671
228
|
recommendations.push({
|
|
672
|
-
type: '
|
|
229
|
+
type: 'file_structure',
|
|
673
230
|
priority: 'high',
|
|
674
|
-
|
|
675
|
-
|
|
231
|
+
message: 'File has too many boundaries (>20)',
|
|
232
|
+
action: 'split_into_modules'
|
|
676
233
|
});
|
|
677
234
|
}
|
|
678
235
|
|
|
679
|
-
|
|
680
|
-
const largeClasses = result.getBoundariesByType(BOUNDARY_TYPES.CLASS)
|
|
681
|
-
.filter(c => c.lineCount > 200);
|
|
682
|
-
|
|
683
|
-
if (largeClasses.length > 0) {
|
|
236
|
+
if (result.metadata.complexity === 'very_high') {
|
|
684
237
|
recommendations.push({
|
|
685
|
-
type: '
|
|
686
|
-
priority: '
|
|
687
|
-
|
|
688
|
-
|
|
238
|
+
type: 'complexity',
|
|
239
|
+
priority: 'high',
|
|
240
|
+
message: 'File has very high complexity',
|
|
241
|
+
action: 'reduce_complexity'
|
|
689
242
|
});
|
|
690
243
|
}
|
|
691
244
|
|
|
692
|
-
|
|
693
|
-
const utilities = result.getBoundariesByType(BOUNDARY_TYPES.UTILITY);
|
|
694
|
-
if (utilities.length === 0 && result.metadata.totalBoundaries > 5) {
|
|
245
|
+
if (result.metadata.cohesion === 'very_low') {
|
|
695
246
|
recommendations.push({
|
|
696
|
-
type: '
|
|
697
|
-
priority: '
|
|
698
|
-
|
|
699
|
-
|
|
247
|
+
type: 'cohesion',
|
|
248
|
+
priority: 'medium',
|
|
249
|
+
message: 'File has very low cohesion',
|
|
250
|
+
action: 'improve_cohesion'
|
|
700
251
|
});
|
|
701
252
|
}
|
|
702
253
|
|
|
703
254
|
return recommendations;
|
|
704
255
|
}
|
|
256
|
+
|
|
257
|
+
async exportResults(result, outputPath) {
|
|
258
|
+
const exportData = {
|
|
259
|
+
filePath: result.filePath,
|
|
260
|
+
timestamp: new Date().toISOString(),
|
|
261
|
+
summary: result.getSummary(),
|
|
262
|
+
boundaries: result.boundaries,
|
|
263
|
+
metadata: result.metadata,
|
|
264
|
+
recommendations: this.generateRefactoringRecommendations(result)
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
await fs.promises.writeFile(outputPath, JSON.stringify(exportData, null, 2), 'utf8');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
getDetectorInfo() {
|
|
271
|
+
return {
|
|
272
|
+
supportedTypes: Object.values(BOUNDARY_TYPES),
|
|
273
|
+
defaultOptions: this.options,
|
|
274
|
+
features: [
|
|
275
|
+
'boundary detection',
|
|
276
|
+
'complexity analysis',
|
|
277
|
+
'cohesion calculation',
|
|
278
|
+
'coupling analysis',
|
|
279
|
+
'refactoring recommendations',
|
|
280
|
+
'batch processing'
|
|
281
|
+
],
|
|
282
|
+
version: '1.0.0'
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
static createDefault(config = {}) {
|
|
287
|
+
return new BoundaryDetector({
|
|
288
|
+
includeComments: true,
|
|
289
|
+
includeImports: true,
|
|
290
|
+
includeExports: true,
|
|
291
|
+
minBoundarySize: 5,
|
|
292
|
+
analysisDepth: 'standard',
|
|
293
|
+
...config
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
static createForRefactoring(config = {}) {
|
|
298
|
+
return new BoundaryDetector({
|
|
299
|
+
includeComments: false,
|
|
300
|
+
includeImports: true,
|
|
301
|
+
includeExports: true,
|
|
302
|
+
minBoundarySize: 10,
|
|
303
|
+
analysisDepth: 'deep',
|
|
304
|
+
...config
|
|
305
|
+
});
|
|
306
|
+
}
|
|
705
307
|
}
|
|
706
308
|
|
|
707
|
-
module.exports =
|
|
708
|
-
BoundaryDetector,
|
|
709
|
-
BoundaryDetectionResult,
|
|
710
|
-
Boundary,
|
|
711
|
-
BOUNDARY_TYPES
|
|
712
|
-
};
|
|
309
|
+
module.exports = BoundaryDetector;
|