devintelligence 0.0.0-stage → 1.0.1
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/.env.example +14 -0
- package/LICENSE +22 -0
- package/README.md +146 -3
- package/bin/devintelligence.js +2486 -0
- package/bin/devintelligence.ts +416 -0
- package/dist/App.d.ts +3 -0
- package/dist/ai.js +366 -0
- package/dist/ai.js.map +7 -0
- package/dist/components/DeepAnalysisViews.d.ts +13 -0
- package/dist/components/MobileAndPlatformViews.d.ts +22 -0
- package/dist/components/OverviewAndExplorerViews.d.ts +20 -0
- package/dist/components/RepairAndGateViews.d.ts +25 -0
- package/dist/engine/aiEngine.d.ts +62 -0
- package/dist/engine/analyzerEngine.d.ts +19 -0
- package/dist/engine/repairEngine.d.ts +42 -0
- package/dist/engine.js +1541 -0
- package/dist/engine.js.map +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +2344 -0
- package/dist/index.js.map +7 -0
- package/dist/main.d.ts +1 -0
- package/dist/repair.js +2052 -0
- package/dist/repair.js.map +7 -0
- package/dist/src/App.d.ts +3 -0
- package/dist/src/components/DeepAnalysisViews.d.ts +13 -0
- package/dist/src/components/MobileAndPlatformViews.d.ts +22 -0
- package/dist/src/components/OverviewAndExplorerViews.d.ts +20 -0
- package/dist/src/components/RepairAndGateViews.d.ts +25 -0
- package/dist/src/engine/aiEngine.d.ts +62 -0
- package/dist/src/engine/analyzerEngine.d.ts +19 -0
- package/dist/src/engine/repairEngine.d.ts +42 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/main.d.ts +1 -0
- package/dist/src/types/devintelligence.d.ts +250 -0
- package/dist/types/devintelligence.d.ts +250 -0
- package/fixtures/django-analytics-service/requirements.txt +4 -0
- package/fixtures/django-analytics-service/settings.py +16 -0
- package/fixtures/express-api-gateway/package.json +14 -0
- package/fixtures/express-api-gateway/src/server.ts +16 -0
- package/fixtures/nextjs-saas-portal/package.json +21 -0
- package/fixtures/nextjs-saas-portal/src/app/dashboard/page.tsx +26 -0
- package/fixtures/rn-bare-fitness/android/build.gradle +19 -0
- package/fixtures/rn-bare-fitness/ios/Info.plist +14 -0
- package/fixtures/rn-bare-fitness/package.json +23 -0
- package/fixtures/rn-bare-fitness/src/WorkoutTracker.tsx +31 -0
- package/fixtures/rn-expo-commerce/android/app/build.gradle +20 -0
- package/fixtures/rn-expo-commerce/android/app/src/main/AndroidManifest.xml +21 -0
- package/fixtures/rn-expo-commerce/android/gradle.properties +6 -0
- package/fixtures/rn-expo-commerce/app.json +17 -0
- package/fixtures/rn-expo-commerce/babel.config.js +10 -0
- package/fixtures/rn-expo-commerce/ios/Podfile +13 -0
- package/fixtures/rn-expo-commerce/metro.config.js +7 -0
- package/fixtures/rn-expo-commerce/package.json +31 -0
- package/fixtures/rn-expo-commerce/src/components/LegacyPromoBanner.tsx +11 -0
- package/fixtures/rn-expo-commerce/src/screens/ProductFeedScreen.tsx +48 -0
- package/fixtures/rn-expo-commerce/src/services/api.ts +15 -0
- package/package.json +89 -6
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import {
|
|
7
|
+
getAllProjectReports,
|
|
8
|
+
getProjectReportById,
|
|
9
|
+
registerLocalProject,
|
|
10
|
+
applyAllSafeRepairsOnDisk,
|
|
11
|
+
MCP_TOOLS_CATALOG,
|
|
12
|
+
executeMcpToolCall,
|
|
13
|
+
} from '../src/engine/repairEngine.ts';
|
|
14
|
+
import {
|
|
15
|
+
inspectHostEnvironment,
|
|
16
|
+
PRESET_ERROR_LOGS,
|
|
17
|
+
} from '../src/engine/analyzerEngine.ts';
|
|
18
|
+
import {
|
|
19
|
+
diagnoseRawErrorLogWithAi,
|
|
20
|
+
generateProjectAiAdvice,
|
|
21
|
+
askDevIntelligenceAi,
|
|
22
|
+
getGroqApiKey,
|
|
23
|
+
} from '../src/engine/aiEngine.ts';
|
|
24
|
+
|
|
25
|
+
// Load environment variables (.env in cwd or root)
|
|
26
|
+
try {
|
|
27
|
+
if (typeof process.loadEnvFile === 'function') {
|
|
28
|
+
const cwdEnv = path.join(process.cwd(), '.env');
|
|
29
|
+
if (fs.existsSync(cwdEnv)) {
|
|
30
|
+
process.loadEnvFile(cwdEnv);
|
|
31
|
+
} else {
|
|
32
|
+
process.loadEnvFile();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch {}
|
|
36
|
+
|
|
37
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
38
|
+
const __dirname = path.dirname(__filename);
|
|
39
|
+
const rootWorkspaceDir = path.resolve(__dirname, '..');
|
|
40
|
+
|
|
41
|
+
// Terminal ANSI Styling Helpers
|
|
42
|
+
const isColorSupported =
|
|
43
|
+
!process.env.NO_COLOR &&
|
|
44
|
+
(Boolean(process.stdout?.isTTY) || process.env.FORCE_COLOR !== undefined);
|
|
45
|
+
|
|
46
|
+
const c = {
|
|
47
|
+
reset: (s: string | number) => (isColorSupported ? `\x1b[0m${s}\x1b[0m` : String(s)),
|
|
48
|
+
bold: (s: string | number) => (isColorSupported ? `\x1b[1m${s}\x1b[22m` : String(s)),
|
|
49
|
+
dim: (s: string | number) => (isColorSupported ? `\x1b[2m${s}\x1b[22m` : String(s)),
|
|
50
|
+
cyan: (s: string | number) => (isColorSupported ? `\x1b[36m${s}\x1b[39m` : String(s)),
|
|
51
|
+
blue: (s: string | number) => (isColorSupported ? `\x1b[34m${s}\x1b[39m` : String(s)),
|
|
52
|
+
green: (s: string | number) => (isColorSupported ? `\x1b[32m${s}\x1b[39m` : String(s)),
|
|
53
|
+
yellow: (s: string | number) => (isColorSupported ? `\x1b[33m${s}\x1b[39m` : String(s)),
|
|
54
|
+
red: (s: string | number) => (isColorSupported ? `\x1b[31m${s}\x1b[39m` : String(s)),
|
|
55
|
+
magenta: (s: string | number) => (isColorSupported ? `\x1b[35m${s}\x1b[39m` : String(s)),
|
|
56
|
+
gray: (s: string | number) => (isColorSupported ? `\x1b[90m${s}\x1b[39m` : String(s)),
|
|
57
|
+
bgBlue: (s: string | number) => (isColorSupported ? `\x1b[44m\x1b[37m ${s} \x1b[49m\x1b[39m` : `[${s}]`),
|
|
58
|
+
bgCyan: (s: string | number) => (isColorSupported ? `\x1b[46m\x1b[30m ${s} \x1b[49m\x1b[39m` : `[${s}]`),
|
|
59
|
+
bgGreen: (s: string | number) => (isColorSupported ? `\x1b[42m\x1b[30m ${s} \x1b[49m\x1b[39m` : `[${s}]`),
|
|
60
|
+
bgRed: (s: string | number) => (isColorSupported ? `\x1b[41m\x1b[37m ${s} \x1b[49m\x1b[39m` : `[${s}]`),
|
|
61
|
+
bgMagenta: (s: string | number) => (isColorSupported ? `\x1b[45m\x1b[37m ${s} \x1b[49m\x1b[39m` : `[${s}]`),
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
function formatScore(score: number): string {
|
|
65
|
+
if (score >= 80) return c.green(c.bold(`${score}/100`));
|
|
66
|
+
if (score >= 60) return c.yellow(c.bold(`${score}/100`));
|
|
67
|
+
return c.red(c.bold(`${score}/100`));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function readStdin(): Promise<string> {
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
let data = '';
|
|
73
|
+
const timer = setTimeout(() => {
|
|
74
|
+
process.stdin.pause();
|
|
75
|
+
resolve(data.trim());
|
|
76
|
+
}, 300);
|
|
77
|
+
|
|
78
|
+
process.stdin.setEncoding('utf8');
|
|
79
|
+
process.stdin.on('data', (chunk) => {
|
|
80
|
+
data += chunk;
|
|
81
|
+
});
|
|
82
|
+
process.stdin.on('end', () => {
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
resolve(data.trim());
|
|
85
|
+
});
|
|
86
|
+
process.stdin.on('error', () => {
|
|
87
|
+
clearTimeout(timer);
|
|
88
|
+
resolve(data.trim());
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const args = process.argv.slice(2);
|
|
94
|
+
const command = args[0] || 'help';
|
|
95
|
+
|
|
96
|
+
// Extract target project or path:
|
|
97
|
+
// 1. --project=<id_or_path>
|
|
98
|
+
// 2. positional argument after command (e.g. `devintelligence scan .` or `devintelligence scan /path`)
|
|
99
|
+
// 3. Defaults to current working directory (process.cwd())!
|
|
100
|
+
const explicitProject =
|
|
101
|
+
args.find((a) => a.startsWith('--project='))?.split('=')[1] ||
|
|
102
|
+
args.find((a) => !a.startsWith('-') && a !== command);
|
|
103
|
+
|
|
104
|
+
const projectArg = explicitProject || process.cwd();
|
|
105
|
+
const isCi = args.includes('--ci');
|
|
106
|
+
|
|
107
|
+
async function runCli() {
|
|
108
|
+
switch (command) {
|
|
109
|
+
case 'init': {
|
|
110
|
+
const cwd = process.cwd();
|
|
111
|
+
const projectName = path.basename(cwd);
|
|
112
|
+
console.log(`\n${c.bgCyan(' DEVINTELLIGENCE INITIALIZATION ')}`);
|
|
113
|
+
console.log(`${c.dim('Initializing workspace configuration in:')} ${c.bold(cwd)}`);
|
|
114
|
+
|
|
115
|
+
const report = registerLocalProject({
|
|
116
|
+
name: projectName,
|
|
117
|
+
rootPath: cwd,
|
|
118
|
+
baseWorkspaceDir: rootWorkspaceDir,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
console.log(`\n${c.green(c.bold('✔ [SUCCESS] Project Registered:'))} ${c.bold(report.name)}`);
|
|
122
|
+
console.log(` ${c.cyan('Ecosystem:')} ${report.ecosystem} | ${c.cyan('Framework:')} ${report.launchDoctor.frameworkName}`);
|
|
123
|
+
console.log(` ${c.cyan('Package Manager:')} ${report.launchDoctor.packageManager} | ${c.cyan('Workflow:')} ${report.launchDoctor.workflowType}`);
|
|
124
|
+
console.log(` ${c.cyan('Files Analyzed:')} ${report.filesAnalyzed.length}`);
|
|
125
|
+
console.log(` ${c.cyan('Health Scores:')} Overall ${formatScore(report.scores.overall)} | Quality ${formatScore(report.scores.codeQuality)} | Security ${formatScore(report.scores.security)}`);
|
|
126
|
+
console.log(` ${c.cyan('Issues Found:')} ${report.issues.length} (${report.issues.filter((i) => i.repairTier === 'SAFE').length} SAFE auto-repairable)`);
|
|
127
|
+
console.log(` ${c.cyan('Recommended Launch:')} ${c.bold(report.launchDoctor.recommendedStartCommand)}`);
|
|
128
|
+
console.log(`\nRun ${c.cyan('devintelligence scan')} or ${c.cyan('devintelligence fix')} to inspect and auto-repair.`);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case 'doctor': {
|
|
133
|
+
console.log(`\n${c.bgBlue(' DEVINTELLIGENCE ENVIRONMENT DOCTOR ')}`);
|
|
134
|
+
console.log(`${c.dim('Inspecting Node, Package Managers, React Native, Android & iOS Native Runtimes...\n')}`);
|
|
135
|
+
const checks = inspectHostEnvironment(true);
|
|
136
|
+
for (const ch of checks) {
|
|
137
|
+
let tag = c.green(c.bold('✔ [WORKING] '));
|
|
138
|
+
if (ch.status === 'not_installed') tag = c.red(c.bold('✖ [MISSING] '));
|
|
139
|
+
if (ch.status === 'incompatible') tag = c.red(c.bold('✖ [INCOMPATIBLE] '));
|
|
140
|
+
if (ch.status === 'misconfigured') tag = c.yellow(c.bold('⚠ [MISCONFIGURED]'));
|
|
141
|
+
if (ch.status === 'os_unsupported') tag = c.gray('• [OS UNSUPPORTED]');
|
|
142
|
+
|
|
143
|
+
const nameCol = ch.name.padEnd(30);
|
|
144
|
+
const verCol = ch.detectedVersion || 'Not found';
|
|
145
|
+
console.log(`${tag} ${c.bold(nameCol)} ${verCol} ${c.dim(`(Req: ${ch.requiredVersion})`)}`);
|
|
146
|
+
if (ch.status !== 'working' && ch.remediationCommand) {
|
|
147
|
+
console.log(` ${c.cyan('➜ Fix Command:')} ${c.bold(ch.remediationCommand)}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
case 'scan': {
|
|
154
|
+
const report = getProjectReportById(projectArg, true, rootWorkspaceDir);
|
|
155
|
+
console.log(`\n${c.bgCyan(` DEVINTELLIGENCE SCAN: ${report.name} `)}`);
|
|
156
|
+
console.log(`${c.cyan('Root Path:')} ${c.dim(report.rootPath)}`);
|
|
157
|
+
console.log(`${c.cyan('Ecosystem:')} ${report.ecosystem} | ${c.cyan('Framework:')} ${report.launchDoctor.frameworkName}`);
|
|
158
|
+
console.log(`${c.cyan('Files Analyzed:')} ${report.filesAnalyzed.length} | ${c.cyan('Scan Time:')} ${report.scanDurationMs}ms`);
|
|
159
|
+
|
|
160
|
+
console.log(`\n${c.bold('Scores:')}`);
|
|
161
|
+
console.log(` - Overall Health: ${formatScore(report.scores.overall)}`);
|
|
162
|
+
console.log(` - React Native: ${formatScore(report.scores.reactNative)}`);
|
|
163
|
+
console.log(` - Code Quality: ${formatScore(report.scores.codeQuality)}`);
|
|
164
|
+
console.log(` - Design Tokens: ${formatScore(report.scores.designQuality)}`);
|
|
165
|
+
console.log(` - Performance: ${formatScore(report.scores.performance)}`);
|
|
166
|
+
console.log(` - Security Audit: ${formatScore(report.scores.security)}`);
|
|
167
|
+
|
|
168
|
+
const safeIssues = report.issues.filter((i) => i.repairTier === 'SAFE');
|
|
169
|
+
const reviewIssues = report.issues.filter((i) => i.repairTier === 'REVIEW_REQUIRED');
|
|
170
|
+
const criticalIssues = report.issues.filter((i) => i.severity === 'critical');
|
|
171
|
+
|
|
172
|
+
console.log(`\n${c.bold('Issues Summary:')} ${report.issues.length} detected`);
|
|
173
|
+
console.log(` - Critical: ${criticalIssues.length > 0 ? c.red(c.bold(criticalIssues.length)) : c.green(0)}`);
|
|
174
|
+
console.log(` - SAFE Auto-Fix: ${safeIssues.length > 0 ? c.yellow(c.bold(safeIssues.length)) : 0}`);
|
|
175
|
+
console.log(` - Review Required: ${reviewIssues.length}`);
|
|
176
|
+
|
|
177
|
+
if (report.issues.length > 0) {
|
|
178
|
+
console.log(`\n${c.bold('Top Findings:')}`);
|
|
179
|
+
report.issues.slice(0, 5).forEach((issue, idx) => {
|
|
180
|
+
const sevColor = issue.severity === 'critical' ? c.red : issue.severity === 'high' ? c.yellow : c.cyan;
|
|
181
|
+
console.log(` ${idx + 1}. [${sevColor(issue.severity.toUpperCase())}] ${c.bold(issue.title)}`);
|
|
182
|
+
console.log(` File: ${c.dim(`${issue.filePath}:${issue.line}`)} (${issue.repairTier === 'SAFE' ? c.green('SAFE Auto-Repair') : c.yellow('Review Required')})`);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const gatePass = report.qualityGateEvaluation.passed;
|
|
187
|
+
console.log(`\n${c.bold('Quality Gate:')} ${gatePass ? c.bgGreen(' PASSED ✅ ') : c.bgRed(' FAILED ❌ ')}`);
|
|
188
|
+
if (!gatePass) {
|
|
189
|
+
const failedChecks = (report.qualityGateEvaluation.checks || [])
|
|
190
|
+
.filter((ch) => !ch.passed)
|
|
191
|
+
.map((ch) => `${ch.name} (Actual: ${ch.actual} vs Required: ${ch.threshold})`);
|
|
192
|
+
console.log(` ${c.red('Violations:')} ${failedChecks.join('; ')}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (isCi) {
|
|
196
|
+
process.exit(report.qualityGateEvaluation.exitCode);
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
case 'diagnose': {
|
|
202
|
+
let customLog = '';
|
|
203
|
+
|
|
204
|
+
// 1. Check for --file=<path> or positional string arguments first
|
|
205
|
+
const fileFlag = args.find((a) => a.startsWith('--file='))?.split('=')[1];
|
|
206
|
+
const positionalWords = args.slice(1).filter((a) => !a.startsWith('-'));
|
|
207
|
+
const candidate = fileFlag || (positionalWords.length > 0 ? positionalWords.join(' ') : '');
|
|
208
|
+
|
|
209
|
+
if (candidate) {
|
|
210
|
+
const candidatePath = path.resolve(process.cwd(), candidate);
|
|
211
|
+
if (fs.existsSync(candidatePath) && fs.statSync(candidatePath).isFile()) {
|
|
212
|
+
try {
|
|
213
|
+
customLog = fs.readFileSync(candidatePath, 'utf8');
|
|
214
|
+
console.log(`${c.dim('[Reading error log from file:]')} ${c.bold(candidatePath)}`);
|
|
215
|
+
} catch {}
|
|
216
|
+
} else {
|
|
217
|
+
customLog = candidate;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// 2. Check if input is piped into stdin (only if no arguments were passed)
|
|
222
|
+
if (!customLog && !process.stdin.isTTY) {
|
|
223
|
+
try {
|
|
224
|
+
customLog = await readStdin();
|
|
225
|
+
} catch {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// 3. Auto-detect recent project error logs
|
|
229
|
+
if (!customLog) {
|
|
230
|
+
const commonLogFiles = ['npm-debug.log', 'yarn-error.log', 'metro.log', 'error.log', 'build.log'];
|
|
231
|
+
for (const logFile of commonLogFiles) {
|
|
232
|
+
const fullPath = path.join(process.cwd(), logFile);
|
|
233
|
+
if (fs.existsSync(fullPath)) {
|
|
234
|
+
try {
|
|
235
|
+
const content = fs.readFileSync(fullPath, 'utf8').trim();
|
|
236
|
+
if (content.length > 20) {
|
|
237
|
+
console.log(`${c.cyan(`[Auto-Detected Log File: ${logFile}]`)}`);
|
|
238
|
+
customLog = content;
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
} catch {}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const isPresetDemo = !customLog;
|
|
247
|
+
if (isPresetDemo) {
|
|
248
|
+
customLog = PRESET_ERROR_LOGS[0].rawLog;
|
|
249
|
+
console.log(`\n${c.yellow(c.bold('ℹ [NOTICE]'))} No error trace provided via argument, file, or stdin pipe.`);
|
|
250
|
+
console.log(`${c.dim('To diagnose real errors in your project:')}`);
|
|
251
|
+
console.log(` ${c.cyan('devintelligence diagnose "Error: <your stack trace>"')}`);
|
|
252
|
+
console.log(` ${c.cyan('devintelligence diagnose ./error.log')}`);
|
|
253
|
+
console.log(` ${c.cyan('npm test 2>&1 | devintelligence diagnose')}\n`);
|
|
254
|
+
console.log(`${c.dim('--- Running diagnosis on sample preset error log for demonstration ---')}`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
console.log(`\n${c.bgMagenta(' DEVINTELLIGENCE ERROR DIAGNOSTICS ')}`);
|
|
258
|
+
const apiKey = getGroqApiKey();
|
|
259
|
+
if (!apiKey) {
|
|
260
|
+
console.log(`${c.dim('[AI Engine Note: Set GROQ_API_KEY environment variable to enable Qwen-27B cloud acceleration. Using local zero-downtime heuristic rule engine.]')}\n`);
|
|
261
|
+
} else {
|
|
262
|
+
console.log(`${c.dim('Analyzing error trace with Groq AI (with zero-downtime heuristic shield)...\n')}`);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const diag = await diagnoseRawErrorLogWithAi(customLog);
|
|
266
|
+
|
|
267
|
+
if (diag.aiPowered) {
|
|
268
|
+
console.log(`${c.magenta(c.bold(`[AI-Powered: Groq ${diag.aiModel || 'Qwen 27B'}]`))} Confidence: ${c.bold(`${diag.confidence}%`)}`);
|
|
269
|
+
} else {
|
|
270
|
+
console.log(`${c.blue(c.bold('[Local Rule Engine - Zero Downtime Fallback]'))} Confidence: ${c.bold(`${diag.confidence}%`)}`);
|
|
271
|
+
if (diag.fallbackReason) {
|
|
272
|
+
console.log(`Note: ${c.dim(diag.fallbackReason)}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
console.log(`Category: ${c.bold(diag.category)}`);
|
|
277
|
+
console.log(`Severity: ${diag.severity === 'critical' ? c.red(c.bold('CRITICAL')) : c.yellow(diag.severity.toUpperCase())}`);
|
|
278
|
+
console.log(`Summary: ${c.bold(diag.summary)}`);
|
|
279
|
+
console.log(`Root Cause: ${diag.rootCause}`);
|
|
280
|
+
console.log(`Responsible: ${c.cyan(diag.responsibleFile)}${diag.line ? `:${diag.line}` : ''}`);
|
|
281
|
+
|
|
282
|
+
if (diag.safeRepairSteps?.length) {
|
|
283
|
+
console.log(`\n${c.bold('Recommended Safe Repair Steps:')}`);
|
|
284
|
+
diag.safeRepairSteps.forEach((s, idx) => console.log(` ${idx + 1}. ${s}`));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (diag.terminalCommands?.length) {
|
|
288
|
+
console.log(`\n${c.bold('Exact Terminal Commands:')}`);
|
|
289
|
+
diag.terminalCommands.forEach((cmd) => console.log(` $ ${c.cyan(c.bold(cmd))}`));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (diag.codePatchSuggestion) {
|
|
293
|
+
console.log(`\n${c.bold('Suggested Configuration / Code Patch:')}`);
|
|
294
|
+
console.log(c.dim(diag.codePatchSuggestion));
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
case 'fix': {
|
|
300
|
+
console.log(`\n${c.bgGreen(' DEVINTELLIGENCE AUTO-REPAIR CENTER ')}`);
|
|
301
|
+
console.log(`Applying validated SAFE fixes on project '${c.bold(projectArg)}'...`);
|
|
302
|
+
const res = applyAllSafeRepairsOnDisk(projectArg, rootWorkspaceDir);
|
|
303
|
+
console.log(`\n${c.green(c.bold(`[COMPLETED] Applied ${res.appliedRepairs.length} SAFE repair(s).`))}`);
|
|
304
|
+
res.appliedRepairs.forEach((r, idx) => {
|
|
305
|
+
console.log(` ${idx + 1}. Fixed: ${c.bold(r.issueTitle)}`);
|
|
306
|
+
console.log(` Target: ${c.dim(r.filePath)} (Backup saved in .devintelligence/backups/)`);
|
|
307
|
+
});
|
|
308
|
+
console.log(`\n${c.bold('Post-Repair Re-Scan:')}`);
|
|
309
|
+
console.log(` Overall Score: ${formatScore(res.updatedReport.scores.overall)}`);
|
|
310
|
+
console.log(` Remaining Issues: ${res.updatedReport.issues.length}`);
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
case 'dashboard':
|
|
315
|
+
case 'ui': {
|
|
316
|
+
console.log(`\n${c.bgCyan(' LAUNCHING DEVINTELLIGENCE WORKSTATION ')}`);
|
|
317
|
+
console.log(`Starting local server at ${c.bold('http://localhost:3000')} ...`);
|
|
318
|
+
const serverScript = path.join(rootWorkspaceDir, 'server.ts');
|
|
319
|
+
const child = spawn(process.execPath, [serverScript], {
|
|
320
|
+
cwd: rootWorkspaceDir,
|
|
321
|
+
stdio: 'inherit',
|
|
322
|
+
});
|
|
323
|
+
child.on('error', (err) => {
|
|
324
|
+
console.error('Failed to start workstation server:', err);
|
|
325
|
+
});
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
case 'advice': {
|
|
330
|
+
const report = getProjectReportById(projectArg, false, rootWorkspaceDir);
|
|
331
|
+
console.log(`\nGenerating AI Executive Advice for '${c.bold(report.name)}'...`);
|
|
332
|
+
const res = await generateProjectAiAdvice(report);
|
|
333
|
+
console.log(`\n${c.bgBlue(' DEVINTELLIGENCE EXECUTIVE ADVICE ')}`);
|
|
334
|
+
console.log(res.aiPowered ? c.magenta(`[Powered by Groq AI - ${res.model || 'Qwen 27B'}]`) : c.blue(`[Local Rule Fallback]`));
|
|
335
|
+
console.log(res.advice);
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
case 'ai': {
|
|
340
|
+
const query = args.slice(1).join(' ');
|
|
341
|
+
if (!query) {
|
|
342
|
+
console.log(`Usage: ${c.cyan('devintelligence ai "your question or build error here"')}`);
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
console.log(`\nAsking DEVINTELLIGENCE AI: "${c.bold(query)}"...`);
|
|
346
|
+
const res = await askDevIntelligenceAi(query);
|
|
347
|
+
console.log(`\n${c.bgMagenta(' AI ASSISTANT ANSWER ')}`);
|
|
348
|
+
console.log(res.answer);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
case 'test': {
|
|
353
|
+
console.log(`\n${c.bgCyan(' RUNNING DEVINTELLIGENCE SELF-TESTING SUITE ')}`);
|
|
354
|
+
const child = spawn(process.execPath, ['--test', 'src/engine/analyzerEngine.test.ts', 'src/engine/aiEngine.test.ts'], {
|
|
355
|
+
cwd: rootWorkspaceDir,
|
|
356
|
+
stdio: 'inherit',
|
|
357
|
+
});
|
|
358
|
+
child.on('exit', (code) => {
|
|
359
|
+
process.exit(code ?? 0);
|
|
360
|
+
});
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
case 'report': {
|
|
365
|
+
const report = getProjectReportById(projectArg, false, rootWorkspaceDir);
|
|
366
|
+
console.log(JSON.stringify(report, null, 2));
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
case 'mcp': {
|
|
371
|
+
console.log(
|
|
372
|
+
JSON.stringify(
|
|
373
|
+
{
|
|
374
|
+
status: 'online',
|
|
375
|
+
server: 'DEVINTELLIGENCE Local MCP Server',
|
|
376
|
+
tools: MCP_TOOLS_CATALOG,
|
|
377
|
+
},
|
|
378
|
+
null,
|
|
379
|
+
2
|
|
380
|
+
)
|
|
381
|
+
);
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
default:
|
|
386
|
+
console.log(`
|
|
387
|
+
${c.cyan(c.bold('DEVINTELLIGENCE'))} — Personal Software Engineering Intelligence System
|
|
388
|
+
${c.dim('Understand. Diagnose. Repair. Optimize.')}
|
|
389
|
+
|
|
390
|
+
${c.bold('Usage:')} ${c.cyan('devintelligence <command> [options]')}
|
|
391
|
+
|
|
392
|
+
${c.bold('Commands:')}
|
|
393
|
+
${c.cyan('init')} Register and initialize current directory as a project
|
|
394
|
+
${c.cyan('doctor')} Audit host runtimes (Node, Expo, Android SDK, Gradle, CocoaPods, Xcode)
|
|
395
|
+
${c.cyan('scan')} [path] Deep AST code audit, quality scores & Quality Gate check (default: current dir)
|
|
396
|
+
${c.cyan('diagnose')} [log|file] AI-first error trace diagnosis with guaranteed rule fallback
|
|
397
|
+
${c.cyan('fix')} [path] Apply all validated SAFE auto-repairs on disk with backup
|
|
398
|
+
${c.cyan('dashboard')} Launch desktop engineering workstation on http://localhost:3000
|
|
399
|
+
${c.cyan('advice')} [path] Generate AI executive engineering brief & prioritized action plan
|
|
400
|
+
${c.cyan('ai')} "<question>" Ask AI assistant technical questions about code or native builds
|
|
401
|
+
${c.cyan('report')} [path] Output full machine-readable JSON project report
|
|
402
|
+
${c.cyan('test')} Run multi-ecosystem verification test suite
|
|
403
|
+
${c.cyan('mcp')} Inspect available Model Context Protocol tools
|
|
404
|
+
|
|
405
|
+
${c.bold('Options:')}
|
|
406
|
+
${c.cyan('--project=<path|id>')} Specify target project directory or ID (default: current directory)
|
|
407
|
+
${c.cyan('--file=<path>')} Specify file path to read error log from in diagnose
|
|
408
|
+
${c.cyan('--ci')} Return proper exit code based on Quality Gate (0 for pass, 1 for fail)
|
|
409
|
+
`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
runCli().catch((err) => {
|
|
414
|
+
console.error('Fatal CLI Error:', err);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
});
|
package/dist/App.d.ts
ADDED