devintelligence 1.0.0 → 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 -14
- package/LICENSE +22 -22
- package/README.md +146 -146
- package/bin/devintelligence.js +2481 -12
- package/bin/devintelligence.ts +244 -103
- 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 -4
- package/fixtures/django-analytics-service/settings.py +16 -16
- package/fixtures/express-api-gateway/package.json +14 -14
- package/fixtures/express-api-gateway/src/server.ts +16 -16
- package/fixtures/nextjs-saas-portal/package.json +21 -21
- package/fixtures/nextjs-saas-portal/src/app/dashboard/page.tsx +26 -26
- package/fixtures/rn-bare-fitness/android/build.gradle +19 -19
- package/fixtures/rn-bare-fitness/ios/Info.plist +14 -14
- package/fixtures/rn-bare-fitness/package.json +23 -23
- package/fixtures/rn-bare-fitness/src/WorkoutTracker.tsx +31 -31
- package/fixtures/rn-expo-commerce/android/app/build.gradle +20 -20
- package/fixtures/rn-expo-commerce/android/app/src/main/AndroidManifest.xml +21 -21
- package/fixtures/rn-expo-commerce/android/gradle.properties +6 -6
- package/fixtures/rn-expo-commerce/app.json +17 -17
- package/fixtures/rn-expo-commerce/babel.config.js +10 -10
- package/fixtures/rn-expo-commerce/ios/Podfile +13 -13
- package/fixtures/rn-expo-commerce/metro.config.js +7 -7
- package/fixtures/rn-expo-commerce/package.json +31 -31
- package/fixtures/rn-expo-commerce/src/components/LegacyPromoBanner.tsx +11 -11
- package/fixtures/rn-expo-commerce/src/screens/ProductFeedScreen.tsx +48 -48
- package/fixtures/rn-expo-commerce/src/services/api.ts +15 -15
- package/package.json +89 -77
- package/index.html +0 -21
- package/server.ts +0 -275
- package/src/App.tsx +0 -783
- package/src/components/DeepAnalysisViews.tsx +0 -526
- package/src/components/MobileAndPlatformViews.tsx +0 -625
- package/src/components/OverviewAndExplorerViews.tsx +0 -753
- package/src/components/RepairAndGateViews.tsx +0 -814
- package/src/engine/aiEngine.test.ts +0 -86
- package/src/engine/aiEngine.ts +0 -346
- package/src/engine/analyzerEngine.test.ts +0 -110
- package/src/engine/analyzerEngine.ts +0 -1579
- package/src/engine/repairEngine.ts +0 -545
- package/src/index.css +0 -44
- package/src/index.ts +0 -59
- package/src/main.tsx +0 -5
- package/src/types/devintelligence.ts +0 -310
- package/tsconfig.json +0 -28
- package/vite.config.ts +0 -22
package/src/App.tsx
DELETED
|
@@ -1,783 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
LayoutDashboard,
|
|
4
|
-
FolderSearch,
|
|
5
|
-
Activity,
|
|
6
|
-
Smartphone,
|
|
7
|
-
Cpu,
|
|
8
|
-
Layers,
|
|
9
|
-
Code2,
|
|
10
|
-
Palette,
|
|
11
|
-
Gauge,
|
|
12
|
-
ShieldAlert,
|
|
13
|
-
PackageCheck,
|
|
14
|
-
Bug,
|
|
15
|
-
Wrench,
|
|
16
|
-
Eye,
|
|
17
|
-
CheckSquare,
|
|
18
|
-
History,
|
|
19
|
-
Server,
|
|
20
|
-
Settings,
|
|
21
|
-
RefreshCw,
|
|
22
|
-
Menu,
|
|
23
|
-
X,
|
|
24
|
-
} from 'lucide-react';
|
|
25
|
-
import {
|
|
26
|
-
DashboardModuleId,
|
|
27
|
-
EnvironmentCheckItem,
|
|
28
|
-
ErrorDiagnosisResult,
|
|
29
|
-
ProjectIntelligenceReport,
|
|
30
|
-
QualityGateConfig,
|
|
31
|
-
} from './types/devintelligence.ts';
|
|
32
|
-
import {
|
|
33
|
-
CommandCenterView,
|
|
34
|
-
ProjectExplorerView,
|
|
35
|
-
ProjectHealthView,
|
|
36
|
-
} from './components/OverviewAndExplorerViews.tsx';
|
|
37
|
-
import {
|
|
38
|
-
ReactNativeDoctorView,
|
|
39
|
-
AndroidDiagnosticsView,
|
|
40
|
-
IosDiagnosticsView,
|
|
41
|
-
ErrorDiagnosticsView,
|
|
42
|
-
} from './components/MobileAndPlatformViews.tsx';
|
|
43
|
-
import {
|
|
44
|
-
CodeIntelligenceView,
|
|
45
|
-
DesignIntelligenceView,
|
|
46
|
-
PerformanceLabView,
|
|
47
|
-
SecurityAuditView,
|
|
48
|
-
DependencyIntelligenceView,
|
|
49
|
-
} from './components/DeepAnalysisViews.tsx';
|
|
50
|
-
import {
|
|
51
|
-
AutoRepairCenterView,
|
|
52
|
-
VisualTestingView,
|
|
53
|
-
QualityGateView,
|
|
54
|
-
ProjectHistoryView,
|
|
55
|
-
EnvironmentManagerView,
|
|
56
|
-
SettingsAndMcpView,
|
|
57
|
-
} from './components/RepairAndGateViews.tsx';
|
|
58
|
-
|
|
59
|
-
interface NavItem {
|
|
60
|
-
id: DashboardModuleId;
|
|
61
|
-
label: string;
|
|
62
|
-
group: 'Core' | 'Mobile & Native' | 'Deep Analysis' | 'Repair & Delivery';
|
|
63
|
-
icon: React.ComponentType<{ className?: string }>;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const NAVIGATION_MODULES: NavItem[] = [
|
|
67
|
-
{ id: 'command-center', label: 'Command Center', group: 'Core', icon: LayoutDashboard },
|
|
68
|
-
{ id: 'project-explorer', label: 'Project Explorer', group: 'Core', icon: FolderSearch },
|
|
69
|
-
{ id: 'project-health', label: 'Project Health', group: 'Core', icon: Activity },
|
|
70
|
-
{ id: 'rn-doctor', label: 'React Native Doctor', group: 'Mobile & Native', icon: Smartphone },
|
|
71
|
-
{ id: 'android-diagnostics', label: 'Android Diagnostics', group: 'Mobile & Native', icon: Cpu },
|
|
72
|
-
{ id: 'ios-diagnostics', label: 'iOS Diagnostics', group: 'Mobile & Native', icon: Layers },
|
|
73
|
-
{ id: 'code-intelligence', label: 'Code Intelligence', group: 'Deep Analysis', icon: Code2 },
|
|
74
|
-
{ id: 'design-intelligence', label: 'Design Intelligence', group: 'Deep Analysis', icon: Palette },
|
|
75
|
-
{ id: 'performance-lab', label: 'Performance Lab', group: 'Deep Analysis', icon: Gauge },
|
|
76
|
-
{ id: 'security-audit', label: 'Security Audit', group: 'Deep Analysis', icon: ShieldAlert },
|
|
77
|
-
{ id: 'dependency-intelligence', label: 'Dependency Intelligence', group: 'Deep Analysis', icon: PackageCheck },
|
|
78
|
-
{ id: 'error-diagnostics', label: 'Error Diagnostics', group: 'Repair & Delivery', icon: Bug },
|
|
79
|
-
{ id: 'auto-repair', label: 'Auto Repair Center', group: 'Repair & Delivery', icon: Wrench },
|
|
80
|
-
{ id: 'visual-testing', label: 'Visual Testing', group: 'Repair & Delivery', icon: Eye },
|
|
81
|
-
{ id: 'quality-gate', label: 'Quality Gate', group: 'Repair & Delivery', icon: CheckSquare },
|
|
82
|
-
{ id: 'project-history', label: 'Project History', group: 'Repair & Delivery', icon: History },
|
|
83
|
-
{ id: 'environment-manager', label: 'Environment Manager', group: 'Repair & Delivery', icon: Server },
|
|
84
|
-
{ id: 'settings', label: 'Settings', group: 'Repair & Delivery', icon: Settings },
|
|
85
|
-
];
|
|
86
|
-
|
|
87
|
-
export function App() {
|
|
88
|
-
const [projects, setProjects] = useState<ProjectIntelligenceReport[]>([]);
|
|
89
|
-
const [selectedProjectId, setSelectedProjectId] = useState<string>('rn-expo-commerce');
|
|
90
|
-
const [activeModule, setActiveModule] = useState<DashboardModuleId>('command-center');
|
|
91
|
-
const [environmentChecks, setEnvironmentChecks] = useState<EnvironmentCheckItem[]>([]);
|
|
92
|
-
const [mcpTools, setMcpTools] = useState<
|
|
93
|
-
{ name: string; description: string; parameters: string[] }[]
|
|
94
|
-
>([]);
|
|
95
|
-
const [presetErrorLogs, setPresetErrorLogs] = useState<
|
|
96
|
-
{ id: string; label: string; ecosystem: string; rawLog: string }[]
|
|
97
|
-
>([]);
|
|
98
|
-
const [loading, setLoading] = useState<boolean>(true);
|
|
99
|
-
const [isBusy, setIsBusy] = useState<boolean>(false);
|
|
100
|
-
const [statusMessage, setStatusMessage] = useState<string | null>(null);
|
|
101
|
-
const [mobileNavOpen, setMobileNavOpen] = useState<boolean>(false);
|
|
102
|
-
|
|
103
|
-
const loadWorkspace = useCallback(async () => {
|
|
104
|
-
try {
|
|
105
|
-
const res = await fetch('/api/devintel/workspace');
|
|
106
|
-
const data = await res.json();
|
|
107
|
-
if (Array.isArray(data.projects)) {
|
|
108
|
-
setProjects(data.projects);
|
|
109
|
-
}
|
|
110
|
-
if (Array.isArray(data.environmentChecks)) {
|
|
111
|
-
setEnvironmentChecks(data.environmentChecks);
|
|
112
|
-
}
|
|
113
|
-
if (Array.isArray(data.mcpTools)) {
|
|
114
|
-
setMcpTools(data.mcpTools);
|
|
115
|
-
}
|
|
116
|
-
if (Array.isArray(data.presetErrorLogs)) {
|
|
117
|
-
setPresetErrorLogs(data.presetErrorLogs);
|
|
118
|
-
}
|
|
119
|
-
} catch (err) {
|
|
120
|
-
console.error('Failed to load DEVINTELLIGENCE workspace:', err);
|
|
121
|
-
} finally {
|
|
122
|
-
setLoading(false);
|
|
123
|
-
}
|
|
124
|
-
}, []);
|
|
125
|
-
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
loadWorkspace();
|
|
128
|
-
}, [loadWorkspace]);
|
|
129
|
-
|
|
130
|
-
const activeReport =
|
|
131
|
-
projects.find((p) => p.id === selectedProjectId) || projects[0] || null;
|
|
132
|
-
|
|
133
|
-
async function handleRunScan() {
|
|
134
|
-
if (!activeReport) return;
|
|
135
|
-
setIsBusy(true);
|
|
136
|
-
setStatusMessage(`Scanning ${activeReport.name}...`);
|
|
137
|
-
try {
|
|
138
|
-
const res = await fetch(`/api/devintel/projects/${activeReport.id}/scan`, {
|
|
139
|
-
method: 'POST',
|
|
140
|
-
});
|
|
141
|
-
const data = await res.json();
|
|
142
|
-
if (Array.isArray(data.projects)) {
|
|
143
|
-
setProjects(data.projects);
|
|
144
|
-
}
|
|
145
|
-
setStatusMessage(
|
|
146
|
-
`Scan completed in ${data.report?.scanDurationMs || 15}ms — ${data.report?.issues?.length ?? 0} findings verified.`
|
|
147
|
-
);
|
|
148
|
-
} finally {
|
|
149
|
-
setIsBusy(false);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async function handleFixIssue(issueId: string, allowReview = false) {
|
|
154
|
-
if (!activeReport) return;
|
|
155
|
-
setIsBusy(true);
|
|
156
|
-
setStatusMessage('Creating backup snapshot and applying repair...');
|
|
157
|
-
try {
|
|
158
|
-
const res = await fetch(`/api/devintel/projects/${activeReport.id}/repair`, {
|
|
159
|
-
method: 'POST',
|
|
160
|
-
headers: { 'Content-Type': 'application/json' },
|
|
161
|
-
body: JSON.stringify({ issueId, allowReviewTier: allowReview }),
|
|
162
|
-
});
|
|
163
|
-
const data = await res.json();
|
|
164
|
-
if (!res.ok) {
|
|
165
|
-
setStatusMessage(`Repair blocked: ${data.error}`);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (Array.isArray(data.projects)) {
|
|
169
|
-
setProjects(data.projects);
|
|
170
|
-
}
|
|
171
|
-
setStatusMessage(
|
|
172
|
-
`Repaired "${data.repairRecord.issueTitle}" and verified fix via re-scan.`
|
|
173
|
-
);
|
|
174
|
-
} finally {
|
|
175
|
-
setIsBusy(false);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async function handleFixAllSafe() {
|
|
180
|
-
if (!activeReport) return;
|
|
181
|
-
setIsBusy(true);
|
|
182
|
-
setStatusMessage('Applying all SAFE repairs with automatic disk backups...');
|
|
183
|
-
try {
|
|
184
|
-
const res = await fetch(
|
|
185
|
-
`/api/devintel/projects/${activeReport.id}/repair-all-safe`,
|
|
186
|
-
{ method: 'POST' }
|
|
187
|
-
);
|
|
188
|
-
const data = await res.json();
|
|
189
|
-
if (Array.isArray(data.projects)) {
|
|
190
|
-
setProjects(data.projects);
|
|
191
|
-
}
|
|
192
|
-
setStatusMessage(
|
|
193
|
-
`Applied ${data.appliedRepairs?.length || 0} SAFE repair(s) and verified on disk.`
|
|
194
|
-
);
|
|
195
|
-
} finally {
|
|
196
|
-
setIsBusy(false);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async function handleRollbackRepair(repairId: string) {
|
|
201
|
-
if (!activeReport) return;
|
|
202
|
-
setIsBusy(true);
|
|
203
|
-
setStatusMessage('Restoring original file from backup snapshot...');
|
|
204
|
-
try {
|
|
205
|
-
const res = await fetch(`/api/devintel/projects/${activeReport.id}/rollback`, {
|
|
206
|
-
method: 'POST',
|
|
207
|
-
headers: { 'Content-Type': 'application/json' },
|
|
208
|
-
body: JSON.stringify({ repairId }),
|
|
209
|
-
});
|
|
210
|
-
const data = await res.json();
|
|
211
|
-
if (Array.isArray(data.projects)) {
|
|
212
|
-
setProjects(data.projects);
|
|
213
|
-
}
|
|
214
|
-
setStatusMessage(
|
|
215
|
-
`Rolled back "${data.restoredRecord?.issueTitle}" and restored original file.`
|
|
216
|
-
);
|
|
217
|
-
} finally {
|
|
218
|
-
setIsBusy(false);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async function handleRegisterProject(name: string, rootPath: string) {
|
|
223
|
-
setIsBusy(true);
|
|
224
|
-
try {
|
|
225
|
-
const res = await fetch('/api/devintel/projects/register', {
|
|
226
|
-
method: 'POST',
|
|
227
|
-
headers: { 'Content-Type': 'application/json' },
|
|
228
|
-
body: JSON.stringify({ name, rootPath }),
|
|
229
|
-
});
|
|
230
|
-
const data = await res.json();
|
|
231
|
-
if (!res.ok) {
|
|
232
|
-
throw new Error(data.error || 'Failed to register project');
|
|
233
|
-
}
|
|
234
|
-
if (Array.isArray(data.projects)) {
|
|
235
|
-
setProjects(data.projects);
|
|
236
|
-
}
|
|
237
|
-
if (data.report?.id) {
|
|
238
|
-
setSelectedProjectId(data.report.id);
|
|
239
|
-
}
|
|
240
|
-
setStatusMessage(`Registered and scanned "${name}" (${data.report?.filesAnalyzed?.length || 0} files).`);
|
|
241
|
-
} finally {
|
|
242
|
-
setIsBusy(false);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async function handleUpdateQualityGate(cfg: Partial<QualityGateConfig>) {
|
|
247
|
-
if (!activeReport) return;
|
|
248
|
-
setIsBusy(true);
|
|
249
|
-
try {
|
|
250
|
-
const res = await fetch(
|
|
251
|
-
`/api/devintel/projects/${activeReport.id}/quality-gate`,
|
|
252
|
-
{
|
|
253
|
-
method: 'PUT',
|
|
254
|
-
headers: { 'Content-Type': 'application/json' },
|
|
255
|
-
body: JSON.stringify(cfg),
|
|
256
|
-
}
|
|
257
|
-
);
|
|
258
|
-
const data = await res.json();
|
|
259
|
-
if (Array.isArray(data.projects)) {
|
|
260
|
-
setProjects(data.projects);
|
|
261
|
-
}
|
|
262
|
-
setStatusMessage(
|
|
263
|
-
`Updated Quality Gate thresholds — Status: ${data.updatedReport?.qualityGateEvaluation?.passed ? 'PASSING' : 'FAILING'}`
|
|
264
|
-
);
|
|
265
|
-
} finally {
|
|
266
|
-
setIsBusy(false);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
async function handleDiagnoseLog(rawLog: string): Promise<ErrorDiagnosisResult> {
|
|
271
|
-
const res = await fetch('/api/devintel/diagnose-log', {
|
|
272
|
-
method: 'POST',
|
|
273
|
-
headers: { 'Content-Type': 'application/json' },
|
|
274
|
-
body: JSON.stringify({ rawLog }),
|
|
275
|
-
});
|
|
276
|
-
return res.json();
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
async function handleRefreshEnvironment() {
|
|
280
|
-
setIsBusy(true);
|
|
281
|
-
try {
|
|
282
|
-
const res = await fetch('/api/devintel/environment/refresh', {
|
|
283
|
-
method: 'POST',
|
|
284
|
-
});
|
|
285
|
-
const data = await res.json();
|
|
286
|
-
if (Array.isArray(data.environmentChecks)) {
|
|
287
|
-
setEnvironmentChecks(data.environmentChecks);
|
|
288
|
-
}
|
|
289
|
-
setStatusMessage('Re-probed host operating system and developer binaries.');
|
|
290
|
-
} finally {
|
|
291
|
-
setIsBusy(false);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
async function handleCallMcpTool(
|
|
296
|
-
toolName: string,
|
|
297
|
-
args: Record<string, string>
|
|
298
|
-
): Promise<unknown> {
|
|
299
|
-
const res = await fetch('/api/devintel/mcp/call', {
|
|
300
|
-
method: 'POST',
|
|
301
|
-
headers: { 'Content-Type': 'application/json' },
|
|
302
|
-
body: JSON.stringify({ toolName, args }),
|
|
303
|
-
});
|
|
304
|
-
const data = await res.json();
|
|
305
|
-
if (Array.isArray(data.projects)) {
|
|
306
|
-
setProjects(data.projects);
|
|
307
|
-
}
|
|
308
|
-
return data.output;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (loading || !activeReport) {
|
|
312
|
-
return (
|
|
313
|
-
<div className="min-h-screen bg-[#090D16] text-slate-100 flex items-center justify-center p-6">
|
|
314
|
-
<div className="text-center space-y-2">
|
|
315
|
-
<div className="text-sm font-semibold tracking-wide text-slate-200">
|
|
316
|
-
DEVINTELLIGENCE
|
|
317
|
-
</div>
|
|
318
|
-
<div className="text-xs text-slate-400 font-mono">
|
|
319
|
-
Initializing local engineering intelligence engines...
|
|
320
|
-
</div>
|
|
321
|
-
</div>
|
|
322
|
-
</div>
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const groups = ['Core', 'Mobile & Native', 'Deep Analysis', 'Repair & Delivery'] as const;
|
|
327
|
-
|
|
328
|
-
return (
|
|
329
|
-
<div className="min-h-screen bg-[#090D16] text-slate-100 flex flex-col">
|
|
330
|
-
{/* Top Bar Contract: 3 Zones Separated by gap-8 */}
|
|
331
|
-
<header className="flex items-center justify-between gap-8 px-6 py-3.5 bg-[#090D16] border-b border-slate-800/90 sticky top-0 z-30">
|
|
332
|
-
{/* Zone 1: Single text element wordmark */}
|
|
333
|
-
<a
|
|
334
|
-
href="#top"
|
|
335
|
-
onClick={(e) => {
|
|
336
|
-
e.preventDefault();
|
|
337
|
-
setActiveModule('command-center');
|
|
338
|
-
}}
|
|
339
|
-
className="text-base font-bold tracking-tight text-slate-100 whitespace-nowrap shrink-0"
|
|
340
|
-
>
|
|
341
|
-
DEVINTELLIGENCE
|
|
342
|
-
</a>
|
|
343
|
-
|
|
344
|
-
{/* Zone 2: 5 concise single-line text navigation links */}
|
|
345
|
-
<nav
|
|
346
|
-
aria-label="Primary Shortcuts"
|
|
347
|
-
className="hidden md:flex items-center gap-6 text-xs font-medium text-slate-400"
|
|
348
|
-
>
|
|
349
|
-
<a
|
|
350
|
-
href="#command-center"
|
|
351
|
-
onClick={(e) => {
|
|
352
|
-
e.preventDefault();
|
|
353
|
-
setActiveModule('command-center');
|
|
354
|
-
}}
|
|
355
|
-
className={`hover:text-slate-100 hover:underline underline-offset-4 transition-colors whitespace-nowrap shrink-0 ${
|
|
356
|
-
activeModule === 'command-center' ? 'text-slate-100' : ''
|
|
357
|
-
}`}
|
|
358
|
-
>
|
|
359
|
-
Command Center
|
|
360
|
-
</a>
|
|
361
|
-
<a
|
|
362
|
-
href="#rn-doctor"
|
|
363
|
-
onClick={(e) => {
|
|
364
|
-
e.preventDefault();
|
|
365
|
-
setActiveModule('rn-doctor');
|
|
366
|
-
}}
|
|
367
|
-
className={`hover:text-slate-100 hover:underline underline-offset-4 transition-colors whitespace-nowrap shrink-0 ${
|
|
368
|
-
activeModule === 'rn-doctor' ? 'text-slate-100' : ''
|
|
369
|
-
}`}
|
|
370
|
-
>
|
|
371
|
-
React Native Doctor
|
|
372
|
-
</a>
|
|
373
|
-
<a
|
|
374
|
-
href="#auto-repair"
|
|
375
|
-
onClick={(e) => {
|
|
376
|
-
e.preventDefault();
|
|
377
|
-
setActiveModule('auto-repair');
|
|
378
|
-
}}
|
|
379
|
-
className={`hover:text-slate-100 hover:underline underline-offset-4 transition-colors whitespace-nowrap shrink-0 ${
|
|
380
|
-
activeModule === 'auto-repair' ? 'text-slate-100' : ''
|
|
381
|
-
}`}
|
|
382
|
-
>
|
|
383
|
-
Auto Repair Center
|
|
384
|
-
</a>
|
|
385
|
-
<a
|
|
386
|
-
href="#error-diagnostics"
|
|
387
|
-
onClick={(e) => {
|
|
388
|
-
e.preventDefault();
|
|
389
|
-
setActiveModule('error-diagnostics');
|
|
390
|
-
}}
|
|
391
|
-
className={`hover:text-slate-100 hover:underline underline-offset-4 transition-colors whitespace-nowrap shrink-0 ${
|
|
392
|
-
activeModule === 'error-diagnostics' ? 'text-slate-100' : ''
|
|
393
|
-
}`}
|
|
394
|
-
>
|
|
395
|
-
Error Diagnostics
|
|
396
|
-
</a>
|
|
397
|
-
<a
|
|
398
|
-
href="#quality-gate"
|
|
399
|
-
onClick={(e) => {
|
|
400
|
-
e.preventDefault();
|
|
401
|
-
setActiveModule('quality-gate');
|
|
402
|
-
}}
|
|
403
|
-
className={`hover:text-slate-100 hover:underline underline-offset-4 transition-colors whitespace-nowrap shrink-0 ${
|
|
404
|
-
activeModule === 'quality-gate' ? 'text-slate-100' : ''
|
|
405
|
-
}`}
|
|
406
|
-
>
|
|
407
|
-
Quality Gate
|
|
408
|
-
</a>
|
|
409
|
-
</nav>
|
|
410
|
-
|
|
411
|
-
{/* Zone 3: 1 Primary Action */}
|
|
412
|
-
<div className="flex items-center gap-3 shrink-0">
|
|
413
|
-
<button
|
|
414
|
-
type="button"
|
|
415
|
-
disabled={isBusy}
|
|
416
|
-
onClick={handleRunScan}
|
|
417
|
-
className="px-4 py-2 text-xs font-semibold text-white bg-blue-600 hover:bg-blue-500 disabled:opacity-50 rounded-lg transition-colors whitespace-nowrap shrink-0 cursor-pointer"
|
|
418
|
-
>
|
|
419
|
-
{isBusy ? 'Scanning...' : 'Run Deep Scan'}
|
|
420
|
-
</button>
|
|
421
|
-
</div>
|
|
422
|
-
</header>
|
|
423
|
-
|
|
424
|
-
{/* Main Workstation Layout: Sidebar + Content Viewport */}
|
|
425
|
-
<div className="flex-1 flex min-h-0">
|
|
426
|
-
{/* Sidebar Navigation (Desktop 256px) */}
|
|
427
|
-
<aside
|
|
428
|
-
aria-label="Workstation Modules"
|
|
429
|
-
className="hidden lg:flex lg:flex-col w-64 shrink-0 bg-[#0B101B] border-r border-slate-800/80 py-5 px-3 space-y-6 overflow-y-auto"
|
|
430
|
-
>
|
|
431
|
-
<div className="px-3 space-y-1.5">
|
|
432
|
-
<label
|
|
433
|
-
htmlFor="sidebar-project-select"
|
|
434
|
-
className="block text-[11px] font-medium text-slate-400"
|
|
435
|
-
>
|
|
436
|
-
Active Local Project
|
|
437
|
-
</label>
|
|
438
|
-
<select
|
|
439
|
-
id="sidebar-project-select"
|
|
440
|
-
value={activeReport.id}
|
|
441
|
-
onChange={(e) => setSelectedProjectId(e.target.value)}
|
|
442
|
-
className="w-full px-2.5 py-2 text-xs font-medium bg-slate-900 border border-slate-800 rounded-md text-slate-100 focus:outline-none focus:border-blue-500"
|
|
443
|
-
>
|
|
444
|
-
{projects.map((p) => (
|
|
445
|
-
<option key={p.id} value={p.id}>
|
|
446
|
-
{p.name}
|
|
447
|
-
</option>
|
|
448
|
-
))}
|
|
449
|
-
</select>
|
|
450
|
-
<div className="text-[11px] text-slate-500 font-mono pt-0.5">
|
|
451
|
-
Understand. Diagnose. Repair. Optimize.
|
|
452
|
-
</div>
|
|
453
|
-
</div>
|
|
454
|
-
|
|
455
|
-
{groups.map((grp) => (
|
|
456
|
-
<div key={grp} className="space-y-1">
|
|
457
|
-
<div className="px-3 text-[11px] font-medium text-slate-500">
|
|
458
|
-
{grp}
|
|
459
|
-
</div>
|
|
460
|
-
{NAVIGATION_MODULES.filter((m) => m.group === grp).map((mod) => {
|
|
461
|
-
const Icon = mod.icon;
|
|
462
|
-
const isActive = activeModule === mod.id;
|
|
463
|
-
return (
|
|
464
|
-
<button
|
|
465
|
-
key={mod.id}
|
|
466
|
-
type="button"
|
|
467
|
-
onClick={() => setActiveModule(mod.id)}
|
|
468
|
-
className={`w-full flex items-center gap-2.5 px-3 py-2 rounded-md text-xs font-medium transition-colors cursor-pointer whitespace-nowrap ${
|
|
469
|
-
isActive
|
|
470
|
-
? 'bg-blue-600/15 text-blue-400'
|
|
471
|
-
: 'text-slate-400 hover:text-slate-100 hover:bg-slate-800/50'
|
|
472
|
-
}`}
|
|
473
|
-
>
|
|
474
|
-
<Icon className="w-4 h-4 shrink-0" />
|
|
475
|
-
<span className="truncate">{mod.label}</span>
|
|
476
|
-
</button>
|
|
477
|
-
);
|
|
478
|
-
})}
|
|
479
|
-
</div>
|
|
480
|
-
))}
|
|
481
|
-
</aside>
|
|
482
|
-
|
|
483
|
-
{/* Main Workspace Content Area */}
|
|
484
|
-
<div className="flex-1 flex flex-col min-w-0">
|
|
485
|
-
{/* Contextual Sub-Toolbar for Mobile Navigation & Active Project Context */}
|
|
486
|
-
<div className="px-6 py-3 bg-[#0B101B] border-b border-slate-800/80 flex flex-wrap items-center justify-between gap-3">
|
|
487
|
-
<div className="flex items-center gap-3">
|
|
488
|
-
<button
|
|
489
|
-
type="button"
|
|
490
|
-
aria-label="Toggle Modules Menu"
|
|
491
|
-
onClick={() => setMobileNavOpen(!mobileNavOpen)}
|
|
492
|
-
className="lg:hidden inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-slate-200 bg-slate-900 border border-slate-800 rounded"
|
|
493
|
-
>
|
|
494
|
-
{mobileNavOpen ? <X className="w-4 h-4" /> : <Menu className="w-4 h-4" />}
|
|
495
|
-
<span>Modules</span>
|
|
496
|
-
</button>
|
|
497
|
-
|
|
498
|
-
<div className="text-xs text-slate-400 font-mono">
|
|
499
|
-
<span className="text-slate-300 font-semibold">
|
|
500
|
-
{NAVIGATION_MODULES.find((m) => m.id === activeModule)?.label}
|
|
501
|
-
</span>
|
|
502
|
-
<span className="mx-2 text-slate-600">/</span>
|
|
503
|
-
<span>{activeReport.id}</span>
|
|
504
|
-
</div>
|
|
505
|
-
</div>
|
|
506
|
-
|
|
507
|
-
<div className="flex items-center gap-3 min-w-0">
|
|
508
|
-
{statusMessage && (
|
|
509
|
-
<div
|
|
510
|
-
role="status"
|
|
511
|
-
className="text-xs text-blue-300 font-mono truncate max-w-[240px] sm:max-w-md"
|
|
512
|
-
>
|
|
513
|
-
{statusMessage}
|
|
514
|
-
</div>
|
|
515
|
-
)}
|
|
516
|
-
<div className="lg:hidden">
|
|
517
|
-
<label htmlFor="mobile-project-select" className="sr-only">
|
|
518
|
-
Select Active Project
|
|
519
|
-
</label>
|
|
520
|
-
<select
|
|
521
|
-
id="mobile-project-select"
|
|
522
|
-
value={activeReport.id}
|
|
523
|
-
onChange={(e) => setSelectedProjectId(e.target.value)}
|
|
524
|
-
className="px-2.5 py-1.5 text-xs bg-slate-900 border border-slate-800 rounded text-slate-100"
|
|
525
|
-
>
|
|
526
|
-
{projects.map((p) => (
|
|
527
|
-
<option key={p.id} value={p.id}>
|
|
528
|
-
{p.name}
|
|
529
|
-
</option>
|
|
530
|
-
))}
|
|
531
|
-
</select>
|
|
532
|
-
</div>
|
|
533
|
-
</div>
|
|
534
|
-
</div>
|
|
535
|
-
|
|
536
|
-
{/* Mobile Drawer Navigation */}
|
|
537
|
-
{mobileNavOpen && (
|
|
538
|
-
<div className="lg:hidden bg-slate-900 border-b border-slate-800 p-4 grid grid-cols-2 sm:grid-cols-3 gap-2">
|
|
539
|
-
{NAVIGATION_MODULES.map((mod) => {
|
|
540
|
-
const Icon = mod.icon;
|
|
541
|
-
return (
|
|
542
|
-
<button
|
|
543
|
-
key={mod.id}
|
|
544
|
-
type="button"
|
|
545
|
-
onClick={() => {
|
|
546
|
-
setActiveModule(mod.id);
|
|
547
|
-
setMobileNavOpen(false);
|
|
548
|
-
}}
|
|
549
|
-
className={`flex items-center gap-2 px-3 py-2 rounded text-xs font-medium text-left ${
|
|
550
|
-
activeModule === mod.id
|
|
551
|
-
? 'bg-blue-600 text-white'
|
|
552
|
-
: 'text-slate-300 hover:bg-slate-800'
|
|
553
|
-
}`}
|
|
554
|
-
>
|
|
555
|
-
<Icon className="w-3.5 h-3.5 shrink-0" />
|
|
556
|
-
<span className="truncate">{mod.label}</span>
|
|
557
|
-
</button>
|
|
558
|
-
);
|
|
559
|
-
})}
|
|
560
|
-
</div>
|
|
561
|
-
)}
|
|
562
|
-
|
|
563
|
-
{/* Active Module Viewport */}
|
|
564
|
-
<main className="flex-1 p-6 lg:p-8 max-w-7xl w-full mx-auto">
|
|
565
|
-
{activeModule === 'command-center' && (
|
|
566
|
-
<CommandCenterView
|
|
567
|
-
report={activeReport}
|
|
568
|
-
allProjects={projects}
|
|
569
|
-
onSelectProject={setSelectedProjectId}
|
|
570
|
-
onNavigateModule={setActiveModule}
|
|
571
|
-
onRunScan={handleRunScan}
|
|
572
|
-
onFixAllSafe={handleFixAllSafe}
|
|
573
|
-
onFixIssue={handleFixIssue}
|
|
574
|
-
onRegisterProject={handleRegisterProject}
|
|
575
|
-
isBusy={isBusy}
|
|
576
|
-
/>
|
|
577
|
-
)}
|
|
578
|
-
|
|
579
|
-
{activeModule === 'project-explorer' && (
|
|
580
|
-
<ProjectExplorerView
|
|
581
|
-
report={activeReport}
|
|
582
|
-
allProjects={projects}
|
|
583
|
-
onSelectProject={setSelectedProjectId}
|
|
584
|
-
onNavigateModule={setActiveModule}
|
|
585
|
-
onRunScan={handleRunScan}
|
|
586
|
-
onFixAllSafe={handleFixAllSafe}
|
|
587
|
-
onFixIssue={handleFixIssue}
|
|
588
|
-
onRegisterProject={handleRegisterProject}
|
|
589
|
-
isBusy={isBusy}
|
|
590
|
-
/>
|
|
591
|
-
)}
|
|
592
|
-
|
|
593
|
-
{activeModule === 'project-health' && (
|
|
594
|
-
<ProjectHealthView
|
|
595
|
-
report={activeReport}
|
|
596
|
-
allProjects={projects}
|
|
597
|
-
onSelectProject={setSelectedProjectId}
|
|
598
|
-
onNavigateModule={setActiveModule}
|
|
599
|
-
onRunScan={handleRunScan}
|
|
600
|
-
onFixAllSafe={handleFixAllSafe}
|
|
601
|
-
onFixIssue={handleFixIssue}
|
|
602
|
-
onRegisterProject={handleRegisterProject}
|
|
603
|
-
isBusy={isBusy}
|
|
604
|
-
/>
|
|
605
|
-
)}
|
|
606
|
-
|
|
607
|
-
{activeModule === 'rn-doctor' && (
|
|
608
|
-
<ReactNativeDoctorView
|
|
609
|
-
report={activeReport}
|
|
610
|
-
onFixIssue={handleFixIssue}
|
|
611
|
-
presetErrorLogs={presetErrorLogs}
|
|
612
|
-
onDiagnoseLog={handleDiagnoseLog}
|
|
613
|
-
isBusy={isBusy}
|
|
614
|
-
/>
|
|
615
|
-
)}
|
|
616
|
-
|
|
617
|
-
{activeModule === 'android-diagnostics' && (
|
|
618
|
-
<AndroidDiagnosticsView
|
|
619
|
-
report={activeReport}
|
|
620
|
-
onFixIssue={handleFixIssue}
|
|
621
|
-
presetErrorLogs={presetErrorLogs}
|
|
622
|
-
onDiagnoseLog={handleDiagnoseLog}
|
|
623
|
-
isBusy={isBusy}
|
|
624
|
-
/>
|
|
625
|
-
)}
|
|
626
|
-
|
|
627
|
-
{activeModule === 'ios-diagnostics' && (
|
|
628
|
-
<IosDiagnosticsView
|
|
629
|
-
report={activeReport}
|
|
630
|
-
onFixIssue={handleFixIssue}
|
|
631
|
-
presetErrorLogs={presetErrorLogs}
|
|
632
|
-
onDiagnoseLog={handleDiagnoseLog}
|
|
633
|
-
isBusy={isBusy}
|
|
634
|
-
/>
|
|
635
|
-
)}
|
|
636
|
-
|
|
637
|
-
{activeModule === 'code-intelligence' && (
|
|
638
|
-
<CodeIntelligenceView
|
|
639
|
-
report={activeReport}
|
|
640
|
-
onFixIssue={handleFixIssue}
|
|
641
|
-
isBusy={isBusy}
|
|
642
|
-
/>
|
|
643
|
-
)}
|
|
644
|
-
|
|
645
|
-
{activeModule === 'design-intelligence' && (
|
|
646
|
-
<DesignIntelligenceView
|
|
647
|
-
report={activeReport}
|
|
648
|
-
onFixIssue={handleFixIssue}
|
|
649
|
-
isBusy={isBusy}
|
|
650
|
-
/>
|
|
651
|
-
)}
|
|
652
|
-
|
|
653
|
-
{activeModule === 'performance-lab' && (
|
|
654
|
-
<PerformanceLabView
|
|
655
|
-
report={activeReport}
|
|
656
|
-
onFixIssue={handleFixIssue}
|
|
657
|
-
isBusy={isBusy}
|
|
658
|
-
/>
|
|
659
|
-
)}
|
|
660
|
-
|
|
661
|
-
{activeModule === 'security-audit' && (
|
|
662
|
-
<SecurityAuditView
|
|
663
|
-
report={activeReport}
|
|
664
|
-
onFixIssue={handleFixIssue}
|
|
665
|
-
isBusy={isBusy}
|
|
666
|
-
/>
|
|
667
|
-
)}
|
|
668
|
-
|
|
669
|
-
{activeModule === 'dependency-intelligence' && (
|
|
670
|
-
<DependencyIntelligenceView
|
|
671
|
-
report={activeReport}
|
|
672
|
-
onFixIssue={handleFixIssue}
|
|
673
|
-
isBusy={isBusy}
|
|
674
|
-
/>
|
|
675
|
-
)}
|
|
676
|
-
|
|
677
|
-
{activeModule === 'error-diagnostics' && (
|
|
678
|
-
<ErrorDiagnosticsView
|
|
679
|
-
report={activeReport}
|
|
680
|
-
onFixIssue={handleFixIssue}
|
|
681
|
-
presetErrorLogs={presetErrorLogs}
|
|
682
|
-
onDiagnoseLog={handleDiagnoseLog}
|
|
683
|
-
isBusy={isBusy}
|
|
684
|
-
/>
|
|
685
|
-
)}
|
|
686
|
-
|
|
687
|
-
{activeModule === 'auto-repair' && (
|
|
688
|
-
<AutoRepairCenterView
|
|
689
|
-
report={activeReport}
|
|
690
|
-
environmentChecks={environmentChecks}
|
|
691
|
-
mcpTools={mcpTools}
|
|
692
|
-
onFixIssue={handleFixIssue}
|
|
693
|
-
onFixAllSafe={handleFixAllSafe}
|
|
694
|
-
onRollbackRepair={handleRollbackRepair}
|
|
695
|
-
onUpdateQualityGate={handleUpdateQualityGate}
|
|
696
|
-
onRefreshEnvironment={handleRefreshEnvironment}
|
|
697
|
-
onCallMcpTool={handleCallMcpTool}
|
|
698
|
-
isBusy={isBusy}
|
|
699
|
-
/>
|
|
700
|
-
)}
|
|
701
|
-
|
|
702
|
-
{activeModule === 'visual-testing' && (
|
|
703
|
-
<VisualTestingView
|
|
704
|
-
report={activeReport}
|
|
705
|
-
environmentChecks={environmentChecks}
|
|
706
|
-
mcpTools={mcpTools}
|
|
707
|
-
onFixIssue={handleFixIssue}
|
|
708
|
-
onFixAllSafe={handleFixAllSafe}
|
|
709
|
-
onRollbackRepair={handleRollbackRepair}
|
|
710
|
-
onUpdateQualityGate={handleUpdateQualityGate}
|
|
711
|
-
onRefreshEnvironment={handleRefreshEnvironment}
|
|
712
|
-
onCallMcpTool={handleCallMcpTool}
|
|
713
|
-
isBusy={isBusy}
|
|
714
|
-
/>
|
|
715
|
-
)}
|
|
716
|
-
|
|
717
|
-
{activeModule === 'quality-gate' && (
|
|
718
|
-
<QualityGateView
|
|
719
|
-
report={activeReport}
|
|
720
|
-
environmentChecks={environmentChecks}
|
|
721
|
-
mcpTools={mcpTools}
|
|
722
|
-
onFixIssue={handleFixIssue}
|
|
723
|
-
onFixAllSafe={handleFixAllSafe}
|
|
724
|
-
onRollbackRepair={handleRollbackRepair}
|
|
725
|
-
onUpdateQualityGate={handleUpdateQualityGate}
|
|
726
|
-
onRefreshEnvironment={handleRefreshEnvironment}
|
|
727
|
-
onCallMcpTool={handleCallMcpTool}
|
|
728
|
-
isBusy={isBusy}
|
|
729
|
-
/>
|
|
730
|
-
)}
|
|
731
|
-
|
|
732
|
-
{activeModule === 'project-history' && (
|
|
733
|
-
<ProjectHistoryView
|
|
734
|
-
report={activeReport}
|
|
735
|
-
environmentChecks={environmentChecks}
|
|
736
|
-
mcpTools={mcpTools}
|
|
737
|
-
onFixIssue={handleFixIssue}
|
|
738
|
-
onFixAllSafe={handleFixAllSafe}
|
|
739
|
-
onRollbackRepair={handleRollbackRepair}
|
|
740
|
-
onUpdateQualityGate={handleUpdateQualityGate}
|
|
741
|
-
onRefreshEnvironment={handleRefreshEnvironment}
|
|
742
|
-
onCallMcpTool={handleCallMcpTool}
|
|
743
|
-
isBusy={isBusy}
|
|
744
|
-
/>
|
|
745
|
-
)}
|
|
746
|
-
|
|
747
|
-
{activeModule === 'environment-manager' && (
|
|
748
|
-
<EnvironmentManagerView
|
|
749
|
-
report={activeReport}
|
|
750
|
-
environmentChecks={environmentChecks}
|
|
751
|
-
mcpTools={mcpTools}
|
|
752
|
-
onFixIssue={handleFixIssue}
|
|
753
|
-
onFixAllSafe={handleFixAllSafe}
|
|
754
|
-
onRollbackRepair={handleRollbackRepair}
|
|
755
|
-
onUpdateQualityGate={handleUpdateQualityGate}
|
|
756
|
-
onRefreshEnvironment={handleRefreshEnvironment}
|
|
757
|
-
onCallMcpTool={handleCallMcpTool}
|
|
758
|
-
isBusy={isBusy}
|
|
759
|
-
/>
|
|
760
|
-
)}
|
|
761
|
-
|
|
762
|
-
{activeModule === 'settings' && (
|
|
763
|
-
<SettingsAndMcpView
|
|
764
|
-
report={activeReport}
|
|
765
|
-
environmentChecks={environmentChecks}
|
|
766
|
-
mcpTools={mcpTools}
|
|
767
|
-
onFixIssue={handleFixIssue}
|
|
768
|
-
onFixAllSafe={handleFixAllSafe}
|
|
769
|
-
onRollbackRepair={handleRollbackRepair}
|
|
770
|
-
onUpdateQualityGate={handleUpdateQualityGate}
|
|
771
|
-
onRefreshEnvironment={handleRefreshEnvironment}
|
|
772
|
-
onCallMcpTool={handleCallMcpTool}
|
|
773
|
-
isBusy={isBusy}
|
|
774
|
-
/>
|
|
775
|
-
)}
|
|
776
|
-
</main>
|
|
777
|
-
</div>
|
|
778
|
-
</div>
|
|
779
|
-
</div>
|
|
780
|
-
);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
export default App;
|