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.
Files changed (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. 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
+ };