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,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constitutional Compliance Rules
|
|
3
|
+
*
|
|
4
|
+
* Defines the compliance rules and categories for constitutional validation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compliance issue categories
|
|
9
|
+
*/
|
|
10
|
+
const COMPLIANCE_CATEGORIES = {
|
|
11
|
+
FILE_SIZE: 'file_size',
|
|
12
|
+
CODE_STRUCTURE: 'code_structure',
|
|
13
|
+
TESTING: 'testing',
|
|
14
|
+
DOCUMENTATION: 'documentation',
|
|
15
|
+
IMPORTS: 'imports',
|
|
16
|
+
NAMING: 'naming',
|
|
17
|
+
ARCHITECTURE: 'architecture'
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Compliance severity levels
|
|
22
|
+
*/
|
|
23
|
+
const COMPLIANCE_SEVERITY = {
|
|
24
|
+
ERROR: 'error',
|
|
25
|
+
WARNING: 'warning',
|
|
26
|
+
INFO: 'info'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Default compliance rules configuration
|
|
31
|
+
*/
|
|
32
|
+
const DEFAULT_RULES = {
|
|
33
|
+
// File size rules
|
|
34
|
+
maxFileSize: {
|
|
35
|
+
enabled: true,
|
|
36
|
+
limit: 555,
|
|
37
|
+
category: COMPLIANCE_CATEGORIES.FILE_SIZE,
|
|
38
|
+
severity: COMPLIANCE_SEVERITY.ERROR
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Code structure rules
|
|
42
|
+
noTrailingWhitespace: {
|
|
43
|
+
enabled: true,
|
|
44
|
+
category: COMPLIANCE_CATEGORIES.CODE_STRUCTURE,
|
|
45
|
+
severity: COMPLIANCE_SEVERITY.ERROR
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
fileEndsWithNewline: {
|
|
49
|
+
enabled: true,
|
|
50
|
+
category: COMPLIANCE_CATEGORIES.CODE_STRUCTURE,
|
|
51
|
+
severity: COMPLIANCE_SEVERITY.INFO
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
maxLineLength: {
|
|
55
|
+
enabled: true,
|
|
56
|
+
limit: 200,
|
|
57
|
+
category: COMPLIANCE_CATEGORIES.CODE_STRUCTURE,
|
|
58
|
+
severity: COMPLIANCE_SEVERITY.WARNING
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Testing rules
|
|
62
|
+
testFirstDevelopment: {
|
|
63
|
+
enabled: true,
|
|
64
|
+
category: COMPLIANCE_CATEGORIES.TESTING,
|
|
65
|
+
severity: COMPLIANCE_SEVERITY.WARNING
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// Documentation rules
|
|
69
|
+
functionDocumentation: {
|
|
70
|
+
enabled: true,
|
|
71
|
+
category: COMPLIANCE_CATEGORIES.DOCUMENTATION,
|
|
72
|
+
severity: COMPLIANCE_SEVERITY.INFO
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
// Import rules
|
|
76
|
+
noCircularDependencies: {
|
|
77
|
+
enabled: true,
|
|
78
|
+
category: COMPLIANCE_CATEGORIES.IMPORTS,
|
|
79
|
+
severity: COMPLIANCE_SEVERITY.ERROR
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
// Naming rules
|
|
83
|
+
consistentNaming: {
|
|
84
|
+
enabled: true,
|
|
85
|
+
category: COMPLIANCE_CATEGORIES.NAMING,
|
|
86
|
+
severity: COMPLIANCE_SEVERITY.WARNING
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get rules for specific file type
|
|
92
|
+
*/
|
|
93
|
+
function getRulesForFileType(fileType) {
|
|
94
|
+
const rules = { ...DEFAULT_RULES };
|
|
95
|
+
|
|
96
|
+
// Adjust rules based on file type
|
|
97
|
+
switch (fileType) {
|
|
98
|
+
case 'javascript':
|
|
99
|
+
case 'typescript':
|
|
100
|
+
// Add JS/TS specific rules
|
|
101
|
+
rules.noConsoleStatements = {
|
|
102
|
+
enabled: false, // Often needed for debugging
|
|
103
|
+
category: COMPLIANCE_CATEGORIES.CODE_STRUCTURE,
|
|
104
|
+
severity: COMPLIANCE_SEVERITY.WARNING
|
|
105
|
+
};
|
|
106
|
+
break;
|
|
107
|
+
|
|
108
|
+
case 'markdown':
|
|
109
|
+
// Markdown-specific rules
|
|
110
|
+
delete rules.maxLineLength; // Markdown can have long lines
|
|
111
|
+
break;
|
|
112
|
+
|
|
113
|
+
case 'json':
|
|
114
|
+
// JSON-specific rules
|
|
115
|
+
delete rules.functionDocumentation;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return rules;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = {
|
|
123
|
+
COMPLIANCE_CATEGORIES,
|
|
124
|
+
COMPLIANCE_SEVERITY,
|
|
125
|
+
DEFAULT_RULES,
|
|
126
|
+
getRulesForFileType
|
|
127
|
+
};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constitutional Compliance Checker
|
|
3
|
+
*
|
|
4
|
+
* Validates that code and files comply with project constitution requirements.
|
|
5
|
+
* Ensures adherence to established development principles and standards.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { getRulesForFileType } = require('./compliance-rules');
|
|
11
|
+
const {
|
|
12
|
+
validateFileSize,
|
|
13
|
+
validateTrailingWhitespace,
|
|
14
|
+
validateFileEndsWithNewline,
|
|
15
|
+
validateMaxLineLength,
|
|
16
|
+
validateFunctionDocumentation,
|
|
17
|
+
getFileType
|
|
18
|
+
} = require('./file-validators');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Constitutional Compliance Validator
|
|
22
|
+
*/
|
|
23
|
+
class ConstitutionValidator {
|
|
24
|
+
constructor(options = {}) {
|
|
25
|
+
this.options = {
|
|
26
|
+
excludePatterns: options.excludePatterns || [/node_modules/, /\.git/, /dist/, /build/],
|
|
27
|
+
includePatterns: options.includePatterns || [],
|
|
28
|
+
maxFileSize: options.maxFileSize || 555,
|
|
29
|
+
...options
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Validate file for constitutional compliance
|
|
35
|
+
*/
|
|
36
|
+
validateFile(filePath, options = {}) {
|
|
37
|
+
const results = [];
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
if (!fs.existsSync(filePath)) {
|
|
41
|
+
return [{
|
|
42
|
+
rule: 'fileExists',
|
|
43
|
+
category: 'file_system',
|
|
44
|
+
severity: 'error',
|
|
45
|
+
message: 'File does not exist',
|
|
46
|
+
line: 0,
|
|
47
|
+
column: 0
|
|
48
|
+
}];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
52
|
+
const fileType = getFileType(filePath);
|
|
53
|
+
const rules = getRulesForFileType(fileType);
|
|
54
|
+
|
|
55
|
+
// Apply all validations
|
|
56
|
+
results.push(...validateFileSize(filePath, content, rules));
|
|
57
|
+
results.push(...validateTrailingWhitespace(filePath, content, rules));
|
|
58
|
+
results.push(...validateFileEndsWithNewline(filePath, content, rules));
|
|
59
|
+
results.push(...validateMaxLineLength(filePath, content, rules));
|
|
60
|
+
results.push(...validateFunctionDocumentation(filePath, content, rules));
|
|
61
|
+
|
|
62
|
+
return results;
|
|
63
|
+
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return [{
|
|
66
|
+
rule: 'validationError',
|
|
67
|
+
category: 'system',
|
|
68
|
+
severity: 'error',
|
|
69
|
+
message: `Validation failed: ${error.message}`,
|
|
70
|
+
line: 0,
|
|
71
|
+
column: 0
|
|
72
|
+
}];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate directory recursively
|
|
78
|
+
*/
|
|
79
|
+
validateDirectory(dirPath, options = {}) {
|
|
80
|
+
const results = new Map();
|
|
81
|
+
|
|
82
|
+
if (!fs.existsSync(dirPath)) {
|
|
83
|
+
return new Map([[dirPath, [{
|
|
84
|
+
rule: 'directoryExists',
|
|
85
|
+
category: 'file_system',
|
|
86
|
+
severity: 'error',
|
|
87
|
+
message: 'Directory does not exist',
|
|
88
|
+
line: 0,
|
|
89
|
+
column: 0
|
|
90
|
+
}]]]);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this._scanDirectory(dirPath, results, options);
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get compliance summary
|
|
99
|
+
*/
|
|
100
|
+
getComplianceSummary(validationResults) {
|
|
101
|
+
const summary = {
|
|
102
|
+
totalFiles: 0,
|
|
103
|
+
compliantFiles: 0,
|
|
104
|
+
nonCompliantFiles: 0,
|
|
105
|
+
totalIssues: 0,
|
|
106
|
+
issuesBySeverity: {
|
|
107
|
+
error: 0,
|
|
108
|
+
warning: 0,
|
|
109
|
+
info: 0
|
|
110
|
+
},
|
|
111
|
+
issuesByCategory: {}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
for (const [filePath, issues] of validationResults) {
|
|
115
|
+
summary.totalFiles++;
|
|
116
|
+
|
|
117
|
+
if (issues.length === 0) {
|
|
118
|
+
summary.compliantFiles++;
|
|
119
|
+
} else {
|
|
120
|
+
summary.nonCompliantFiles++;
|
|
121
|
+
summary.totalIssues += issues.length;
|
|
122
|
+
|
|
123
|
+
issues.forEach(issue => {
|
|
124
|
+
summary.issuesBySeverity[issue.severity] =
|
|
125
|
+
(summary.issuesBySeverity[issue.severity] || 0) + 1;
|
|
126
|
+
|
|
127
|
+
summary.issuesByCategory[issue.category] =
|
|
128
|
+
(summary.issuesByCategory[issue.category] || 0) + 1;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return summary;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Private: Scan directory recursively
|
|
138
|
+
*/
|
|
139
|
+
_scanDirectory(dirPath, results, options) {
|
|
140
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
141
|
+
|
|
142
|
+
for (const entry of entries) {
|
|
143
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
144
|
+
|
|
145
|
+
if (entry.isDirectory()) {
|
|
146
|
+
// Skip excluded directories
|
|
147
|
+
if (this._shouldExclude(fullPath)) continue;
|
|
148
|
+
|
|
149
|
+
this._scanDirectory(fullPath, results, options);
|
|
150
|
+
} else if (entry.isFile()) {
|
|
151
|
+
// Skip excluded files
|
|
152
|
+
if (this._shouldExclude(fullPath)) continue;
|
|
153
|
+
|
|
154
|
+
const issues = this.validateFile(fullPath, options);
|
|
155
|
+
results.set(fullPath, issues);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Private: Check if path should be excluded
|
|
162
|
+
*/
|
|
163
|
+
_shouldExclude(filePath) {
|
|
164
|
+
const relativePath = path.relative(process.cwd(), filePath);
|
|
165
|
+
|
|
166
|
+
// Check exclude patterns
|
|
167
|
+
for (const pattern of this.options.excludePatterns) {
|
|
168
|
+
if (pattern.test(filePath) || pattern.test(relativePath)) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Check include patterns (if specified)
|
|
174
|
+
if (this.options.includePatterns.length > 0) {
|
|
175
|
+
for (const pattern of this.options.includePatterns) {
|
|
176
|
+
if (pattern.test(filePath) || pattern.test(relativePath)) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Export singleton instance
|
|
188
|
+
const validator = new ConstitutionValidator();
|
|
189
|
+
|
|
190
|
+
module.exports = {
|
|
191
|
+
ConstitutionValidator,
|
|
192
|
+
validator,
|
|
193
|
+
validateFile: (filePath, options) => validator.validateFile(filePath, options),
|
|
194
|
+
validateDirectory: (dirPath, options) => validator.validateDirectory(dirPath, options),
|
|
195
|
+
getComplianceSummary: (results) => validator.getComplianceSummary(results)
|
|
196
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constitutional Compliance Checker
|
|
3
|
+
*
|
|
4
|
+
* Validates that code and files comply with project constitution requirements.
|
|
5
|
+
* Ensures adherence to established development principles and standards.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { ConstitutionValidator, validator, validateFile, validateDirectory, getComplianceSummary } = require('./constitution-validator-new');
|
|
9
|
+
|
|
10
|
+
// Re-export for backward compatibility
|
|
11
|
+
module.exports = {
|
|
12
|
+
ConstitutionValidator,
|
|
13
|
+
validator,
|
|
14
|
+
validateFile,
|
|
15
|
+
validateDirectory,
|
|
16
|
+
getComplianceSummary
|
|
17
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Validators
|
|
3
|
+
*
|
|
4
|
+
* Individual validation functions for different compliance rules.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { COMPLIANCE_CATEGORIES, COMPLIANCE_SEVERITY } = require('./compliance-rules');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validate file size
|
|
13
|
+
*/
|
|
14
|
+
function validateFileSize(filePath, content, rules) {
|
|
15
|
+
const issues = [];
|
|
16
|
+
const rule = rules.maxFileSize;
|
|
17
|
+
|
|
18
|
+
if (rule && rule.enabled) {
|
|
19
|
+
const lineCount = content.split('\n').length;
|
|
20
|
+
if (lineCount > rule.limit) {
|
|
21
|
+
issues.push({
|
|
22
|
+
rule: 'maxFileSize',
|
|
23
|
+
category: rule.category,
|
|
24
|
+
severity: rule.severity,
|
|
25
|
+
message: `File has ${lineCount} lines, exceeds limit of ${rule.limit}`,
|
|
26
|
+
line: lineCount,
|
|
27
|
+
column: 0
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return issues;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Validate trailing whitespace
|
|
37
|
+
*/
|
|
38
|
+
function validateTrailingWhitespace(filePath, content, rules) {
|
|
39
|
+
const issues = [];
|
|
40
|
+
const rule = rules.noTrailingWhitespace;
|
|
41
|
+
|
|
42
|
+
if (rule && rule.enabled) {
|
|
43
|
+
const lines = content.split('\n');
|
|
44
|
+
lines.forEach((line, index) => {
|
|
45
|
+
if (line.endsWith(' ') || line.endsWith('\t')) {
|
|
46
|
+
issues.push({
|
|
47
|
+
rule: 'noTrailingWhitespace',
|
|
48
|
+
category: rule.category,
|
|
49
|
+
severity: rule.severity,
|
|
50
|
+
message: 'Line has trailing whitespace',
|
|
51
|
+
line: index + 1,
|
|
52
|
+
column: line.length + 1
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return issues;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validate file ends with newline
|
|
63
|
+
*/
|
|
64
|
+
function validateFileEndsWithNewline(filePath, content, rules) {
|
|
65
|
+
const issues = [];
|
|
66
|
+
const rule = rules.fileEndsWithNewline;
|
|
67
|
+
|
|
68
|
+
if (rule && rule.enabled) {
|
|
69
|
+
if (!content.endsWith('\n')) {
|
|
70
|
+
issues.push({
|
|
71
|
+
rule: 'fileEndsWithNewline',
|
|
72
|
+
category: rule.category,
|
|
73
|
+
severity: rule.severity,
|
|
74
|
+
message: 'File does not end with newline',
|
|
75
|
+
line: content.split('\n').length,
|
|
76
|
+
column: 0
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return issues;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Validate maximum line length
|
|
86
|
+
*/
|
|
87
|
+
function validateMaxLineLength(filePath, content, rules) {
|
|
88
|
+
const issues = [];
|
|
89
|
+
const rule = rules.maxLineLength;
|
|
90
|
+
|
|
91
|
+
if (rule && rule.enabled) {
|
|
92
|
+
const lines = content.split('\n');
|
|
93
|
+
lines.forEach((line, index) => {
|
|
94
|
+
if (line.length > rule.limit) {
|
|
95
|
+
issues.push({
|
|
96
|
+
rule: 'maxLineLength',
|
|
97
|
+
category: rule.category,
|
|
98
|
+
severity: rule.severity,
|
|
99
|
+
message: `Line length ${line.length} exceeds limit of ${rule.limit}`,
|
|
100
|
+
line: index + 1,
|
|
101
|
+
column: rule.limit + 1
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return issues;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Validate function documentation
|
|
112
|
+
*/
|
|
113
|
+
function validateFunctionDocumentation(filePath, content, rules) {
|
|
114
|
+
const issues = [];
|
|
115
|
+
const rule = rules.functionDocumentation;
|
|
116
|
+
|
|
117
|
+
if (rule && rule.enabled) {
|
|
118
|
+
// Simple heuristic: check for function declarations without preceding comments
|
|
119
|
+
const lines = content.split('\n');
|
|
120
|
+
lines.forEach((line, index) => {
|
|
121
|
+
const functionMatch = line.match(/^\s*(function|const\s+\w+\s*=\s*(function|\([^)]*\)\s*=>))/);
|
|
122
|
+
if (functionMatch) {
|
|
123
|
+
// Check preceding lines for documentation
|
|
124
|
+
const prevLine = index > 0 ? lines[index - 1].trim() : '';
|
|
125
|
+
const hasDoc = prevLine.startsWith('//') || prevLine.startsWith('/*') || prevLine.startsWith('*');
|
|
126
|
+
|
|
127
|
+
if (!hasDoc) {
|
|
128
|
+
issues.push({
|
|
129
|
+
rule: 'functionDocumentation',
|
|
130
|
+
category: rule.category,
|
|
131
|
+
severity: rule.severity,
|
|
132
|
+
message: 'Function appears to lack documentation',
|
|
133
|
+
line: index + 1,
|
|
134
|
+
column: functionMatch.index + 1
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return issues;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get file type from path
|
|
146
|
+
*/
|
|
147
|
+
function getFileType(filePath) {
|
|
148
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
149
|
+
const typeMap = {
|
|
150
|
+
'.js': 'javascript',
|
|
151
|
+
'.jsx': 'javascript',
|
|
152
|
+
'.ts': 'typescript',
|
|
153
|
+
'.tsx': 'typescript',
|
|
154
|
+
'.md': 'markdown',
|
|
155
|
+
'.json': 'json',
|
|
156
|
+
'.yml': 'yaml',
|
|
157
|
+
'.yaml': 'yaml'
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return typeMap[ext] || 'text';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = {
|
|
164
|
+
validateFileSize,
|
|
165
|
+
validateTrailingWhitespace,
|
|
166
|
+
validateFileEndsWithNewline,
|
|
167
|
+
validateMaxLineLength,
|
|
168
|
+
validateFunctionDocumentation,
|
|
169
|
+
getFileType
|
|
170
|
+
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Line Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes files to count lines and detect potential issues.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* File line analyzer class
|
|
12
|
+
*/
|
|
13
|
+
class FileLineAnalyzer {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.defaultLimit = 555;
|
|
16
|
+
this.excludedExtensions = new Set([
|
|
17
|
+
'.json', '.lock', '.log', '.tmp', '.cache', '.map', '.min.js', '.min.css'
|
|
18
|
+
]);
|
|
19
|
+
this.excludedDirectories = new Set([
|
|
20
|
+
'node_modules', '.git', 'dist', 'build', 'coverage', '.nyc_output'
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Check if a file should be analyzed based on its path and extension
|
|
26
|
+
*/
|
|
27
|
+
shouldAnalyze(filePath) {
|
|
28
|
+
const ext = path.extname(filePath);
|
|
29
|
+
const dirName = path.basename(path.dirname(filePath));
|
|
30
|
+
|
|
31
|
+
// Skip excluded extensions
|
|
32
|
+
if (this.excludedExtensions.has(ext)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Skip excluded directories
|
|
37
|
+
for (const excludedDir of this.excludedDirectories) {
|
|
38
|
+
if (filePath.includes(`/${excludedDir}/`) || filePath.includes(`\\${excludedDir}\\`)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Only analyze source code files
|
|
44
|
+
const sourceExtensions = new Set([
|
|
45
|
+
'.js', '.jsx', '.ts', '.tsx', '.vue', '.py', '.java', '.cpp', '.c', '.h',
|
|
46
|
+
'.cs', '.php', '.rb', '.go', '.rs', '.swift', '.kt', '.scala', '.sh',
|
|
47
|
+
'.html', '.css', '.scss', '.sass', '.less', '.md', '.yml', '.yaml'
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
return sourceExtensions.has(ext);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Count lines in a file
|
|
55
|
+
*/
|
|
56
|
+
countLines(filePath) {
|
|
57
|
+
try {
|
|
58
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
59
|
+
return this.countLinesInContent(content);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Count lines in content string
|
|
67
|
+
*/
|
|
68
|
+
countLinesInContent(content) {
|
|
69
|
+
if (!content) return 0;
|
|
70
|
+
|
|
71
|
+
// Split by lines and filter out empty lines (but keep them for counting)
|
|
72
|
+
const lines = content.split('\n');
|
|
73
|
+
|
|
74
|
+
// Remove trailing empty line if it exists (POSIX standard requires files to end with newline)
|
|
75
|
+
if (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
76
|
+
return lines.length - 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return lines.length;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Analyze a file and return detailed line information
|
|
84
|
+
*/
|
|
85
|
+
analyzeFile(filePath, limit = this.defaultLimit) {
|
|
86
|
+
if (!this.shouldAnalyze(filePath)) {
|
|
87
|
+
return {
|
|
88
|
+
filePath,
|
|
89
|
+
lineCount: 0,
|
|
90
|
+
limit,
|
|
91
|
+
shouldAnalyze: false,
|
|
92
|
+
reason: 'File type excluded from analysis'
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const lineCount = this.countLines(filePath);
|
|
98
|
+
const exceedsLimit = lineCount > limit;
|
|
99
|
+
const percentage = Math.round((lineCount / limit) * 100);
|
|
100
|
+
|
|
101
|
+
// Determine severity based on how much the limit is exceeded
|
|
102
|
+
let severity = 'info';
|
|
103
|
+
if (exceedsLimit) {
|
|
104
|
+
const excessPercentage = percentage - 100;
|
|
105
|
+
if (excessPercentage > 50) {
|
|
106
|
+
severity = 'critical';
|
|
107
|
+
} else if (excessPercentage > 25) {
|
|
108
|
+
severity = 'error';
|
|
109
|
+
} else if (excessPercentage > 10) {
|
|
110
|
+
severity = 'warning';
|
|
111
|
+
}
|
|
112
|
+
} else if (percentage > 80) {
|
|
113
|
+
severity = 'warning';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
filePath,
|
|
118
|
+
lineCount,
|
|
119
|
+
limit,
|
|
120
|
+
exceedsLimit,
|
|
121
|
+
percentage,
|
|
122
|
+
severity,
|
|
123
|
+
shouldAnalyze: true,
|
|
124
|
+
warnings: this.generateWarnings(lineCount, limit)
|
|
125
|
+
};
|
|
126
|
+
} catch (error) {
|
|
127
|
+
return {
|
|
128
|
+
filePath,
|
|
129
|
+
lineCount: 0,
|
|
130
|
+
limit,
|
|
131
|
+
shouldAnalyze: false,
|
|
132
|
+
error: error.message
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Generate warnings for a file based on line count
|
|
139
|
+
*/
|
|
140
|
+
generateWarnings(lineCount, limit) {
|
|
141
|
+
const warnings = [];
|
|
142
|
+
const percentage = Math.round((lineCount / limit) * 100);
|
|
143
|
+
|
|
144
|
+
if (percentage > 80 && percentage <= 100) {
|
|
145
|
+
warnings.push(`File is ${percentage}% of the ${limit} line limit`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (lineCount > limit) {
|
|
149
|
+
const excess = lineCount - limit;
|
|
150
|
+
warnings.push(`File exceeds limit by ${excess} lines (${percentage}% of limit)`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return warnings;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Analyze multiple files
|
|
158
|
+
*/
|
|
159
|
+
analyzeFiles(filePaths, limit = this.defaultLimit) {
|
|
160
|
+
const results = [];
|
|
161
|
+
|
|
162
|
+
for (const filePath of filePaths) {
|
|
163
|
+
const result = this.analyzeFile(filePath, limit);
|
|
164
|
+
results.push(result);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return results;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Find files in a directory that should be analyzed
|
|
172
|
+
*/
|
|
173
|
+
findFilesToAnalyze(directory, recursive = true) {
|
|
174
|
+
const files = [];
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
178
|
+
|
|
179
|
+
for (const entry of entries) {
|
|
180
|
+
const fullPath = path.join(directory, entry.name);
|
|
181
|
+
|
|
182
|
+
if (entry.isDirectory() && recursive) {
|
|
183
|
+
// Skip excluded directories
|
|
184
|
+
if (!this.excludedDirectories.has(entry.name)) {
|
|
185
|
+
files.push(...this.findFilesToAnalyze(fullPath, recursive));
|
|
186
|
+
}
|
|
187
|
+
} else if (entry.isFile() && this.shouldAnalyze(fullPath)) {
|
|
188
|
+
files.push(fullPath);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
// Skip directories that can't be read
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return files;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
module.exports = {
|
|
200
|
+
FileLineAnalyzer
|
|
201
|
+
};
|