vibecodingmachine-cli 2026.2.20-436 ā 2026.2.26-1642
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/bin/auth/auth-compliance.js +126 -0
- package/bin/cli-program.js +104 -0
- package/bin/cli-setup.js +52 -0
- package/bin/commands/agent-commands.js +310 -0
- package/bin/commands/auto-commands.js +70 -0
- package/bin/commands/command-aliases.js +118 -0
- package/bin/commands/repo-commands.js +39 -0
- package/bin/commands/rui-commands.js +152 -0
- package/bin/config/cli-config.js +394 -0
- package/bin/init/environment-setup.js +84 -0
- package/bin/update/update-checker.js +126 -0
- package/bin/vibecodingmachine-new.js +50 -0
- package/bin/vibecodingmachine.js +29 -663
- package/package.json +8 -2
- package/src/commands/agents/add.js +277 -0
- package/src/commands/agents/check.js +380 -0
- package/src/commands/agents/list.js +471 -0
- package/src/commands/agents/remove.js +351 -0
- package/src/commands/analyze-file-sizes.js +428 -0
- package/src/commands/auto-direct/code-processor.js +282 -0
- package/src/commands/auto-direct/file-scanner.js +266 -0
- package/src/commands/auto-direct/provider-config.js +178 -0
- package/src/commands/auto-direct/provider-manager.js +219 -0
- package/src/commands/auto-direct/requirement-manager.js +172 -0
- package/src/commands/auto-direct/status-display.js +91 -0
- package/src/commands/auto-direct/utils.js +106 -0
- package/src/commands/auto-direct.js +875 -488
- package/src/commands/auto-execution.js +342 -0
- package/src/commands/auto-provider-management.js +102 -0
- package/src/commands/auto-requirement-management.js +161 -0
- package/src/commands/auto-status-helpers.js +141 -0
- package/src/commands/auto.js +105 -5155
- package/src/commands/check-compliance.js +536 -0
- package/src/commands/continuous-scan.js +119 -0
- package/src/commands/ide.js +16 -4
- package/src/commands/refactor-file.js +486 -0
- package/src/commands/requirements.js +301 -2
- package/src/commands/timeout.js +290 -0
- package/src/trui/TruiInterface.js +108 -0
- package/src/trui/agents/AgentInterface.js +580 -0
- package/src/utils/antigravity-installer.js +60 -6
- package/src/utils/clarification-actions.js +290 -0
- package/src/utils/config.js +123 -2
- package/src/utils/first-run.js +5 -5
- package/src/utils/ide-handlers.js +212 -0
- package/src/utils/interactive/clarification-actions.js +348 -0
- package/src/utils/interactive/core-ui.js +265 -0
- package/src/utils/interactive/file-backup.js +237 -0
- package/src/utils/interactive/file-import-export.js +305 -0
- package/src/utils/interactive/file-operations.js +49 -0
- package/src/utils/interactive/file-validation.js +276 -0
- package/src/utils/interactive/interactive-prompts.js +480 -0
- package/src/utils/interactive/requirement-actions.js +127 -0
- package/src/utils/interactive/requirement-crud.js +356 -0
- package/src/utils/interactive/requirements-navigation.js +286 -0
- package/src/utils/interactive.js +390 -3459
- package/src/utils/provider-checker/agent-checker.js +250 -0
- package/src/utils/provider-checker/agent-runner.js +450 -0
- package/src/utils/provider-checker/cli-installer.js +123 -0
- package/src/utils/provider-checker/cli-utils.js +15 -0
- package/src/utils/provider-checker/format-utils.js +32 -0
- package/src/utils/provider-checker/ide-manager.js +72 -0
- package/src/utils/provider-checker/ide-utils.js +71 -0
- package/src/utils/provider-checker/node-detector.js +56 -0
- package/src/utils/provider-checker/node-utils.js +61 -0
- package/src/utils/provider-checker/process-spawn.js +22 -0
- package/src/utils/provider-checker/process-utils.js +37 -0
- package/src/utils/provider-checker/provider-validator.js +160 -0
- package/src/utils/provider-checker/quota-checker.js +54 -0
- package/src/utils/provider-checker/quota-detector.js +44 -0
- package/src/utils/provider-checker/requirements-manager.js +94 -0
- package/src/utils/provider-checker/test-requirements.js +95 -0
- package/src/utils/provider-checker/time-formatter.js +18 -0
- package/src/utils/provider-checker-new.js +14 -0
- package/src/utils/provider-checker.js +12 -407
- package/src/utils/provider-checkers/ide-manager.js +128 -0
- package/src/utils/provider-checkers/node-executable-finder.js +51 -0
- package/src/utils/provider-checkers/provider-checker-core.js +172 -0
- package/src/utils/provider-checkers/provider-checker-main.js +107 -0
- package/src/utils/provider-manager.js +60 -4
- package/src/utils/provider-registry.js +26 -3
- package/src/utils/provider-utils.js +173 -0
- package/src/utils/quota-detectors.js +212 -0
- package/src/utils/requirement-action-handlers.js +288 -0
- package/src/utils/requirement-actions/clarification-actions.js +229 -0
- package/src/utils/requirement-actions/confirmation-prompts.js +93 -0
- package/src/utils/requirement-actions/file-operations.js +92 -0
- package/src/utils/requirement-actions/helpers.js +40 -0
- package/src/utils/requirement-actions/requirement-operations.js +335 -0
- package/src/utils/requirement-actions.js +46 -856
- package/src/utils/requirement-file-operations.js +259 -0
- package/src/utils/requirement-helpers.js +128 -0
- package/src/utils/requirement-management.js +279 -0
- package/src/utils/requirement-navigation.js +146 -0
- package/src/utils/requirement-organization.js +271 -0
- package/src/utils/simple-trui.js +75 -1
- package/src/utils/trui-navigation.js +28 -2
- package/src/utils/trui-req-tree.js +196 -11
- package/src/utils/trui-specifications.js +31 -1
- package/src/utils/interactive-backup.js +0 -5664
- package/src/utils/trui-provider-manager.js +0 -182
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI Command for Checking Compliance
|
|
5
|
+
*
|
|
6
|
+
* Provides command-line interface for checking file size compliance
|
|
7
|
+
* and constitutional adherence across the codebase.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const { program } = require('commander');
|
|
13
|
+
|
|
14
|
+
// Import core modules
|
|
15
|
+
const { LineLimitValidator } = require('../../../core/src/validation/line-limit-validator');
|
|
16
|
+
const { ConstitutionValidator } = require('../../../core/src/validation/constitution-validator');
|
|
17
|
+
const ComplianceReporter = require('../../../core/src/validation/compliance-reporter');
|
|
18
|
+
// const FileMonitor = require('../../../core/src/monitoring/file-monitor');
|
|
19
|
+
const { AlertSystem } = require('../../../core/src/monitoring/alert-system');
|
|
20
|
+
|
|
21
|
+
// Configuration
|
|
22
|
+
const DEFAULT_CONFIG = {
|
|
23
|
+
maxFileSize: 555,
|
|
24
|
+
warningThreshold: 500,
|
|
25
|
+
criticalThreshold: 800,
|
|
26
|
+
allowedFileTypes: ['js', 'jsx', 'ts', 'tsx', 'md', 'json'],
|
|
27
|
+
excludedPaths: [
|
|
28
|
+
'node_modules',
|
|
29
|
+
'.git',
|
|
30
|
+
'dist',
|
|
31
|
+
'build',
|
|
32
|
+
'coverage',
|
|
33
|
+
'.vscode',
|
|
34
|
+
'.idea',
|
|
35
|
+
'.cursor',
|
|
36
|
+
'.windsurf',
|
|
37
|
+
'vendor',
|
|
38
|
+
'bower_components'
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Colors for console output
|
|
44
|
+
*/
|
|
45
|
+
const COLORS = {
|
|
46
|
+
reset: '\x1b[0m',
|
|
47
|
+
red: '\x1b[31m',
|
|
48
|
+
yellow: '\x1b[33m',
|
|
49
|
+
green: '\x1b[32m',
|
|
50
|
+
cyan: '\x1b[36m',
|
|
51
|
+
blue: '\x1b[34m',
|
|
52
|
+
bold: '\x1b[1m',
|
|
53
|
+
dim: '\x1b[2m'
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Color output helper
|
|
58
|
+
*/
|
|
59
|
+
function colorLog(color, message) {
|
|
60
|
+
console.log(`${COLORS[color]}${message}${COLORS.reset}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Format bytes to human readable
|
|
65
|
+
*/
|
|
66
|
+
function formatBytes(bytes) {
|
|
67
|
+
if (bytes === 0) return '0 B';
|
|
68
|
+
const k = 1024;
|
|
69
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
70
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
71
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Format duration
|
|
76
|
+
*/
|
|
77
|
+
function formatDuration(ms) {
|
|
78
|
+
if (ms < 1000) return `${ms}ms`;
|
|
79
|
+
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
|
80
|
+
return `${(ms / 60000).toFixed(1)}m`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get all files in directory recursively
|
|
85
|
+
*/
|
|
86
|
+
async function getAllFiles(dirPath, options = {}) {
|
|
87
|
+
const files = [];
|
|
88
|
+
|
|
89
|
+
const scanDir = (dir) => {
|
|
90
|
+
try {
|
|
91
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
92
|
+
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
const fullPath = path.join(dir, entry.name);
|
|
95
|
+
|
|
96
|
+
if (entry.isDirectory()) {
|
|
97
|
+
// Skip excluded directories
|
|
98
|
+
if (!options.excludedPaths?.some(pattern => fullPath.includes(pattern))) {
|
|
99
|
+
scanDir(fullPath);
|
|
100
|
+
}
|
|
101
|
+
} else if (entry.isFile()) {
|
|
102
|
+
// Check file extension
|
|
103
|
+
const ext = path.extname(fullPath).slice(1);
|
|
104
|
+
if (options.allowedFileTypes?.includes(ext)) {
|
|
105
|
+
files.push(fullPath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (!options.quiet) {
|
|
111
|
+
colorLog('yellow', `ā ļø Warning: Cannot read directory ${dir}: ${error.message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
scanDir(dirPath);
|
|
117
|
+
return files;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Validate single file
|
|
122
|
+
*/
|
|
123
|
+
async function validateFile(filePath, validators, options) {
|
|
124
|
+
const results = {
|
|
125
|
+
filePath,
|
|
126
|
+
lineCount: 0,
|
|
127
|
+
fileSize: 0,
|
|
128
|
+
lineLimitValidation: null,
|
|
129
|
+
constitutionalValidation: null,
|
|
130
|
+
hasViolations: false,
|
|
131
|
+
hasWarnings: false
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
if (!fs.existsSync(filePath)) {
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Get file stats
|
|
140
|
+
const fileStats = fs.statSync(filePath);
|
|
141
|
+
results.fileSize = fileStats.size;
|
|
142
|
+
|
|
143
|
+
// Read file content
|
|
144
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
145
|
+
results.lineCount = content.split('\n').length;
|
|
146
|
+
|
|
147
|
+
// Line limit validation
|
|
148
|
+
if (validators.lineLimit) {
|
|
149
|
+
results.lineLimitValidation = validators.lineLimit.validateFile(filePath);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Constitutional validation
|
|
153
|
+
if (validators.constitution && options.enableConstitutional) {
|
|
154
|
+
results.constitutionalValidation = validators.constitution.validateFile(filePath);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Determine violation/warning status
|
|
158
|
+
results.hasViolations = !results.lineLimitValidation?.isValid ||
|
|
159
|
+
(results.constitutionalValidation?.some(r => r.severity === 'critical' || r.severity === 'error'));
|
|
160
|
+
|
|
161
|
+
results.hasWarnings = results.lineLimitValidation?.violation?.type === 'warning' ||
|
|
162
|
+
(results.constitutionalValidation?.some(r => r.severity === 'warning'));
|
|
163
|
+
|
|
164
|
+
} catch (error) {
|
|
165
|
+
results.error = error.message;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return results;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Validate multiple files
|
|
173
|
+
*/
|
|
174
|
+
async function validateFiles(filePaths, validators, options) {
|
|
175
|
+
const results = [];
|
|
176
|
+
const startTime = Date.now();
|
|
177
|
+
|
|
178
|
+
if (options.parallel) {
|
|
179
|
+
// Process files in parallel
|
|
180
|
+
const promises = filePaths.map(filePath => validateFile(filePath, validators, options));
|
|
181
|
+
const settled = await Promise.allSettled(promises);
|
|
182
|
+
|
|
183
|
+
for (const result of settled) {
|
|
184
|
+
if (result.status === 'fulfilled') {
|
|
185
|
+
results.push(result.value);
|
|
186
|
+
} else {
|
|
187
|
+
if (!options.quiet) {
|
|
188
|
+
colorLog('red', `ā Error processing file: ${result.reason.message}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
// Process files sequentially
|
|
194
|
+
for (const filePath of filePaths) {
|
|
195
|
+
try {
|
|
196
|
+
const result = await validateFile(filePath, validators, options);
|
|
197
|
+
results.push(result);
|
|
198
|
+
|
|
199
|
+
if (options.progress && filePaths.length > 10) {
|
|
200
|
+
const progress = (results.length / filePaths.length * 100).toFixed(1);
|
|
201
|
+
process.stdout.write(`\rProgress: ${progress}% (${results.length}/${filePaths.length})`);
|
|
202
|
+
}
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (!options.quiet) {
|
|
205
|
+
colorLog('red', `ā Error validating ${filePath}: ${error.message}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (options.progress && filePaths.length > 10) {
|
|
211
|
+
console.log(''); // New line after progress
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const duration = Date.now() - startTime;
|
|
216
|
+
return { results, duration };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Print validation summary
|
|
221
|
+
*/
|
|
222
|
+
function printSummary(results, duration, options) {
|
|
223
|
+
const totalFiles = results.length;
|
|
224
|
+
const compliantFiles = results.filter(r => !r.hasViolations && !r.hasWarnings).length;
|
|
225
|
+
const warningFiles = results.filter(r => r.hasWarnings && !r.hasViolations).length;
|
|
226
|
+
const violationFiles = results.filter(r => r.hasViolations).length;
|
|
227
|
+
|
|
228
|
+
const totalLines = results.reduce((sum, r) => sum + r.lineCount, 0);
|
|
229
|
+
const totalSize = results.reduce((sum, r) => sum + r.fileSize, 0);
|
|
230
|
+
|
|
231
|
+
console.log('\n' + COLORS.bold + 'Compliance Summary' + COLORS.reset);
|
|
232
|
+
console.log('ā'.repeat(50));
|
|
233
|
+
|
|
234
|
+
// Basic stats
|
|
235
|
+
console.log(`š Files analyzed: ${COLORS.cyan}${totalFiles}${COLORS.reset}`);
|
|
236
|
+
console.log(`ā
Compliant files: ${COLORS.green}${compliantFiles}${COLORS.reset}`);
|
|
237
|
+
console.log(`ā ļø Warning files: ${COLORS.yellow}${warningFiles}${COLORS.reset}`);
|
|
238
|
+
console.log(`ā Violation files: ${COLORS.red}${violationFiles}${COLORS.reset}`);
|
|
239
|
+
|
|
240
|
+
// Compliance rate
|
|
241
|
+
const complianceRate = totalFiles > 0 ? (compliantFiles / totalFiles * 100) : 100;
|
|
242
|
+
const complianceColor = complianceRate >= 90 ? 'green' : complianceRate >= 70 ? 'yellow' : 'red';
|
|
243
|
+
console.log(`š Compliance rate: ${COLORS[complianceColor]}${complianceRate.toFixed(1)}%${COLORS.reset}`);
|
|
244
|
+
|
|
245
|
+
// File stats
|
|
246
|
+
console.log(`š Total lines: ${COLORS.cyan}${totalLines.toLocaleString()}${COLORS.reset}`);
|
|
247
|
+
console.log(`š¾ Total size: ${COLORS.cyan}${formatBytes(totalSize)}${COLORS.reset}`);
|
|
248
|
+
console.log(`ā±ļø Analysis time: ${COLORS.blue}${formatDuration(duration)}${COLORS.reset}`);
|
|
249
|
+
|
|
250
|
+
// Average stats
|
|
251
|
+
if (totalFiles > 0) {
|
|
252
|
+
const avgLines = Math.round(totalLines / totalFiles);
|
|
253
|
+
const avgSize = Math.round(totalSize / totalFiles);
|
|
254
|
+
console.log(`š Average lines/file: ${COLORS.cyan}${avgLines}${COLORS.reset}`);
|
|
255
|
+
console.log(`š Average size/file: ${COLORS.cyan}${formatBytes(avgSize)}${COLORS.reset}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
totalFiles,
|
|
260
|
+
compliantFiles,
|
|
261
|
+
warningFiles,
|
|
262
|
+
violationFiles,
|
|
263
|
+
complianceRate,
|
|
264
|
+
totalLines,
|
|
265
|
+
totalSize,
|
|
266
|
+
duration
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Print violations
|
|
272
|
+
*/
|
|
273
|
+
function printViolations(results, options) {
|
|
274
|
+
const violatingFiles = results.filter(r => r.hasViolations);
|
|
275
|
+
|
|
276
|
+
if (violatingFiles.length === 0) {
|
|
277
|
+
colorLog('green', '\nš No violations found!');
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
console.log('\n' + COLORS.bold + 'Violations' + COLORS.reset);
|
|
282
|
+
console.log('ā'.repeat(50));
|
|
283
|
+
|
|
284
|
+
for (const file of violatingFiles.sort((a, b) => b.lineCount - a.lineCount)) {
|
|
285
|
+
console.log(`\n${COLORS.red}ā ${file.filePath}${COLORS.reset}`);
|
|
286
|
+
console.log(` Lines: ${file.lineCount}`);
|
|
287
|
+
|
|
288
|
+
// Line limit violations
|
|
289
|
+
if (file.lineLimitValidation && !file.lineLimitValidation.isValid) {
|
|
290
|
+
const violation = file.lineLimitValidation.violation;
|
|
291
|
+
if (violation) {
|
|
292
|
+
console.log(` ${COLORS.red}Line limit violation: ${violation.message}${COLORS.reset}`);
|
|
293
|
+
console.log(` Excess: ${violation.excessLines} lines (${violation.percentageOverLimit}% over)`);
|
|
294
|
+
} else {
|
|
295
|
+
console.log(` ${COLORS.red}Line limit violation: File exceeds size limit${COLORS.reset}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Constitutional violations
|
|
300
|
+
if (file.constitutionalValidation) {
|
|
301
|
+
const criticalIssues = file.constitutionalValidation.filter(r => r.severity === 'critical');
|
|
302
|
+
const errorIssues = file.constitutionalValidation.filter(r => r.severity === 'error');
|
|
303
|
+
|
|
304
|
+
for (const issue of criticalIssues) {
|
|
305
|
+
console.log(` ${COLORS.red}šØ Critical (${issue.category}): ${issue.message}${COLORS.reset}`);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
for (const issue of errorIssues) {
|
|
309
|
+
console.log(` ${COLORS.red}ā Error (${issue.category}): ${issue.message}${COLORS.reset}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Print warnings
|
|
317
|
+
*/
|
|
318
|
+
function printWarnings(results, options) {
|
|
319
|
+
const warningFiles = results.filter(r => r.hasWarnings && !r.hasViolations);
|
|
320
|
+
|
|
321
|
+
if (warningFiles.length === 0) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
console.log('\n' + COLORS.bold + 'Warnings' + COLORS.reset);
|
|
326
|
+
console.log('ā'.repeat(50));
|
|
327
|
+
|
|
328
|
+
for (const file of warningFiles.sort((a, b) => b.lineCount - a.lineCount)) {
|
|
329
|
+
console.log(`\n${COLORS.yellow}ā ļø ${file.filePath}${COLORS.reset}`);
|
|
330
|
+
console.log(` Lines: ${file.lineCount}`);
|
|
331
|
+
|
|
332
|
+
// Line limit warnings
|
|
333
|
+
if (file.lineLimitValidation?.violation?.type === 'warning') {
|
|
334
|
+
console.log(` ${COLORS.yellow}Approaching limit: ${file.lineLimitValidation.violation.message}${COLORS.reset}`);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Constitutional warnings
|
|
338
|
+
if (file.constitutionalValidation) {
|
|
339
|
+
const warningIssues = file.constitutionalValidation.filter(r => r.severity === 'warning');
|
|
340
|
+
|
|
341
|
+
for (const issue of warningIssues) {
|
|
342
|
+
console.log(` ${COLORS.yellow}ā ļø Warning (${issue.category}): ${issue.message}${COLORS.reset}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Print top files
|
|
350
|
+
*/
|
|
351
|
+
function printTopFiles(results, options) {
|
|
352
|
+
const topFiles = results
|
|
353
|
+
.sort((a, b) => b.lineCount - a.lineCount)
|
|
354
|
+
.slice(0, options.top || 10);
|
|
355
|
+
|
|
356
|
+
console.log('\n' + COLORS.bold + `Top ${topFiles.length} Files by Size` + COLORS.reset);
|
|
357
|
+
console.log('ā'.repeat(50));
|
|
358
|
+
|
|
359
|
+
for (let i = 0; i < topFiles.length; i++) {
|
|
360
|
+
const file = topFiles[i];
|
|
361
|
+
const status = file.hasViolations ? 'ā' : file.hasWarnings ? 'ā ļø' : 'ā
';
|
|
362
|
+
const statusColor = file.hasViolations ? 'red' : file.hasWarnings ? 'yellow' : 'green';
|
|
363
|
+
|
|
364
|
+
console.log(`${i + 1}. ${COLORS[statusColor]}${status}${COLORS.reset} ${file.filePath}`);
|
|
365
|
+
console.log(` ${file.lineCount} lines ⢠${formatBytes(file.fileSize)}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Generate and save report
|
|
371
|
+
*/
|
|
372
|
+
async function generateReport(results, options) {
|
|
373
|
+
if (!options.report) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
const reporter = new ComplianceReporter({
|
|
379
|
+
outputDir: path.dirname(options.report),
|
|
380
|
+
formats: [path.extname(options.report).slice(1) || 'json']
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const reportResult = await reporter.generateReport(results, {
|
|
384
|
+
title: 'CLI Compliance Report',
|
|
385
|
+
includeMetrics: true,
|
|
386
|
+
includeRecommendations: true
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
colorLog('green', `\nš Report saved to: ${reportResult.files[0].filePath}`);
|
|
390
|
+
|
|
391
|
+
} catch (error) {
|
|
392
|
+
colorLog('red', `ā Failed to generate report: ${error.message}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Main check compliance function
|
|
398
|
+
*/
|
|
399
|
+
async function checkCompliance(options) {
|
|
400
|
+
const startTime = Date.now();
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
// Initialize validators
|
|
404
|
+
const validators = {
|
|
405
|
+
lineLimit: new LineLimitValidator({
|
|
406
|
+
maxLines: options.maxFileSize,
|
|
407
|
+
warningThreshold: options.warningThreshold,
|
|
408
|
+
criticalThreshold: options.criticalThreshold
|
|
409
|
+
})
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
if (options.enableConstitutional) {
|
|
413
|
+
validators.constitution = new ConstitutionValidator();
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Get files to validate
|
|
417
|
+
colorLog('cyan', `š Scanning ${options.path || 'current directory'} for files...`);
|
|
418
|
+
const files = await getAllFiles(options.path || process.cwd(), {
|
|
419
|
+
allowedFileTypes: options.fileTypes,
|
|
420
|
+
excludedPaths: options.excludedPaths,
|
|
421
|
+
quiet: options.quiet
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
if (files.length === 0) {
|
|
425
|
+
colorLog('yellow', 'ā ļø No files found to validate');
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
colorLog('cyan', `š Found ${files.length} files to validate`);
|
|
430
|
+
|
|
431
|
+
// Validate files
|
|
432
|
+
const { results, duration } = await validateFiles(files, validators, options);
|
|
433
|
+
|
|
434
|
+
// Print results
|
|
435
|
+
const summary = printSummary(results, duration, options);
|
|
436
|
+
|
|
437
|
+
if (options.violations || options.verbose) {
|
|
438
|
+
printViolations(results, options);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (options.warnings || options.verbose) {
|
|
442
|
+
printWarnings(results, options);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (options.top) {
|
|
446
|
+
printTopFiles(results, options);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Generate report if requested
|
|
450
|
+
await generateReport(results, options);
|
|
451
|
+
|
|
452
|
+
// Exit with appropriate code
|
|
453
|
+
if (summary.violationFiles > 0) {
|
|
454
|
+
if (!options.quiet) {
|
|
455
|
+
colorLog('red', `\nā Compliance check failed with ${summary.violationFiles} violations`);
|
|
456
|
+
}
|
|
457
|
+
process.exit(1);
|
|
458
|
+
} else if (summary.warningFiles > 0 && !options.warningsAllowed) {
|
|
459
|
+
if (!options.quiet) {
|
|
460
|
+
colorLog('yellow', `\nā ļø Compliance check passed with ${summary.warningFiles} warnings`);
|
|
461
|
+
}
|
|
462
|
+
process.exit(2);
|
|
463
|
+
} else {
|
|
464
|
+
if (!options.quiet) {
|
|
465
|
+
colorLog('green', `\nā
Compliance check passed successfully!`);
|
|
466
|
+
}
|
|
467
|
+
process.exit(0);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
} catch (error) {
|
|
471
|
+
colorLog('red', `ā Compliance check failed: ${error.message}`);
|
|
472
|
+
if (options.verbose) {
|
|
473
|
+
console.error(error.stack);
|
|
474
|
+
}
|
|
475
|
+
process.exit(1);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Setup CLI program
|
|
481
|
+
*/
|
|
482
|
+
function setupProgram() {
|
|
483
|
+
program
|
|
484
|
+
.name('check-compliance')
|
|
485
|
+
.description('Check file size compliance and constitutional adherence')
|
|
486
|
+
.version('1.0.0');
|
|
487
|
+
|
|
488
|
+
program
|
|
489
|
+
.argument('[path]', 'Path to check (default: current directory)')
|
|
490
|
+
.option('-m, --max-file-size <number>', 'Maximum file size in lines', String(DEFAULT_CONFIG.maxFileSize))
|
|
491
|
+
.option('-w, --warning-threshold <number>', 'Warning threshold in lines', String(DEFAULT_CONFIG.warningThreshold))
|
|
492
|
+
.option('-c, --critical-threshold <number>', 'Critical threshold in lines', String(DEFAULT_CONFIG.criticalThreshold))
|
|
493
|
+
.option('-t, --file-types <types>', 'File types to check (comma-separated)', DEFAULT_CONFIG.allowedFileTypes.join(','))
|
|
494
|
+
.option('-e, --exclude <paths>', 'Paths to exclude (comma-separated)', DEFAULT_CONFIG.excludedPaths.join(','))
|
|
495
|
+
.option('--enable-constitutional', 'Enable constitutional compliance checking', false)
|
|
496
|
+
.option('--parallel', 'Process files in parallel', false)
|
|
497
|
+
.option('--progress', 'Show progress bar', false)
|
|
498
|
+
.option('--violations', 'Show only violations', false)
|
|
499
|
+
.option('--warnings', 'Show warnings', false)
|
|
500
|
+
.option('--warnings-allowed', 'Allow warnings (exit code 0)', false)
|
|
501
|
+
.option('--top <number>', 'Show top N files by size', '10')
|
|
502
|
+
.option('--report <path>', 'Generate report file')
|
|
503
|
+
.option('--verbose', 'Verbose output', false)
|
|
504
|
+
.option('--quiet', 'Quiet mode', false)
|
|
505
|
+
.action(async (path, options) => {
|
|
506
|
+
// Parse options
|
|
507
|
+
options.path = path;
|
|
508
|
+
options.maxFileSize = parseInt(options.maxFileSize);
|
|
509
|
+
options.warningThreshold = parseInt(options.warningThreshold);
|
|
510
|
+
options.criticalThreshold = parseInt(options.criticalThreshold);
|
|
511
|
+
options.fileTypes = options.fileTypes.split(',').map(t => t.trim());
|
|
512
|
+
options.excludedPaths = options.exclude.split(',').map(p => p.trim());
|
|
513
|
+
options.top = parseInt(options.top);
|
|
514
|
+
|
|
515
|
+
await checkCompliance(options);
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
program.parse();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Run if called directly
|
|
522
|
+
if (require.main === module) {
|
|
523
|
+
setupProgram();
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
module.exports = {
|
|
527
|
+
checkCompliance,
|
|
528
|
+
getAllFiles,
|
|
529
|
+
validateFile,
|
|
530
|
+
validateFiles,
|
|
531
|
+
printSummary,
|
|
532
|
+
printViolations,
|
|
533
|
+
printWarnings,
|
|
534
|
+
printTopFiles,
|
|
535
|
+
generateReport
|
|
536
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Continuous Scan CLI Command
|
|
5
|
+
*
|
|
6
|
+
* This command runs continuous compliance scanning to identify files
|
|
7
|
+
* exceeding the 555-line limit and generates refactoring tasks.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { program } = require('commander');
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const { ContinuousScanner } = require('../../../core/src/monitoring/continuous-scanner');
|
|
13
|
+
const taskListUpdater = require('../../../core/src/task-generation/task-list-updater');
|
|
14
|
+
const complianceReporter = require('../../../core/src/validation/compliance-reporter');
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.name('continuous-scan')
|
|
18
|
+
.description('Run continuous compliance scanning for file size violations')
|
|
19
|
+
.option('-w, --watch', 'Run in watch mode for continuous monitoring')
|
|
20
|
+
.option('-o, --output <file>', 'Output report to file', 'continuous-scan-report.json')
|
|
21
|
+
.option('-t, --tasks', 'Generate refactoring tasks for violations')
|
|
22
|
+
.option('-v, --verbose', 'Verbose output with detailed information')
|
|
23
|
+
.option('--threshold <lines>', 'Line count threshold (default: 555)', '555')
|
|
24
|
+
.action(async (options) => {
|
|
25
|
+
try {
|
|
26
|
+
console.log(chalk.blue('š Starting continuous compliance scan...'));
|
|
27
|
+
|
|
28
|
+
// Initialize scanner
|
|
29
|
+
const scanner = new ContinuousScanner({
|
|
30
|
+
maxFileSize: parseInt(options.threshold),
|
|
31
|
+
enableFileWatching: options.watch
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Set up event handlers
|
|
35
|
+
scanner.events.on('scan_completed', (data) => {
|
|
36
|
+
const violations = data.violations || [];
|
|
37
|
+
|
|
38
|
+
if (violations.length === 0) {
|
|
39
|
+
console.log(chalk.green('ā
No file size violations found!'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log(chalk.yellow(`ā ļø Found ${violations.length} files exceeding ${options.threshold} lines:`));
|
|
44
|
+
|
|
45
|
+
// Display violations
|
|
46
|
+
violations.forEach((violation, index) => {
|
|
47
|
+
const severity = violation.lineCount > 1000 ? chalk.red('CRITICAL') :
|
|
48
|
+
violation.lineCount > 750 ? chalk.orange('HIGH') :
|
|
49
|
+
chalk.yellow('MEDIUM');
|
|
50
|
+
|
|
51
|
+
console.log(`${index + 1}. ${violation.filePath} - ${violation.lineCount} lines ${severity}`);
|
|
52
|
+
|
|
53
|
+
if (options.verbose) {
|
|
54
|
+
console.log(` File size: ${(violation.fileSize / 1024).toFixed(2)} KB`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Generate tasks if requested
|
|
59
|
+
if (options.tasks) {
|
|
60
|
+
console.log(chalk.blue('\nš Generating refactoring tasks...'));
|
|
61
|
+
// Task generation would be implemented here
|
|
62
|
+
console.log(chalk.yellow('ā ļø Task generation not yet implemented'));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Generate report
|
|
66
|
+
if (options.output) {
|
|
67
|
+
const report = {
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
violations: violations,
|
|
70
|
+
stats: data.stats || {}
|
|
71
|
+
};
|
|
72
|
+
require('fs').writeFileSync(options.output, JSON.stringify(report, null, 2));
|
|
73
|
+
console.log(chalk.blue(`š Report saved to: ${options.output}`));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Summary statistics
|
|
77
|
+
console.log(chalk.blue('\nš Scan Summary:'));
|
|
78
|
+
console.log(`Violations found: ${violations.length}`);
|
|
79
|
+
if (data.stats && data.stats.filesScanned) {
|
|
80
|
+
console.log(`Total files scanned: ${data.stats.filesScanned}`);
|
|
81
|
+
console.log(`Compliance rate: ${((data.stats.filesScanned - violations.length) / data.stats.filesScanned * 100).toFixed(1)}%`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Start scanning
|
|
86
|
+
scanner.start();
|
|
87
|
+
|
|
88
|
+
if (options.watch) {
|
|
89
|
+
console.log(chalk.green('š Watching for file changes... Press Ctrl+C to stop'));
|
|
90
|
+
|
|
91
|
+
// Set up additional event handlers for continuous monitoring
|
|
92
|
+
scanner.events.on('violations_found', ({ count, violations }) => {
|
|
93
|
+
console.log(chalk.yellow(`\nšØ Violations found: ${count}`));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Handle graceful shutdown
|
|
97
|
+
process.on('SIGINT', () => {
|
|
98
|
+
console.log(chalk.yellow('\nš Stopping continuous scan...'));
|
|
99
|
+
scanner.stop();
|
|
100
|
+
console.log(chalk.green('ā
Continuous scan stopped'));
|
|
101
|
+
process.exit(0);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Keep process running
|
|
105
|
+
// The scanner will continue running in the background
|
|
106
|
+
} else {
|
|
107
|
+
// Run for a short time then stop
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
scanner.stop();
|
|
110
|
+
}, 5000);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error(chalk.red('ā Error during continuous scan:'), error.message);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
program.parse();
|
package/src/commands/ide.js
CHANGED
|
@@ -138,16 +138,28 @@ async function health(options = {}) {
|
|
|
138
138
|
console.log(chalk.bold('\nš Successful IDEs:'));
|
|
139
139
|
for (const result of successful) {
|
|
140
140
|
const metrics = await healthTracker.getHealthMetrics(result.ide);
|
|
141
|
-
console.log(chalk.cyan(` ${result.ide}:`)
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
console.log(chalk.cyan(` ${result.ide}:`));
|
|
142
|
+
console.log(chalk.gray(` Response Time: ${result.responseTime}ms`));
|
|
143
|
+
console.log(chalk.gray(` Success Rate: ${(metrics.successRate * 100).toFixed(1)}%`));
|
|
144
|
+
console.log(chalk.gray(` Total Successes: ${metrics.successCount}`));
|
|
145
|
+
console.log(chalk.gray(` Total Failures: ${metrics.failureCount}`));
|
|
146
|
+
console.log(chalk.gray(` Avg Response Time: ${Math.round(metrics.averageResponseTime)}ms`));
|
|
147
|
+
console.log(chalk.gray(` Consecutive Failures: ${metrics.consecutiveFailures}`));
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
if ((failed.length > 0 || timeouts.length > 0) && verbose) {
|
|
148
152
|
console.log(chalk.bold('\nā ļø Problematic IDEs:'));
|
|
149
153
|
for (const result of [...failed, ...timeouts]) {
|
|
150
|
-
|
|
154
|
+
const metrics = await healthTracker.getHealthMetrics(result.ide);
|
|
155
|
+
console.log(chalk.red(` ${result.ide}:`));
|
|
156
|
+
console.log(chalk.gray(` Response Time: ${result.responseTime}ms`));
|
|
157
|
+
console.log(chalk.gray(` Error: ${result.error || 'Timeout'}`));
|
|
158
|
+
console.log(chalk.gray(` Success Rate: ${(metrics.successRate * 100).toFixed(1)}%`));
|
|
159
|
+
console.log(chalk.gray(` Total Successes: ${metrics.successCount}`));
|
|
160
|
+
console.log(chalk.gray(` Total Failures: ${metrics.failureCount}`));
|
|
161
|
+
console.log(chalk.gray(` Avg Response Time: ${Math.round(metrics.averageResponseTime)}ms`));
|
|
162
|
+
console.log(chalk.gray(` Consecutive Failures: ${metrics.consecutiveFailures}`));
|
|
151
163
|
}
|
|
152
164
|
}
|
|
153
165
|
|