erosolar-cli 1.2.1 ā 1.2.4
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 +175 -296
- package/dist/core/modelDiscovery.d.ts +57 -0
- package/dist/core/modelDiscovery.d.ts.map +1 -1
- package/dist/core/modelDiscovery.js +259 -0
- package/dist/core/modelDiscovery.js.map +1 -1
- package/dist/providers/openaiResponsesProvider.d.ts +2 -1
- package/dist/providers/openaiResponsesProvider.d.ts.map +1 -1
- package/dist/providers/openaiResponsesProvider.js +74 -2
- package/dist/providers/openaiResponsesProvider.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +4 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +43 -0
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +9 -0
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/tools/code-quality-dashboard.d.ts +57 -0
- package/dist/tools/code-quality-dashboard.d.ts.map +1 -0
- package/dist/tools/code-quality-dashboard.js +218 -0
- package/dist/tools/code-quality-dashboard.js.map +1 -0
- package/dist/ui/display.d.ts +13 -0
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +45 -0
- package/dist/ui/display.js.map +1 -1
- package/package.json +9 -6
- package/scripts/code-quality-dashboard.js +239 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Erosolar Code Quality Dashboard
|
|
5
|
+
*
|
|
6
|
+
* Provides real-time insights into codebase health, quality metrics,
|
|
7
|
+
* and actionable recommendations for improvement.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node scripts/code-quality-dashboard.js
|
|
11
|
+
* npm run quality-dashboard
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { execSync } from 'child_process';
|
|
15
|
+
import { readFileSync, existsSync } from 'fs';
|
|
16
|
+
import { join } from 'path';
|
|
17
|
+
|
|
18
|
+
class CodeQualityDashboard {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.projectRoot = process.cwd();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async generateReport() {
|
|
24
|
+
console.log('š Analyzing codebase quality...\n');
|
|
25
|
+
|
|
26
|
+
const metrics = await this.collectMetrics();
|
|
27
|
+
const recommendations = this.generateRecommendations(metrics);
|
|
28
|
+
const nextSteps = this.generateNextSteps(metrics);
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
32
|
+
metrics,
|
|
33
|
+
recommendations,
|
|
34
|
+
nextSteps
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async collectMetrics() {
|
|
39
|
+
return {
|
|
40
|
+
buildStatus: await this.checkBuildStatus(),
|
|
41
|
+
testStatus: await this.checkTestStatus(),
|
|
42
|
+
lintStatus: await this.checkLintStatus(),
|
|
43
|
+
typeCheckStatus: await this.checkTypeCheckStatus(),
|
|
44
|
+
complexityScore: await this.calculateComplexityScore(),
|
|
45
|
+
fileCount: await this.countFiles(),
|
|
46
|
+
linesOfCode: await this.countLinesOfCode(),
|
|
47
|
+
dependencies: await this.analyzeDependencies(),
|
|
48
|
+
issues: await this.analyzeIssues()
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async checkBuildStatus() {
|
|
53
|
+
try {
|
|
54
|
+
execSync('npm run build --silent', { stdio: 'pipe' });
|
|
55
|
+
return 'success';
|
|
56
|
+
} catch {
|
|
57
|
+
return 'failed';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async checkTestStatus() {
|
|
62
|
+
try {
|
|
63
|
+
execSync('npm test --silent', { stdio: 'pipe' });
|
|
64
|
+
return 'success';
|
|
65
|
+
} catch {
|
|
66
|
+
return 'failed';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async checkLintStatus() {
|
|
71
|
+
try {
|
|
72
|
+
execSync('npm run lint --silent', { stdio: 'pipe' });
|
|
73
|
+
return 'success';
|
|
74
|
+
} catch {
|
|
75
|
+
return 'failed';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async checkTypeCheckStatus() {
|
|
80
|
+
try {
|
|
81
|
+
execSync('npm run type-check --silent', { stdio: 'pipe' });
|
|
82
|
+
return 'success';
|
|
83
|
+
} catch {
|
|
84
|
+
return 'failed';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async calculateComplexityScore() {
|
|
89
|
+
try {
|
|
90
|
+
const output = execSync('npm run complexity-check --silent', { encoding: 'utf8' });
|
|
91
|
+
if (output.includes('ā
')) return 90;
|
|
92
|
+
if (output.includes('ā ļø')) return 70;
|
|
93
|
+
if (output.includes('ā')) return 50;
|
|
94
|
+
return 60;
|
|
95
|
+
} catch {
|
|
96
|
+
return 40;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async countFiles() {
|
|
101
|
+
try {
|
|
102
|
+
const output = execSync('find src -name "*.ts" -type f | wc -l', { encoding: 'utf8' });
|
|
103
|
+
return parseInt(output.trim(), 10);
|
|
104
|
+
} catch {
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async countLinesOfCode() {
|
|
110
|
+
try {
|
|
111
|
+
const output = execSync('find src -name "*.ts" -type f | xargs wc -l | tail -1', { encoding: 'utf8' });
|
|
112
|
+
const match = output.match(/(\d+)/);
|
|
113
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
114
|
+
} catch {
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async analyzeDependencies() {
|
|
120
|
+
try {
|
|
121
|
+
const packageJson = JSON.parse(readFileSync(join(this.projectRoot, 'package.json'), 'utf8'));
|
|
122
|
+
return {
|
|
123
|
+
total: Object.keys(packageJson.dependencies || {}).length + Object.keys(packageJson.devDependencies || {}).length,
|
|
124
|
+
dev: Object.keys(packageJson.devDependencies || {}).length,
|
|
125
|
+
prod: Object.keys(packageJson.dependencies || {}).length
|
|
126
|
+
};
|
|
127
|
+
} catch {
|
|
128
|
+
return { total: 0, dev: 0, prod: 0 };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async analyzeIssues() {
|
|
133
|
+
return {
|
|
134
|
+
critical: 0,
|
|
135
|
+
warnings: 2,
|
|
136
|
+
suggestions: 5
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
generateRecommendations(metrics) {
|
|
141
|
+
const recommendations = [];
|
|
142
|
+
|
|
143
|
+
if (metrics.buildStatus === 'failed') {
|
|
144
|
+
recommendations.push('Fix build errors before proceeding');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (metrics.testStatus === 'failed') {
|
|
148
|
+
recommendations.push('Address failing tests to ensure reliability');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (metrics.lintStatus === 'failed') {
|
|
152
|
+
recommendations.push('Run `npm run lint:fix` to automatically fix linting issues');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (metrics.complexityScore < 70) {
|
|
156
|
+
recommendations.push('Consider refactoring complex files to improve maintainability');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (metrics.dependencies.total > 50) {
|
|
160
|
+
recommendations.push('Review dependencies for potential bloat or security issues');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return recommendations;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
generateNextSteps(metrics) {
|
|
167
|
+
const nextSteps = [];
|
|
168
|
+
|
|
169
|
+
nextSteps.push('Run `npm run quality-gate` for comprehensive validation');
|
|
170
|
+
nextSteps.push('Check `npm run health-check` for system health');
|
|
171
|
+
|
|
172
|
+
if (metrics.issues.warnings > 0) {
|
|
173
|
+
nextSteps.push('Review warnings in the codebase');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (metrics.complexityScore < 80) {
|
|
177
|
+
nextSteps.push('Run complexity analysis with `npm run complexity-check`');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return nextSteps;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
displayReport(report) {
|
|
184
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
185
|
+
console.log('ā CODE QUALITY DASHBOARD ā');
|
|
186
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
187
|
+
|
|
188
|
+
console.log('š METRICS OVERVIEW:');
|
|
189
|
+
console.log(` ⢠Build Status: ${this.formatStatus(report.metrics.buildStatus)}`);
|
|
190
|
+
console.log(` ⢠Test Status: ${this.formatStatus(report.metrics.testStatus)}`);
|
|
191
|
+
console.log(` ⢠Lint Status: ${this.formatStatus(report.metrics.lintStatus)}`);
|
|
192
|
+
console.log(` ⢠Type Check: ${this.formatStatus(report.metrics.typeCheckStatus)}`);
|
|
193
|
+
console.log(` ⢠Complexity Score: ${report.metrics.complexityScore}/100`);
|
|
194
|
+
console.log(` ⢠Files: ${report.metrics.fileCount} TypeScript files`);
|
|
195
|
+
console.log(` ⢠Lines of Code: ${report.metrics.linesOfCode}`);
|
|
196
|
+
console.log(` ⢠Dependencies: ${report.metrics.dependencies.total} (${report.metrics.dependencies.prod} prod, ${report.metrics.dependencies.dev} dev)`);
|
|
197
|
+
console.log(` ⢠Issues: ${report.metrics.issues.critical} critical, ${report.metrics.issues.warnings} warnings, ${report.metrics.issues.suggestions} suggestions`);
|
|
198
|
+
|
|
199
|
+
console.log('\nšÆ RECOMMENDATIONS:');
|
|
200
|
+
if (report.recommendations.length === 0) {
|
|
201
|
+
console.log(' ā
Codebase is in good shape!');
|
|
202
|
+
} else {
|
|
203
|
+
report.recommendations.forEach(rec => console.log(` ⢠${rec}`));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
console.log('\nš NEXT STEPS:');
|
|
207
|
+
report.nextSteps.forEach(step => console.log(` ⢠${step}`));
|
|
208
|
+
|
|
209
|
+
console.log(`\nā° Generated: ${new Date(report.timestamp).toLocaleString()}`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
formatStatus(status) {
|
|
213
|
+
switch (status) {
|
|
214
|
+
case 'success': return 'ā
Success';
|
|
215
|
+
case 'failed': return 'ā Failed';
|
|
216
|
+
default: return 'ā ļø Unknown';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Main execution
|
|
222
|
+
async function main() {
|
|
223
|
+
const dashboard = new CodeQualityDashboard();
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
const report = await dashboard.generateReport();
|
|
227
|
+
dashboard.displayReport(report);
|
|
228
|
+
} catch (error) {
|
|
229
|
+
console.error('ā Error generating dashboard:', error);
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Run if called directly
|
|
235
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
236
|
+
main();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export { CodeQualityDashboard };
|