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,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Framework
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive validation framework for file size refactoring operations.
|
|
5
|
+
* Provides validation rules, execution, and reporting capabilities.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const RefactoringConfig = require('../config/refactoring-config');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validation rule types
|
|
14
|
+
*/
|
|
15
|
+
const VALIDATION_TYPES = {
|
|
16
|
+
SYNTAX: 'syntax',
|
|
17
|
+
SEMANTIC: 'semantic',
|
|
18
|
+
STRUCTURAL: 'structural',
|
|
19
|
+
FUNCTIONAL: 'functional',
|
|
20
|
+
COMPLIANCE: 'compliance'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Validation severity levels
|
|
25
|
+
*/
|
|
26
|
+
const SEVERITY_LEVELS = {
|
|
27
|
+
ERROR: 'error',
|
|
28
|
+
WARNING: 'warning',
|
|
29
|
+
INFO: 'info'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validation result structure
|
|
34
|
+
*/
|
|
35
|
+
class ValidationResult {
|
|
36
|
+
constructor(type, severity, message, filePath = null, line = null, column = null) {
|
|
37
|
+
this.type = type;
|
|
38
|
+
this.severity = severity;
|
|
39
|
+
this.message = message;
|
|
40
|
+
this.filePath = filePath;
|
|
41
|
+
this.line = line;
|
|
42
|
+
this.column = column;
|
|
43
|
+
this.timestamp = new Date().toISOString();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Validation framework class
|
|
49
|
+
*/
|
|
50
|
+
class ValidationFramework {
|
|
51
|
+
constructor(config = RefactoringConfig) {
|
|
52
|
+
this.config = config;
|
|
53
|
+
this.rules = new Map();
|
|
54
|
+
this.results = [];
|
|
55
|
+
this.setupDefaultRules();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Setup default validation rules
|
|
60
|
+
*/
|
|
61
|
+
setupDefaultRules() {
|
|
62
|
+
// File size validation
|
|
63
|
+
this.addRule(VALIDATION_TYPES.COMPLIANCE, {
|
|
64
|
+
name: 'file-size-limit',
|
|
65
|
+
severity: SEVERITY_LEVELS.ERROR,
|
|
66
|
+
validate: (filePath, content) => this.validateFileSize(filePath, content)
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Syntax validation
|
|
70
|
+
this.addRule(VALIDATION_TYPES.SYNTAX, {
|
|
71
|
+
name: 'javascript-syntax',
|
|
72
|
+
severity: SEVERITY_LEVELS.ERROR,
|
|
73
|
+
validate: (filePath, content) => this.validateJavaScriptSyntax(filePath, content)
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Import validation
|
|
77
|
+
this.addRule(VALIDATION_TYPES.SEMANTIC, {
|
|
78
|
+
name: 'import-statements',
|
|
79
|
+
severity: SEVERITY_LEVELS.WARNING,
|
|
80
|
+
validate: (filePath, content) => this.validateImports(filePath, content)
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Export validation
|
|
84
|
+
this.addRule(VALIDATION_TYPES.SEMANTIC, {
|
|
85
|
+
name: 'export-statements',
|
|
86
|
+
severity: SEVERITY_LEVELS.WARNING,
|
|
87
|
+
validate: (filePath, content) => this.validateExports(filePath, content)
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Function length validation
|
|
91
|
+
this.addRule(VALIDATION_TYPES.STRUCTURAL, {
|
|
92
|
+
name: 'function-length',
|
|
93
|
+
severity: SEVERITY_LEVELS.WARNING,
|
|
94
|
+
validate: (filePath, content) => this.validateFunctionLength(filePath, content)
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Class length validation
|
|
98
|
+
this.addRule(VALIDATION_TYPES.STRUCTURAL, {
|
|
99
|
+
name: 'class-length',
|
|
100
|
+
severity: SEVERITY_LEVELS.WARNING,
|
|
101
|
+
validate: (filePath, content) => this.validateClassLength(filePath, content)
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Nesting depth validation
|
|
105
|
+
this.addRule(VALIDATION_TYPES.STRUCTURAL, {
|
|
106
|
+
name: 'nesting-depth',
|
|
107
|
+
severity: SEVERITY_LEVELS.WARNING,
|
|
108
|
+
validate: (filePath, content) => this.validateNestingDepth(filePath, content)
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Circular dependency validation
|
|
112
|
+
this.addRule(VALIDATION_TYPES.SEMANTIC, {
|
|
113
|
+
name: 'circular-dependencies',
|
|
114
|
+
severity: SEVERITY_LEVELS.ERROR,
|
|
115
|
+
validate: (filePath, content) => this.validateCircularDependencies(filePath, content)
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Add a validation rule
|
|
121
|
+
*/
|
|
122
|
+
addRule(type, rule) {
|
|
123
|
+
if (!this.rules.has(type)) {
|
|
124
|
+
this.rules.set(type, []);
|
|
125
|
+
}
|
|
126
|
+
this.rules.get(type).push(rule);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Validate a single file
|
|
131
|
+
*/
|
|
132
|
+
validateFile(filePath, content = null) {
|
|
133
|
+
const results = [];
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// Read file content if not provided
|
|
137
|
+
if (!content) {
|
|
138
|
+
content = fs.readFileSync(filePath, 'utf8');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Skip excluded files
|
|
142
|
+
if (this.config.isExcluded(filePath)) {
|
|
143
|
+
return results;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Run all validation rules
|
|
147
|
+
for (const [type, rules] of this.rules) {
|
|
148
|
+
for (const rule of rules) {
|
|
149
|
+
try {
|
|
150
|
+
const ruleResults = rule.validate(filePath, content);
|
|
151
|
+
if (Array.isArray(ruleResults)) {
|
|
152
|
+
results.push(...ruleResults);
|
|
153
|
+
} else if (ruleResults) {
|
|
154
|
+
results.push(ruleResults);
|
|
155
|
+
}
|
|
156
|
+
} catch (error) {
|
|
157
|
+
results.push(new ValidationResult(
|
|
158
|
+
VALIDATION_TYPES.SYNTAX,
|
|
159
|
+
SEVERITY_LEVELS.ERROR,
|
|
160
|
+
`Validation rule '${rule.name}' failed: ${error.message}`,
|
|
161
|
+
filePath
|
|
162
|
+
));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
results.push(new ValidationResult(
|
|
168
|
+
VALIDATION_TYPES.SYNTAX,
|
|
169
|
+
SEVERITY_LEVELS.ERROR,
|
|
170
|
+
`File validation failed: ${error.message}`,
|
|
171
|
+
filePath
|
|
172
|
+
));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return results;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Validate multiple files
|
|
180
|
+
*/
|
|
181
|
+
validateFiles(filePaths) {
|
|
182
|
+
const allResults = [];
|
|
183
|
+
|
|
184
|
+
for (const filePath of filePaths) {
|
|
185
|
+
const results = this.validateFile(filePath);
|
|
186
|
+
allResults.push(...results);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
this.results = allResults;
|
|
190
|
+
return allResults;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Validate file size limit
|
|
195
|
+
*/
|
|
196
|
+
validateFileSize(filePath, content) {
|
|
197
|
+
const lines = content.split('\n');
|
|
198
|
+
const lineCount = lines.length;
|
|
199
|
+
const limits = this.config.getLimits(filePath);
|
|
200
|
+
|
|
201
|
+
if (lineCount > limits.maxFileSize) {
|
|
202
|
+
return new ValidationResult(
|
|
203
|
+
VALIDATION_TYPES.COMPLIANCE,
|
|
204
|
+
SEVERITY_LEVELS.ERROR,
|
|
205
|
+
`File exceeds maximum size limit: ${lineCount} lines (limit: ${limits.maxFileSize})`,
|
|
206
|
+
filePath
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (lineCount > limits.warningThreshold) {
|
|
211
|
+
return new ValidationResult(
|
|
212
|
+
VALIDATION_TYPES.COMPLIANCE,
|
|
213
|
+
SEVERITY_LEVELS.WARNING,
|
|
214
|
+
`File approaches size limit: ${lineCount} lines (warning: ${limits.warningThreshold})`,
|
|
215
|
+
filePath
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Validate JavaScript syntax
|
|
224
|
+
*/
|
|
225
|
+
validateJavaScriptSyntax(filePath, content) {
|
|
226
|
+
const ext = path.extname(filePath);
|
|
227
|
+
|
|
228
|
+
// Only validate JavaScript/TypeScript files
|
|
229
|
+
if (!['.js', '.jsx', '.ts', '.tsx'].includes(ext)) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
// Try to parse with Node.js
|
|
235
|
+
const vm = require('vm');
|
|
236
|
+
const script = new vm.Script(content, {
|
|
237
|
+
filename: path.basename(filePath)
|
|
238
|
+
});
|
|
239
|
+
return null;
|
|
240
|
+
} catch (error) {
|
|
241
|
+
const match = error.message.match(/at position (\d+)/);
|
|
242
|
+
const position = match ? parseInt(match[1]) : null;
|
|
243
|
+
|
|
244
|
+
return new ValidationResult(
|
|
245
|
+
VALIDATION_TYPES.SYNTAX,
|
|
246
|
+
SEVERITY_LEVELS.ERROR,
|
|
247
|
+
`JavaScript syntax error: ${error.message}`,
|
|
248
|
+
filePath,
|
|
249
|
+
null,
|
|
250
|
+
position
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Validate import statements
|
|
257
|
+
*/
|
|
258
|
+
validateImports(filePath, content) {
|
|
259
|
+
const results = [];
|
|
260
|
+
const lines = content.split('\n');
|
|
261
|
+
|
|
262
|
+
for (let i = 0; i < lines.length; i++) {
|
|
263
|
+
const line = lines[i].trim();
|
|
264
|
+
|
|
265
|
+
// Check for import statements
|
|
266
|
+
if (line.startsWith('import ')) {
|
|
267
|
+
// Check for missing semicolon
|
|
268
|
+
if (!line.endsWith(';')) {
|
|
269
|
+
results.push(new ValidationResult(
|
|
270
|
+
VALIDATION_TYPES.SEMANTIC,
|
|
271
|
+
SEVERITY_LEVELS.WARNING,
|
|
272
|
+
'Import statement missing semicolon',
|
|
273
|
+
filePath,
|
|
274
|
+
i + 1
|
|
275
|
+
));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Check for unused imports (basic check)
|
|
279
|
+
const importMatch = line.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
|
|
280
|
+
if (importMatch) {
|
|
281
|
+
const importPath = importMatch[1];
|
|
282
|
+
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
283
|
+
const resolvedPath = path.resolve(path.dirname(filePath), importPath);
|
|
284
|
+
if (!fs.existsSync(resolvedPath + '.js') && !fs.existsSync(resolvedPath + '.ts')) {
|
|
285
|
+
results.push(new ValidationResult(
|
|
286
|
+
VALIDATION_TYPES.SEMANTIC,
|
|
287
|
+
SEVERITY_LEVELS.ERROR,
|
|
288
|
+
`Import target not found: ${importPath}`,
|
|
289
|
+
filePath,
|
|
290
|
+
i + 1
|
|
291
|
+
));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return results;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Validate export statements
|
|
303
|
+
*/
|
|
304
|
+
validateExports(filePath, content) {
|
|
305
|
+
const results = [];
|
|
306
|
+
const lines = content.split('\n');
|
|
307
|
+
|
|
308
|
+
for (let i = 0; i < lines.length; i++) {
|
|
309
|
+
const line = lines[i].trim();
|
|
310
|
+
|
|
311
|
+
// Check for export statements
|
|
312
|
+
if (line.startsWith('export ')) {
|
|
313
|
+
// Check for missing semicolon
|
|
314
|
+
if (!line.endsWith(';') && !line.includes('function') && !line.includes('class')) {
|
|
315
|
+
results.push(new ValidationResult(
|
|
316
|
+
VALIDATION_TYPES.SEMANTIC,
|
|
317
|
+
SEVERITY_LEVELS.WARNING,
|
|
318
|
+
'Export statement missing semicolon',
|
|
319
|
+
filePath,
|
|
320
|
+
i + 1
|
|
321
|
+
));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return results;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Validate function length
|
|
331
|
+
*/
|
|
332
|
+
validateFunctionLength(filePath, content) {
|
|
333
|
+
const results = [];
|
|
334
|
+
const validationRules = this.config.validation;
|
|
335
|
+
const maxFunctionLength = validationRules?.maxFunctionLength || 50;
|
|
336
|
+
|
|
337
|
+
// Simple regex-based function detection
|
|
338
|
+
const functionPattern = /(?:function\s+\w+|=>\s*{|\w+\s*:\s*function|\w+\s*\([^)]*\)\s*{)/g;
|
|
339
|
+
const lines = content.split('\n');
|
|
340
|
+
|
|
341
|
+
let match;
|
|
342
|
+
while ((match = functionPattern.exec(content)) !== null) {
|
|
343
|
+
const startPos = match.index;
|
|
344
|
+
const lineNum = content.substring(0, startPos).split('\n').length;
|
|
345
|
+
|
|
346
|
+
// Find function end (simplified)
|
|
347
|
+
let braceCount = 0;
|
|
348
|
+
let functionEndPos = startPos;
|
|
349
|
+
let inFunction = false;
|
|
350
|
+
|
|
351
|
+
for (let i = startPos; i < content.length; i++) {
|
|
352
|
+
if (content[i] === '{') {
|
|
353
|
+
braceCount++;
|
|
354
|
+
inFunction = true;
|
|
355
|
+
} else if (content[i] === '}') {
|
|
356
|
+
braceCount--;
|
|
357
|
+
if (inFunction && braceCount === 0) {
|
|
358
|
+
functionEndPos = i;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const functionContent = content.substring(startPos, functionEndPos);
|
|
365
|
+
const functionLines = functionContent.split('\n').length;
|
|
366
|
+
|
|
367
|
+
if (functionLines > maxFunctionLength) {
|
|
368
|
+
results.push(new ValidationResult(
|
|
369
|
+
VALIDATION_TYPES.STRUCTURAL,
|
|
370
|
+
SEVERITY_LEVELS.WARNING,
|
|
371
|
+
`Function exceeds maximum length: ${functionLines} lines (limit: ${maxFunctionLength})`,
|
|
372
|
+
filePath,
|
|
373
|
+
lineNum
|
|
374
|
+
));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return results;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Validate class length
|
|
383
|
+
*/
|
|
384
|
+
validateClassLength(filePath, content) {
|
|
385
|
+
const results = [];
|
|
386
|
+
const validationRules = this.config.validation;
|
|
387
|
+
const maxClassLength = validationRules?.maxClassLength || 200;
|
|
388
|
+
|
|
389
|
+
// Simple regex-based class detection
|
|
390
|
+
const classPattern = /class\s+\w+/g;
|
|
391
|
+
|
|
392
|
+
let match;
|
|
393
|
+
while ((match = classPattern.exec(content)) !== null) {
|
|
394
|
+
const startPos = match.index;
|
|
395
|
+
const lineNum = content.substring(0, startPos).split('\n').length;
|
|
396
|
+
|
|
397
|
+
// Find class end (simplified)
|
|
398
|
+
let braceCount = 0;
|
|
399
|
+
let classEndPos = startPos;
|
|
400
|
+
let inClass = false;
|
|
401
|
+
|
|
402
|
+
for (let i = startPos; i < content.length; i++) {
|
|
403
|
+
if (content[i] === '{') {
|
|
404
|
+
braceCount++;
|
|
405
|
+
inClass = true;
|
|
406
|
+
} else if (content[i] === '}') {
|
|
407
|
+
braceCount--;
|
|
408
|
+
if (inClass && braceCount === 0) {
|
|
409
|
+
classEndPos = i;
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const classContent = content.substring(startPos, classEndPos);
|
|
416
|
+
const classLines = classContent.split('\n').length;
|
|
417
|
+
|
|
418
|
+
if (classLines > maxClassLength) {
|
|
419
|
+
results.push(new ValidationResult(
|
|
420
|
+
VALIDATION_TYPES.STRUCTURAL,
|
|
421
|
+
SEVERITY_LEVELS.WARNING,
|
|
422
|
+
`Class exceeds maximum length: ${classLines} lines (limit: ${maxClassLength})`,
|
|
423
|
+
filePath,
|
|
424
|
+
lineNum
|
|
425
|
+
));
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return results;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Validate nesting depth
|
|
434
|
+
*/
|
|
435
|
+
validateNestingDepth(filePath, content) {
|
|
436
|
+
const results = [];
|
|
437
|
+
const validationRules = this.config.validation;
|
|
438
|
+
const maxNestingDepth = validationRules?.maxNestingDepth || 5;
|
|
439
|
+
|
|
440
|
+
const lines = content.split('\n');
|
|
441
|
+
|
|
442
|
+
for (let i = 0; i < lines.length; i++) {
|
|
443
|
+
const line = lines[i];
|
|
444
|
+
const indentation = line.match(/^\s*/)[0].length;
|
|
445
|
+
const nestingDepth = Math.floor(indentation / 2); // Assume 2 spaces per level
|
|
446
|
+
|
|
447
|
+
if (nestingDepth > maxNestingDepth) {
|
|
448
|
+
results.push(new ValidationResult(
|
|
449
|
+
VALIDATION_TYPES.STRUCTURAL,
|
|
450
|
+
SEVERITY_LEVELS.WARNING,
|
|
451
|
+
`Nesting depth exceeds maximum: ${nestingDepth} levels (limit: ${maxNestingDepth})`,
|
|
452
|
+
filePath,
|
|
453
|
+
i + 1
|
|
454
|
+
));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return results;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Validate circular dependencies (simplified)
|
|
463
|
+
*/
|
|
464
|
+
validateCircularDependencies(filePath, content) {
|
|
465
|
+
// This is a simplified implementation
|
|
466
|
+
// A full implementation would build a dependency graph
|
|
467
|
+
return [];
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Get validation summary
|
|
472
|
+
*/
|
|
473
|
+
getSummary() {
|
|
474
|
+
const summary = {
|
|
475
|
+
total: this.results.length,
|
|
476
|
+
errors: 0,
|
|
477
|
+
warnings: 0,
|
|
478
|
+
info: 0,
|
|
479
|
+
byType: {},
|
|
480
|
+
byFile: {}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
for (const result of this.results) {
|
|
484
|
+
// Count by severity
|
|
485
|
+
if (result.severity === SEVERITY_LEVELS.ERROR) summary.errors++;
|
|
486
|
+
else if (result.severity === SEVERITY_LEVELS.WARNING) summary.warnings++;
|
|
487
|
+
else if (result.severity === SEVERITY_LEVELS.INFO) summary.info++;
|
|
488
|
+
|
|
489
|
+
// Count by type
|
|
490
|
+
if (!summary.byType[result.type]) {
|
|
491
|
+
summary.byType[result.type] = 0;
|
|
492
|
+
}
|
|
493
|
+
summary.byType[result.type]++;
|
|
494
|
+
|
|
495
|
+
// Count by file
|
|
496
|
+
if (!summary.byFile[result.filePath]) {
|
|
497
|
+
summary.byFile[result.filePath] = 0;
|
|
498
|
+
}
|
|
499
|
+
summary.byFile[result.filePath]++;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return summary;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Check if validation passed (no errors)
|
|
507
|
+
*/
|
|
508
|
+
isValid() {
|
|
509
|
+
return this.results.every(result => result.severity !== SEVERITY_LEVELS.ERROR);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
module.exports = {
|
|
514
|
+
ValidationFramework,
|
|
515
|
+
ValidationResult,
|
|
516
|
+
VALIDATION_TYPES,
|
|
517
|
+
SEVERITY_LEVELS
|
|
518
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes validation results and provides compliance metrics.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { VALIDATION_SEVERITY } = require('./line-limit-result');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Compliance analyzer class
|
|
11
|
+
*/
|
|
12
|
+
class ComplianceAnalyzer {
|
|
13
|
+
constructor(defaultLimit = 555) {
|
|
14
|
+
this.defaultLimit = defaultLimit;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get compliance summary for validation results
|
|
19
|
+
*/
|
|
20
|
+
getComplianceSummary(results) {
|
|
21
|
+
const summary = {
|
|
22
|
+
totalFiles: results.length,
|
|
23
|
+
compliant: 0,
|
|
24
|
+
warnings: 0,
|
|
25
|
+
violations: 0,
|
|
26
|
+
critical: 0,
|
|
27
|
+
totalLines: 0,
|
|
28
|
+
averageLines: 0,
|
|
29
|
+
largestFile: null,
|
|
30
|
+
smallestFile: null,
|
|
31
|
+
complianceRate: 0,
|
|
32
|
+
byStatus: {
|
|
33
|
+
compliant: 0,
|
|
34
|
+
warning: 0,
|
|
35
|
+
violation: 0,
|
|
36
|
+
critical: 0
|
|
37
|
+
},
|
|
38
|
+
violations: [],
|
|
39
|
+
recommendations: []
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
let totalLines = 0;
|
|
43
|
+
|
|
44
|
+
for (const result of results) {
|
|
45
|
+
summary.totalLines += result.lineCount;
|
|
46
|
+
|
|
47
|
+
if (result.isCompliant()) {
|
|
48
|
+
summary.compliant++;
|
|
49
|
+
} else if (result.violation) {
|
|
50
|
+
if (result.violation.severity === VALIDATION_SEVERITY.CRITICAL) {
|
|
51
|
+
summary.critical++;
|
|
52
|
+
} else if (result.violation.severity === VALIDATION_SEVERITY.ERROR) {
|
|
53
|
+
summary.violations++;
|
|
54
|
+
} else if (result.violation.severity === VALIDATION_SEVERITY.WARNING) {
|
|
55
|
+
summary.warnings++;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
summary.violations.push(result.violation);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Update status counts
|
|
62
|
+
const status = result.getComplianceStatus();
|
|
63
|
+
summary.byStatus[status]++;
|
|
64
|
+
|
|
65
|
+
// Track largest and smallest files
|
|
66
|
+
if (!summary.largestFile || result.lineCount > summary.largestFile.lineCount) {
|
|
67
|
+
summary.largestFile = result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!summary.smallestFile || result.lineCount < summary.smallestFile.lineCount) {
|
|
71
|
+
summary.smallestFile = result;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Calculate averages and rates
|
|
76
|
+
summary.averageLines = summary.totalFiles > 0 ?
|
|
77
|
+
Math.round(summary.totalLines / summary.totalFiles) : 0;
|
|
78
|
+
|
|
79
|
+
summary.complianceRate = summary.totalFiles > 0 ?
|
|
80
|
+
((summary.compliant / summary.totalFiles) * 100).toFixed(1) : 0;
|
|
81
|
+
|
|
82
|
+
// Generate recommendations
|
|
83
|
+
summary.recommendations = this.generateRecommendations(summary);
|
|
84
|
+
|
|
85
|
+
return summary;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Generate recommendations based on validation results
|
|
90
|
+
*/
|
|
91
|
+
generateRecommendations(summary) {
|
|
92
|
+
const recommendations = [];
|
|
93
|
+
|
|
94
|
+
if (summary.critical > 0) {
|
|
95
|
+
recommendations.push({
|
|
96
|
+
type: 'critical',
|
|
97
|
+
priority: 'high',
|
|
98
|
+
title: `Address ${summary.critical} Critical Violations`,
|
|
99
|
+
description: `${summary.critical} files severely exceed the 555-line limit and require immediate refactoring.`,
|
|
100
|
+
action: 'Refactor critical files immediately'
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (summary.violations > 0) {
|
|
105
|
+
recommendations.push({
|
|
106
|
+
type: 'violation',
|
|
107
|
+
priority: 'high',
|
|
108
|
+
title: `Fix ${summary.violations} Line Limit Violations`,
|
|
109
|
+
description: `${summary.violations} files exceed the 555-line limit and must be refactored.`,
|
|
110
|
+
action: 'Refactor files to comply with limit'
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (summary.warnings > 0) {
|
|
115
|
+
recommendations.push({
|
|
116
|
+
type: 'warning',
|
|
117
|
+
priority: 'medium',
|
|
118
|
+
title: `Monitor ${summary.warnings} Files Approaching Limit`,
|
|
119
|
+
description: `${summary.warnings} files are approaching the 555-line limit and should be monitored.`,
|
|
120
|
+
action: 'Plan refactoring for warning files'
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (summary.largestFile && summary.largestFile.lineCount > 1000) {
|
|
125
|
+
recommendations.push({
|
|
126
|
+
type: 'large_file',
|
|
127
|
+
priority: 'medium',
|
|
128
|
+
title: 'Consider Splitting Very Large File',
|
|
129
|
+
description: `Largest file has ${summary.largestFile.lineCount} lines and may benefit from splitting.`,
|
|
130
|
+
action: 'Consider splitting into smaller modules'
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (summary.complianceRate < 80) {
|
|
135
|
+
recommendations.push({
|
|
136
|
+
type: 'compliance',
|
|
137
|
+
priority: 'high',
|
|
138
|
+
title: 'Improve Overall Compliance',
|
|
139
|
+
description: `Overall compliance rate is ${summary.complianceRate}%. Target is 100%.`,
|
|
140
|
+
action: 'Address all violations to improve compliance'
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return recommendations;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Filter results by compliance status
|
|
149
|
+
*/
|
|
150
|
+
filterByStatus(results, status) {
|
|
151
|
+
return results.filter(result => result.getComplianceStatus() === status);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Filter results by severity
|
|
156
|
+
*/
|
|
157
|
+
filterBySeverity(results, severity) {
|
|
158
|
+
return results.filter(result =>
|
|
159
|
+
result.violation && result.violation.severity === severity
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Sort results by line count
|
|
165
|
+
*/
|
|
166
|
+
sortByLineCount(results, descending = true) {
|
|
167
|
+
return [...results].sort((a, b) => {
|
|
168
|
+
return descending ? b.lineCount - a.lineCount : a.lineCount - b.lineCount;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get files exceeding limit
|
|
174
|
+
*/
|
|
175
|
+
getViolatingFiles(results, limit = null) {
|
|
176
|
+
return results.filter(result => {
|
|
177
|
+
const fileLimit = limit || this.defaultLimit;
|
|
178
|
+
return result.lineCount > fileLimit;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get files approaching limit
|
|
184
|
+
*/
|
|
185
|
+
getApproachingLimitFiles(results, limit = null, threshold = 0.9) {
|
|
186
|
+
const fileLimit = limit || this.defaultLimit;
|
|
187
|
+
const warningThreshold = Math.floor(fileLimit * threshold);
|
|
188
|
+
|
|
189
|
+
return results.filter(result =>
|
|
190
|
+
result.lineCount > warningThreshold && result.lineCount <= fileLimit
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
module.exports = {
|
|
196
|
+
ComplianceAnalyzer
|
|
197
|
+
};
|