vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739
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,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeoutConfigManager
|
|
3
|
+
*
|
|
4
|
+
* Manages timeout configuration including mode (fixed/adaptive),
|
|
5
|
+
* default timeout values, buffer percentages, and EWMA alpha values.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const EventEmitter = require('events');
|
|
9
|
+
|
|
10
|
+
class TimeoutConfigManager extends EventEmitter {
|
|
11
|
+
/**
|
|
12
|
+
* Create timeout config manager
|
|
13
|
+
* @param {Object} [initialConfig] - Initial configuration
|
|
14
|
+
*/
|
|
15
|
+
constructor(initialConfig = {}) {
|
|
16
|
+
super();
|
|
17
|
+
|
|
18
|
+
this.config = {
|
|
19
|
+
mode: initialConfig.mode || 'fixed',
|
|
20
|
+
defaultTimeout: initialConfig.defaultTimeout || 300000, // 5 minutes
|
|
21
|
+
bufferPercentage: initialConfig.bufferPercentage || 50,
|
|
22
|
+
ewmaAlpha: initialConfig.ewmaAlpha || 0.3,
|
|
23
|
+
minTimeout: initialConfig.minTimeout || 30000, // 30 seconds
|
|
24
|
+
maxTimeout: initialConfig.maxTimeout || 600000 // 10 minutes
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Set timeout mode
|
|
30
|
+
* @param {string} mode - Mode ('fixed' or 'adaptive')
|
|
31
|
+
*/
|
|
32
|
+
setMode(mode) {
|
|
33
|
+
if (mode !== 'fixed' && mode !== 'adaptive') {
|
|
34
|
+
throw new Error(`Invalid mode: ${mode}. Must be 'fixed' or 'adaptive'`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.config.mode = mode;
|
|
38
|
+
this.emit('mode-changed', mode);
|
|
39
|
+
this.emit('config-changed', this.getConfig());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get current mode
|
|
44
|
+
* @returns {string} Current mode
|
|
45
|
+
*/
|
|
46
|
+
getMode() {
|
|
47
|
+
return this.config.mode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if adaptive mode is enabled
|
|
52
|
+
* @returns {boolean} True if adaptive mode
|
|
53
|
+
*/
|
|
54
|
+
isAdaptiveMode() {
|
|
55
|
+
return this.config.mode === 'adaptive';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Set default timeout
|
|
60
|
+
* @param {number} timeout - Default timeout in milliseconds
|
|
61
|
+
*/
|
|
62
|
+
setDefaultTimeout(timeout) {
|
|
63
|
+
if (timeout <= 0) {
|
|
64
|
+
throw new Error('Default timeout must be greater than 0');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.config.defaultTimeout = timeout;
|
|
68
|
+
this.emit('config-changed', this.getConfig());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get default timeout
|
|
73
|
+
* @returns {number} Default timeout in milliseconds
|
|
74
|
+
*/
|
|
75
|
+
getDefaultTimeout() {
|
|
76
|
+
return this.config.defaultTimeout;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Set buffer percentage
|
|
81
|
+
* @param {number} percentage - Buffer percentage (0-200)
|
|
82
|
+
*/
|
|
83
|
+
setBufferPercentage(percentage) {
|
|
84
|
+
if (percentage < 0 || percentage > 200) {
|
|
85
|
+
throw new Error('Buffer percentage must be between 0 and 200');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.config.bufferPercentage = percentage;
|
|
89
|
+
this.emit('config-changed', this.getConfig());
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get buffer percentage
|
|
94
|
+
* @returns {number} Buffer percentage
|
|
95
|
+
*/
|
|
96
|
+
getBufferPercentage() {
|
|
97
|
+
return this.config.bufferPercentage;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set EWMA alpha value
|
|
102
|
+
* @param {number} alpha - Alpha value (0-1)
|
|
103
|
+
*/
|
|
104
|
+
setEWMAAlpha(alpha) {
|
|
105
|
+
if (alpha < 0 || alpha > 1) {
|
|
106
|
+
throw new Error('EWMA alpha must be between 0 and 1');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.config.ewmaAlpha = alpha;
|
|
110
|
+
this.emit('config-changed', this.getConfig());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get EWMA alpha value
|
|
115
|
+
* @returns {number} Alpha value
|
|
116
|
+
*/
|
|
117
|
+
getEWMAAlpha() {
|
|
118
|
+
return this.config.ewmaAlpha;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Set minimum timeout
|
|
123
|
+
* @param {number} timeout - Minimum timeout in milliseconds
|
|
124
|
+
*/
|
|
125
|
+
setMinTimeout(timeout) {
|
|
126
|
+
if (timeout < 0) {
|
|
127
|
+
throw new Error('Minimum timeout must be non-negative');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.config.minTimeout = timeout;
|
|
131
|
+
this.emit('config-changed', this.getConfig());
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Set maximum timeout
|
|
136
|
+
* @param {number} timeout - Maximum timeout in milliseconds
|
|
137
|
+
*/
|
|
138
|
+
setMaxTimeout(timeout) {
|
|
139
|
+
if (timeout < this.config.minTimeout) {
|
|
140
|
+
throw new Error('Maximum timeout must be greater than minimum timeout');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this.config.maxTimeout = timeout;
|
|
144
|
+
this.emit('config-changed', this.getConfig());
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get complete configuration
|
|
149
|
+
* @returns {Object} Configuration object
|
|
150
|
+
*/
|
|
151
|
+
getConfig() {
|
|
152
|
+
return { ...this.config };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Reset to default configuration
|
|
157
|
+
*/
|
|
158
|
+
reset() {
|
|
159
|
+
this.config = {
|
|
160
|
+
mode: 'fixed',
|
|
161
|
+
defaultTimeout: 300000,
|
|
162
|
+
bufferPercentage: 50,
|
|
163
|
+
ewmaAlpha: 0.3,
|
|
164
|
+
minTimeout: 30000,
|
|
165
|
+
maxTimeout: 600000
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
this.emit('config-changed', this.getConfig());
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = { TimeoutConfigManager };
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST-Based Code Structure Analyzer
|
|
3
|
+
* Analyzes code structure to identify logical module boundaries
|
|
4
|
+
* Part of specs/010-555-max-file-size implementation (Task 102)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Analyze file structure to identify logical boundaries
|
|
12
|
+
* Uses simple heuristics without heavy AST parsing dependencies
|
|
13
|
+
* @param {string} filePath - Path to file to analyze
|
|
14
|
+
* @returns {Object} Analysis results with suggested module boundaries
|
|
15
|
+
*/
|
|
16
|
+
function analyzeFileStructure(filePath) {
|
|
17
|
+
try {
|
|
18
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
19
|
+
const lines = content.split('\n');
|
|
20
|
+
|
|
21
|
+
const analysis = {
|
|
22
|
+
filePath,
|
|
23
|
+
totalLines: lines.length,
|
|
24
|
+
functions: [],
|
|
25
|
+
classes: [],
|
|
26
|
+
exports: [],
|
|
27
|
+
imports: [],
|
|
28
|
+
comments: [],
|
|
29
|
+
sections: [],
|
|
30
|
+
suggestedModules: []
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Track current section
|
|
34
|
+
let currentSection = null;
|
|
35
|
+
let sectionStart = 0;
|
|
36
|
+
|
|
37
|
+
// Analyze line by line
|
|
38
|
+
for (let i = 0; i < lines.length; i++) {
|
|
39
|
+
const line = lines[i];
|
|
40
|
+
const trimmed = line.trim();
|
|
41
|
+
|
|
42
|
+
// Detect section headers (comments with separators)
|
|
43
|
+
if (isSectionHeader(trimmed)) {
|
|
44
|
+
if (currentSection) {
|
|
45
|
+
currentSection.endLine = i - 1;
|
|
46
|
+
currentSection.lineCount = currentSection.endLine - currentSection.startLine + 1;
|
|
47
|
+
analysis.sections.push(currentSection);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
currentSection = {
|
|
51
|
+
title: extractSectionTitle(trimmed),
|
|
52
|
+
startLine: i,
|
|
53
|
+
endLine: null,
|
|
54
|
+
lineCount: 0
|
|
55
|
+
};
|
|
56
|
+
sectionStart = i;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Detect function declarations
|
|
60
|
+
if (isFunctionDeclaration(trimmed)) {
|
|
61
|
+
const funcInfo = extractFunctionInfo(trimmed, i);
|
|
62
|
+
if (funcInfo) {
|
|
63
|
+
analysis.functions.push(funcInfo);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Detect class declarations
|
|
68
|
+
if (isClassDeclaration(trimmed)) {
|
|
69
|
+
const classInfo = extractClassInfo(trimmed, i);
|
|
70
|
+
if (classInfo) {
|
|
71
|
+
analysis.classes.push(classInfo);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Detect exports
|
|
76
|
+
if (isExport(trimmed)) {
|
|
77
|
+
analysis.exports.push({
|
|
78
|
+
line: i + 1,
|
|
79
|
+
text: trimmed
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Detect imports
|
|
84
|
+
if (isImport(trimmed)) {
|
|
85
|
+
analysis.imports.push({
|
|
86
|
+
line: i + 1,
|
|
87
|
+
text: trimmed
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Detect comments
|
|
92
|
+
if (isComment(trimmed)) {
|
|
93
|
+
analysis.comments.push({
|
|
94
|
+
line: i + 1,
|
|
95
|
+
text: trimmed
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Close last section
|
|
101
|
+
if (currentSection) {
|
|
102
|
+
currentSection.endLine = lines.length - 1;
|
|
103
|
+
currentSection.lineCount = currentSection.endLine - currentSection.startLine + 1;
|
|
104
|
+
analysis.sections.push(currentSection);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Generate module suggestions based on analysis
|
|
108
|
+
analysis.suggestedModules = generateModuleSuggestions(analysis);
|
|
109
|
+
|
|
110
|
+
return analysis;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
return {
|
|
113
|
+
filePath,
|
|
114
|
+
error: error.message,
|
|
115
|
+
suggestedModules: []
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if line is a section header comment
|
|
122
|
+
* @param {string} line - Trimmed line
|
|
123
|
+
* @returns {boolean}
|
|
124
|
+
*/
|
|
125
|
+
function isSectionHeader(line) {
|
|
126
|
+
// Look for comment lines with separators like:
|
|
127
|
+
// // ========= Section Name =========
|
|
128
|
+
// /* -------- Section Name -------- */
|
|
129
|
+
// // ─────────────────────────────────
|
|
130
|
+
return (
|
|
131
|
+
(line.startsWith('//') || line.startsWith('/*')) &&
|
|
132
|
+
(line.includes('===') || line.includes('---') || line.includes('━━') || line.includes('──'))
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Extract section title from header comment
|
|
138
|
+
* @param {string} line - Section header line
|
|
139
|
+
* @returns {string}
|
|
140
|
+
*/
|
|
141
|
+
function extractSectionTitle(line) {
|
|
142
|
+
// Remove comment markers and separators
|
|
143
|
+
let title = line
|
|
144
|
+
.replace(/^\/\/\s*/, '')
|
|
145
|
+
.replace(/^\/\*\s*/, '')
|
|
146
|
+
.replace(/\*\/\s*$/, '')
|
|
147
|
+
.replace(/[=\-━─]+/g, '')
|
|
148
|
+
.trim();
|
|
149
|
+
|
|
150
|
+
return title || 'Unnamed Section';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Check if line is a function declaration
|
|
155
|
+
* @param {string} line - Trimmed line
|
|
156
|
+
* @returns {boolean}
|
|
157
|
+
*/
|
|
158
|
+
function isFunctionDeclaration(line) {
|
|
159
|
+
return (
|
|
160
|
+
line.startsWith('function ') ||
|
|
161
|
+
line.startsWith('async function ') ||
|
|
162
|
+
line.includes(' function ') ||
|
|
163
|
+
/^(const|let|var)\s+\w+\s*=\s*(async\s+)?(\([^)]*\)|[a-zA-Z_$][\w$]*)\s*=>/.test(line) ||
|
|
164
|
+
/^(async\s+)?[\w$]+\s*\([^)]*\)\s*{/.test(line)
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Extract function information
|
|
170
|
+
* @param {string} line - Function declaration line
|
|
171
|
+
* @param {number} lineNum - Line number
|
|
172
|
+
* @returns {Object|null}
|
|
173
|
+
*/
|
|
174
|
+
function extractFunctionInfo(line, lineNum) {
|
|
175
|
+
let name = 'anonymous';
|
|
176
|
+
let isAsync = line.includes('async');
|
|
177
|
+
let isExported = line.includes('export');
|
|
178
|
+
|
|
179
|
+
// Try to extract function name
|
|
180
|
+
const funcMatch = line.match(/function\s+([a-zA-Z_$][\w$]*)/);
|
|
181
|
+
const arrowMatch = line.match(/(const|let|var)\s+([a-zA-Z_$][\w$]*)\s*=/);
|
|
182
|
+
const methodMatch = line.match(/^(async\s+)?([\w$]+)\s*\(/);
|
|
183
|
+
|
|
184
|
+
if (funcMatch) {
|
|
185
|
+
name = funcMatch[1];
|
|
186
|
+
} else if (arrowMatch) {
|
|
187
|
+
name = arrowMatch[2];
|
|
188
|
+
} else if (methodMatch) {
|
|
189
|
+
name = methodMatch[2];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
name,
|
|
194
|
+
line: lineNum + 1,
|
|
195
|
+
isAsync,
|
|
196
|
+
isExported
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check if line is a class declaration
|
|
202
|
+
* @param {string} line - Trimmed line
|
|
203
|
+
* @returns {boolean}
|
|
204
|
+
*/
|
|
205
|
+
function isClassDeclaration(line) {
|
|
206
|
+
return line.startsWith('class ') || line.includes(' class ');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Extract class information
|
|
211
|
+
* @param {string} line - Class declaration line
|
|
212
|
+
* @param {number} lineNum - Line number
|
|
213
|
+
* @returns {Object|null}
|
|
214
|
+
*/
|
|
215
|
+
function extractClassInfo(line, lineNum) {
|
|
216
|
+
const match = line.match(/class\s+([a-zA-Z_$][\w$]*)/);
|
|
217
|
+
if (match) {
|
|
218
|
+
return {
|
|
219
|
+
name: match[1],
|
|
220
|
+
line: lineNum + 1,
|
|
221
|
+
isExported: line.includes('export')
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Check if line is an export statement
|
|
229
|
+
* @param {string} line - Trimmed line
|
|
230
|
+
* @returns {boolean}
|
|
231
|
+
*/
|
|
232
|
+
function isExport(line) {
|
|
233
|
+
return line.startsWith('export ') || line.startsWith('module.exports');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Check if line is an import statement
|
|
238
|
+
* @param {string} line - Trimmed line
|
|
239
|
+
* @returns {boolean}
|
|
240
|
+
*/
|
|
241
|
+
function isImport(line) {
|
|
242
|
+
return line.startsWith('import ') || line.startsWith('const ') && line.includes('require(') ||
|
|
243
|
+
line.startsWith('require(');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check if line is a comment
|
|
248
|
+
* @param {string} line - Trimmed line
|
|
249
|
+
* @returns {boolean}
|
|
250
|
+
*/
|
|
251
|
+
function isComment(line) {
|
|
252
|
+
return line.startsWith('//') || line.startsWith('/*') || line.startsWith('*');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Generate module suggestions based on file analysis
|
|
257
|
+
* @param {Object} analysis - File analysis results
|
|
258
|
+
* @returns {Array} Array of module suggestions
|
|
259
|
+
*/
|
|
260
|
+
function generateModuleSuggestions(analysis) {
|
|
261
|
+
const suggestions = [];
|
|
262
|
+
|
|
263
|
+
// If file has clear sections, suggest splitting by section
|
|
264
|
+
if (analysis.sections.length > 1) {
|
|
265
|
+
analysis.sections.forEach((section, idx) => {
|
|
266
|
+
if (section.lineCount > 100) { // Only suggest if section is substantial
|
|
267
|
+
suggestions.push({
|
|
268
|
+
type: 'section-based',
|
|
269
|
+
moduleName: sanitizeModuleName(section.title),
|
|
270
|
+
startLine: section.startLine,
|
|
271
|
+
endLine: section.endLine,
|
|
272
|
+
estimatedLines: section.lineCount,
|
|
273
|
+
description: `Extract "${section.title}" section into separate module`
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// If file has many functions, suggest grouping related functions
|
|
280
|
+
if (analysis.functions.length > 10) {
|
|
281
|
+
const functionGroups = groupFunctionsByPrefix(analysis.functions);
|
|
282
|
+
Object.entries(functionGroups).forEach(([prefix, funcs]) => {
|
|
283
|
+
if (funcs.length >= 3) {
|
|
284
|
+
suggestions.push({
|
|
285
|
+
type: 'function-group',
|
|
286
|
+
moduleName: `${prefix}-functions`,
|
|
287
|
+
functions: funcs.map(f => f.name),
|
|
288
|
+
description: `Group ${funcs.length} related functions with prefix "${prefix}"`
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// If file has classes, suggest one class per module
|
|
295
|
+
if (analysis.classes.length > 1) {
|
|
296
|
+
analysis.classes.forEach(cls => {
|
|
297
|
+
suggestions.push({
|
|
298
|
+
type: 'class-based',
|
|
299
|
+
moduleName: cls.name,
|
|
300
|
+
className: cls.name,
|
|
301
|
+
description: `Extract ${cls.name} class into separate module`
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return suggestions;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Group functions by common prefix
|
|
311
|
+
* @param {Array} functions - Array of function objects
|
|
312
|
+
* @returns {Object} Grouped functions by prefix
|
|
313
|
+
*/
|
|
314
|
+
function groupFunctionsByPrefix(functions) {
|
|
315
|
+
const groups = {};
|
|
316
|
+
|
|
317
|
+
functions.forEach(func => {
|
|
318
|
+
const name = func.name;
|
|
319
|
+
// Extract prefix (e.g., "handle" from "handleClick", "get" from "getUserData")
|
|
320
|
+
const prefixMatch = name.match(/^(get|set|handle|is|has|create|update|delete|fetch|send|load|save|parse|format|validate|check)/i);
|
|
321
|
+
|
|
322
|
+
if (prefixMatch) {
|
|
323
|
+
const prefix = prefixMatch[1].toLowerCase();
|
|
324
|
+
if (!groups[prefix]) {
|
|
325
|
+
groups[prefix] = [];
|
|
326
|
+
}
|
|
327
|
+
groups[prefix].push(func);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
return groups;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Sanitize section title to valid module name
|
|
336
|
+
* @param {string} title - Section title
|
|
337
|
+
* @returns {string} Sanitized module name
|
|
338
|
+
*/
|
|
339
|
+
function sanitizeModuleName(title) {
|
|
340
|
+
return title
|
|
341
|
+
.toLowerCase()
|
|
342
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
343
|
+
.replace(/^-+|-+$/g, '');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Generate refactoring plan for a file
|
|
348
|
+
* @param {string} filePath - Path to file
|
|
349
|
+
* @param {number} targetLinesPerModule - Target lines per module (default 400)
|
|
350
|
+
* @returns {Object} Refactoring plan
|
|
351
|
+
*/
|
|
352
|
+
function generateRefactoringPlan(filePath, targetLinesPerModule = 400) {
|
|
353
|
+
const analysis = analyzeFileStructure(filePath);
|
|
354
|
+
|
|
355
|
+
if (analysis.error) {
|
|
356
|
+
return { success: false, error: analysis.error };
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const plan = {
|
|
360
|
+
sourceFile: filePath,
|
|
361
|
+
totalLines: analysis.totalLines,
|
|
362
|
+
targetLinesPerModule,
|
|
363
|
+
estimatedModuleCount: Math.ceil(analysis.totalLines / targetLinesPerModule),
|
|
364
|
+
suggestedModules: analysis.suggestedModules,
|
|
365
|
+
strategy: determineRefactoringStrategy(analysis),
|
|
366
|
+
complexity: assessRefactoringComplexity(analysis)
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
return plan;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Determine best refactoring strategy
|
|
374
|
+
* @param {Object} analysis - File analysis
|
|
375
|
+
* @returns {string} Strategy description
|
|
376
|
+
*/
|
|
377
|
+
function determineRefactoringStrategy(analysis) {
|
|
378
|
+
if (analysis.sections.length > 1) {
|
|
379
|
+
return 'section-based: File has clear sections that can be extracted';
|
|
380
|
+
} else if (analysis.classes.length > 0) {
|
|
381
|
+
return 'class-based: Extract classes into separate modules';
|
|
382
|
+
} else if (analysis.functions.length > 10) {
|
|
383
|
+
return 'function-based: Group related functions into modules';
|
|
384
|
+
} else {
|
|
385
|
+
return 'manual: Requires manual analysis and refactoring';
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Assess refactoring complexity
|
|
391
|
+
* @param {Object} analysis - File analysis
|
|
392
|
+
* @returns {string} Complexity level
|
|
393
|
+
*/
|
|
394
|
+
function assessRefactoringComplexity(analysis) {
|
|
395
|
+
const exportCount = analysis.exports.length;
|
|
396
|
+
const importCount = analysis.imports.length;
|
|
397
|
+
const functionCount = analysis.functions.length;
|
|
398
|
+
|
|
399
|
+
if (exportCount > 20 || functionCount > 50) {
|
|
400
|
+
return 'HIGH';
|
|
401
|
+
} else if (exportCount > 10 || functionCount > 20) {
|
|
402
|
+
return 'MEDIUM';
|
|
403
|
+
} else {
|
|
404
|
+
return 'LOW';
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
module.exports = {
|
|
409
|
+
analyzeFileStructure,
|
|
410
|
+
generateRefactoringPlan,
|
|
411
|
+
isSectionHeader,
|
|
412
|
+
isFunctionDeclaration,
|
|
413
|
+
isClassDeclaration,
|
|
414
|
+
isExport,
|
|
415
|
+
isImport,
|
|
416
|
+
isComment
|
|
417
|
+
};
|