@mozole/cli 2.0.0 → 2.1.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +109 -15
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.d.ts +7 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +87 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/adopt.d.ts +2 -0
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +243 -45
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/assets.d.ts +28 -0
- package/dist/commands/assets.d.ts.map +1 -0
- package/dist/commands/assets.js +176 -0
- package/dist/commands/assets.js.map +1 -0
- package/dist/commands/backend.d.ts +5 -0
- package/dist/commands/backend.d.ts.map +1 -0
- package/dist/commands/backend.js +68 -0
- package/dist/commands/backend.js.map +1 -0
- package/dist/commands/new.d.ts +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +13 -5
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/prototype.d.ts.map +1 -1
- package/dist/commands/prototype.js +68 -20
- package/dist/commands/prototype.js.map +1 -1
- package/dist/commands/release.d.ts +10 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +181 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/commands/ui.d.ts +5 -0
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +49 -0
- package/dist/commands/ui.js.map +1 -1
- package/dist/scaffold/agents.d.ts.map +1 -1
- package/dist/scaffold/agents.js +40 -6
- package/dist/scaffold/agents.js.map +1 -1
- package/dist/scaffold/backend.d.ts +1 -1
- package/dist/scaffold/backend.d.ts.map +1 -1
- package/dist/scaffold/backend.js +63 -31
- package/dist/scaffold/backend.js.map +1 -1
- package/dist/scaffold/components.d.ts +8 -0
- package/dist/scaffold/components.d.ts.map +1 -0
- package/dist/scaffold/components.js +305 -0
- package/dist/scaffold/components.js.map +1 -0
- package/dist/scaffold/design.d.ts.map +1 -1
- package/dist/scaffold/design.js +47 -25
- package/dist/scaffold/design.js.map +1 -1
- package/dist/scaffold/flagship.d.ts +5 -0
- package/dist/scaffold/flagship.d.ts.map +1 -1
- package/dist/scaffold/flagship.js +161 -102
- package/dist/scaffold/flagship.js.map +1 -1
- package/dist/scaffold/index.d.ts +1 -1
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +22 -7
- package/dist/scaffold/index.js.map +1 -1
- package/dist/scaffold/library.d.ts +3 -0
- package/dist/scaffold/library.d.ts.map +1 -0
- package/dist/scaffold/library.js +98 -0
- package/dist/scaffold/library.js.map +1 -0
- package/dist/scaffold/phases.d.ts.map +1 -1
- package/dist/scaffold/phases.js +19 -14
- package/dist/scaffold/phases.js.map +1 -1
- package/dist/scaffold/repomap.d.ts +3 -3
- package/dist/scaffold/repomap.d.ts.map +1 -1
- package/dist/scaffold/repomap.js +22 -10
- package/dist/scaffold/repomap.js.map +1 -1
- package/dist/scaffold/standard.d.ts.map +1 -1
- package/dist/scaffold/standard.js +3 -2
- package/dist/scaffold/standard.js.map +1 -1
- package/dist/scaffold/tools-guide.d.ts +3 -0
- package/dist/scaffold/tools-guide.d.ts.map +1 -0
- package/dist/scaffold/tools-guide.js +117 -0
- package/dist/scaffold/tools-guide.js.map +1 -0
- package/dist/scaffold/workflow.d.ts +5 -0
- package/dist/scaffold/workflow.d.ts.map +1 -0
- package/dist/scaffold/workflow.js +221 -0
- package/dist/scaffold/workflow.js.map +1 -0
- package/dist/ui/CockpitApp.d.ts +2 -2
- package/dist/ui/CockpitApp.d.ts.map +1 -1
- package/dist/ui/CockpitApp.js +361 -15
- package/dist/ui/CockpitApp.js.map +1 -1
- package/dist/ui/ToolsPanel.d.ts +9 -0
- package/dist/ui/ToolsPanel.d.ts.map +1 -0
- package/dist/ui/ToolsPanel.js +230 -0
- package/dist/ui/ToolsPanel.js.map +1 -0
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +42 -6
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/project-files.d.ts +4 -0
- package/dist/utils/project-files.d.ts.map +1 -0
- package/dist/utils/project-files.js +49 -0
- package/dist/utils/project-files.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +29 -4
package/dist/ui/CockpitApp.js
CHANGED
|
@@ -1,18 +1,37 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text, useApp, useInput } from "ink";
|
|
3
3
|
import { useCallback, useEffect, useState } from "react";
|
|
4
|
+
import { adoptProject } from "../commands/adopt.js";
|
|
4
5
|
import { doctorCommand } from "../commands/doctor.js";
|
|
6
|
+
import { createNewProject } from "../commands/new.js";
|
|
5
7
|
import { getProjectPhaseStatus, phaseCommand } from "../commands/phase.js";
|
|
8
|
+
import { prototypeInit } from "../commands/prototype.js";
|
|
6
9
|
import { repomapCommand } from "../commands/repomap.js";
|
|
7
10
|
import { verifyCommand } from "../commands/verify.js";
|
|
8
11
|
import { PHASES } from "../scaffold/phases.js";
|
|
9
12
|
import { serverManager } from "../server/manager.js";
|
|
13
|
+
import { discoverWorkspaceProjects, findPrototypeRoot, } from "../utils/fs.js";
|
|
10
14
|
import { CLI_VERSION } from "../version.js";
|
|
15
|
+
import { ToolsPanel } from "./ToolsPanel.js";
|
|
11
16
|
export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: initialActiveProject, protoRoot, projects = [], initialTab = "overview", onExit, }) {
|
|
12
17
|
const { exit } = useApp();
|
|
13
18
|
const [currentTab, setCurrentTab] = useState(initialTab);
|
|
14
19
|
const [activeProject, setActiveProject] = useState(initialActiveProject);
|
|
15
20
|
const [projectRoot, setProjectRoot] = useState(initialProjectRoot);
|
|
21
|
+
const [workspaceProjects, setWorkspaceProjects] = useState(projects);
|
|
22
|
+
const [currentProtoRoot, setCurrentProtoRoot] = useState(protoRoot);
|
|
23
|
+
const [workspaceMode, setWorkspaceMode] = useState("menu");
|
|
24
|
+
const [workspaceMenuIndex, setWorkspaceMenuIndex] = useState(0);
|
|
25
|
+
// New Project Form
|
|
26
|
+
const [newProjectStep, setNewProjectStep] = useState(0);
|
|
27
|
+
const [newProjectName, setNewProjectName] = useState("");
|
|
28
|
+
const [newProjectFlagship, setNewProjectFlagship] = useState(false);
|
|
29
|
+
const [newProjectBackend, setNewProjectBackend] = useState("none");
|
|
30
|
+
// Adopt Form
|
|
31
|
+
const [adoptPath, setAdoptPath] = useState("");
|
|
32
|
+
// Feedback/Error
|
|
33
|
+
const [formError, setFormError] = useState(null);
|
|
34
|
+
const [toolsEditing, setToolsEditing] = useState(false);
|
|
16
35
|
const [selectedProjectIndex, setSelectedProjectIndex] = useState(() => {
|
|
17
36
|
const idx = projects.findIndex((p) => p.name === initialActiveProject);
|
|
18
37
|
return idx >= 0 ? idx : 0;
|
|
@@ -193,23 +212,256 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
193
212
|
setBusyAction(null);
|
|
194
213
|
}
|
|
195
214
|
}, [busyAction, activeProject, projectRoot, addLog]);
|
|
215
|
+
// Rescan Workspace Projects
|
|
216
|
+
const rescanWorkspace = useCallback(async () => {
|
|
217
|
+
try {
|
|
218
|
+
const pRoot = currentProtoRoot ?? (await findPrototypeRoot(projectRoot));
|
|
219
|
+
if (pRoot) {
|
|
220
|
+
setCurrentProtoRoot(pRoot);
|
|
221
|
+
const discovered = await discoverWorkspaceProjects(pRoot);
|
|
222
|
+
setWorkspaceProjects(discovered);
|
|
223
|
+
addLog(`Workspace rescan found ${discovered.length} client project(s).`, "info");
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
addLog("Rescan: Standalone repository mode, no prototype workspace root found.", "info");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
addLog(`Rescan error: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
231
|
+
}
|
|
232
|
+
}, [currentProtoRoot, projectRoot, addLog]);
|
|
233
|
+
// Create New Project
|
|
234
|
+
const handleCreateProject = useCallback(async () => {
|
|
235
|
+
const trimmedName = newProjectName.trim().toLowerCase();
|
|
236
|
+
if (!trimmedName) {
|
|
237
|
+
setFormError("Project name cannot be empty.");
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(trimmedName)) {
|
|
241
|
+
setFormError("Project name must use lowercase alphanumeric characters and hyphens.");
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
setBusyAction("Scaffolding Project");
|
|
245
|
+
addLog(`Scaffolding new client project: ${trimmedName}...`, "info");
|
|
246
|
+
try {
|
|
247
|
+
const target = await createNewProject({
|
|
248
|
+
name: trimmedName,
|
|
249
|
+
flagship: newProjectFlagship,
|
|
250
|
+
backend: newProjectBackend,
|
|
251
|
+
cwd: currentProtoRoot ?? projectRoot,
|
|
252
|
+
});
|
|
253
|
+
addLog(`Project generated successfully at: ${target}`, "success");
|
|
254
|
+
setNewProjectName("");
|
|
255
|
+
setNewProjectFlagship(false);
|
|
256
|
+
setNewProjectBackend("none");
|
|
257
|
+
setNewProjectStep(0);
|
|
258
|
+
setWorkspaceMode("menu");
|
|
259
|
+
setFormError(null);
|
|
260
|
+
// Rescan and activate new project
|
|
261
|
+
const pRoot = currentProtoRoot ?? (await findPrototypeRoot(projectRoot));
|
|
262
|
+
if (pRoot) {
|
|
263
|
+
setCurrentProtoRoot(pRoot);
|
|
264
|
+
const discovered = await discoverWorkspaceProjects(pRoot);
|
|
265
|
+
setWorkspaceProjects(discovered);
|
|
266
|
+
const found = discovered.find((p) => p.name === trimmedName || p.path === target);
|
|
267
|
+
if (found) {
|
|
268
|
+
switchProject(found);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
setActiveProject(trimmedName);
|
|
273
|
+
setProjectRoot(target);
|
|
274
|
+
refreshPhase(target);
|
|
275
|
+
}
|
|
276
|
+
setCurrentTab("overview");
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
280
|
+
setFormError(msg);
|
|
281
|
+
addLog(`Project creation failed: ${msg}`, "error");
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
setBusyAction(null);
|
|
285
|
+
}
|
|
286
|
+
}, [
|
|
287
|
+
newProjectName,
|
|
288
|
+
newProjectFlagship,
|
|
289
|
+
newProjectBackend,
|
|
290
|
+
currentProtoRoot,
|
|
291
|
+
projectRoot,
|
|
292
|
+
addLog,
|
|
293
|
+
switchProject,
|
|
294
|
+
refreshPhase,
|
|
295
|
+
]);
|
|
296
|
+
// Adopt Project
|
|
297
|
+
const handleAdoptProject = useCallback(async () => {
|
|
298
|
+
const target = adoptPath.trim() || ".";
|
|
299
|
+
setBusyAction("Adopting Project");
|
|
300
|
+
addLog(`Adopting project at path: ${target}...`, "info");
|
|
301
|
+
try {
|
|
302
|
+
await adoptProject({ targetDir: target });
|
|
303
|
+
addLog(`Successfully adopted project into Mozole governance: ${target}`, "success");
|
|
304
|
+
setAdoptPath("");
|
|
305
|
+
setWorkspaceMode("menu");
|
|
306
|
+
setFormError(null);
|
|
307
|
+
await rescanWorkspace();
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
311
|
+
setFormError(msg);
|
|
312
|
+
addLog(`Project adoption failed: ${msg}`, "error");
|
|
313
|
+
}
|
|
314
|
+
finally {
|
|
315
|
+
setBusyAction(null);
|
|
316
|
+
}
|
|
317
|
+
}, [adoptPath, addLog, rescanWorkspace]);
|
|
318
|
+
// Init Prototype Workspace
|
|
319
|
+
const handleInitPrototype = useCallback(async () => {
|
|
320
|
+
setBusyAction("Initializing Prototype");
|
|
321
|
+
addLog(`Initializing prototype workspace ecosystem in ${projectRoot}...`, "info");
|
|
322
|
+
try {
|
|
323
|
+
await prototypeInit({ cwd: projectRoot });
|
|
324
|
+
setCurrentProtoRoot(projectRoot);
|
|
325
|
+
addLog("Prototype workspace initialized successfully.", "success");
|
|
326
|
+
setWorkspaceMode("menu");
|
|
327
|
+
await rescanWorkspace();
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
addLog(`Prototype initialization failed: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
331
|
+
}
|
|
332
|
+
finally {
|
|
333
|
+
setBusyAction(null);
|
|
334
|
+
}
|
|
335
|
+
}, [projectRoot, addLog, rescanWorkspace]);
|
|
196
336
|
// Keyboard navigation
|
|
197
337
|
useInput((input, key) => {
|
|
338
|
+
if (currentTab === "tools" && toolsEditing)
|
|
339
|
+
return;
|
|
340
|
+
// Form interaction inside Workspace tab
|
|
341
|
+
if (currentTab === "workspace" && workspaceMode !== "menu") {
|
|
342
|
+
if (key.escape) {
|
|
343
|
+
if (workspaceMode === "new_project" && newProjectStep > 0) {
|
|
344
|
+
setNewProjectStep((prev) => prev - 1);
|
|
345
|
+
setFormError(null);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
setWorkspaceMode("menu");
|
|
349
|
+
setFormError(null);
|
|
350
|
+
}
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (workspaceMode === "new_project") {
|
|
354
|
+
if (newProjectStep === 0) {
|
|
355
|
+
if (key.return) {
|
|
356
|
+
const name = newProjectName.trim();
|
|
357
|
+
if (!name) {
|
|
358
|
+
setFormError("Please enter a project name.");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(name)) {
|
|
362
|
+
setFormError("Alphanumeric characters, hyphens, and dots only.");
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
setFormError(null);
|
|
366
|
+
setNewProjectStep(1);
|
|
367
|
+
}
|
|
368
|
+
else if (key.backspace || key.delete) {
|
|
369
|
+
setNewProjectName((prev) => prev.slice(0, -1));
|
|
370
|
+
setFormError(null);
|
|
371
|
+
}
|
|
372
|
+
else if (input &&
|
|
373
|
+
input.length === 1 &&
|
|
374
|
+
!key.ctrl &&
|
|
375
|
+
!key.meta &&
|
|
376
|
+
/[a-z0-9._-]/i.test(input)) {
|
|
377
|
+
setNewProjectName((prev) => prev + input.toLowerCase());
|
|
378
|
+
setFormError(null);
|
|
379
|
+
}
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if (newProjectStep === 1) {
|
|
383
|
+
if (key.return) {
|
|
384
|
+
setNewProjectStep(2);
|
|
385
|
+
}
|
|
386
|
+
else if (key.leftArrow || key.rightArrow || key.tab || input === " ") {
|
|
387
|
+
setNewProjectFlagship((prev) => !prev);
|
|
388
|
+
}
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (newProjectStep === 2) {
|
|
392
|
+
if (key.return) {
|
|
393
|
+
handleCreateProject();
|
|
394
|
+
}
|
|
395
|
+
else if (key.leftArrow) {
|
|
396
|
+
setNewProjectBackend((prev) => prev === "none" ? "node" : prev === "php" ? "none" : "php");
|
|
397
|
+
}
|
|
398
|
+
else if (key.rightArrow || key.tab || input === " ") {
|
|
399
|
+
setNewProjectBackend((prev) => prev === "none" ? "php" : prev === "php" ? "node" : "none");
|
|
400
|
+
}
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (workspaceMode === "adopt_project") {
|
|
405
|
+
if (key.return) {
|
|
406
|
+
handleAdoptProject();
|
|
407
|
+
}
|
|
408
|
+
else if (key.backspace || key.delete) {
|
|
409
|
+
setAdoptPath((prev) => prev.slice(0, -1));
|
|
410
|
+
setFormError(null);
|
|
411
|
+
}
|
|
412
|
+
else if (input && input.length === 1 && !key.ctrl && !key.meta) {
|
|
413
|
+
setAdoptPath((prev) => prev + input);
|
|
414
|
+
setFormError(null);
|
|
415
|
+
}
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (workspaceMode === "init_prototype") {
|
|
419
|
+
if (key.return || input === "y" || input === "Y") {
|
|
420
|
+
handleInitPrototype();
|
|
421
|
+
}
|
|
422
|
+
else if (input === "n" || input === "N") {
|
|
423
|
+
setWorkspaceMode("menu");
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
198
429
|
if (key.escape || input === "q" || input === "Q") {
|
|
430
|
+
if (currentTab === "tools") {
|
|
431
|
+
setCurrentTab("overview");
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
199
434
|
onExit?.();
|
|
200
435
|
exit();
|
|
201
436
|
return;
|
|
202
437
|
}
|
|
203
438
|
// Tab jumping
|
|
204
|
-
if (input === "1")
|
|
439
|
+
if (input === "1") {
|
|
440
|
+
setToolsEditing(false);
|
|
205
441
|
setCurrentTab("overview");
|
|
206
|
-
|
|
442
|
+
}
|
|
443
|
+
else if (input === "2") {
|
|
444
|
+
setToolsEditing(false);
|
|
207
445
|
setCurrentTab("servers");
|
|
208
|
-
|
|
446
|
+
}
|
|
447
|
+
else if (input === "3") {
|
|
448
|
+
setToolsEditing(false);
|
|
209
449
|
setCurrentTab("projects");
|
|
210
|
-
|
|
450
|
+
}
|
|
451
|
+
else if (input === "4") {
|
|
452
|
+
setToolsEditing(false);
|
|
211
453
|
setCurrentTab("logs");
|
|
454
|
+
}
|
|
455
|
+
else if (input === "5") {
|
|
456
|
+
setToolsEditing(false);
|
|
457
|
+
setCurrentTab("workspace");
|
|
458
|
+
}
|
|
459
|
+
else if (input === "6") {
|
|
460
|
+
setToolsEditing(false);
|
|
461
|
+
setCurrentTab("tools");
|
|
462
|
+
}
|
|
212
463
|
else if (key.tab) {
|
|
464
|
+
setToolsEditing(false);
|
|
213
465
|
setCurrentTab((prev) => {
|
|
214
466
|
if (prev === "overview")
|
|
215
467
|
return "servers";
|
|
@@ -217,10 +469,66 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
217
469
|
return "projects";
|
|
218
470
|
if (prev === "projects")
|
|
219
471
|
return "logs";
|
|
472
|
+
if (prev === "logs")
|
|
473
|
+
return "workspace";
|
|
474
|
+
if (prev === "workspace")
|
|
475
|
+
return "tools";
|
|
220
476
|
return "overview";
|
|
221
477
|
});
|
|
222
478
|
}
|
|
223
|
-
|
|
479
|
+
if (currentTab === "tools")
|
|
480
|
+
return;
|
|
481
|
+
// Workspace menu navigation
|
|
482
|
+
if (currentTab === "workspace" && workspaceMode === "menu") {
|
|
483
|
+
if (key.upArrow) {
|
|
484
|
+
setWorkspaceMenuIndex((prev) => (prev > 0 ? prev - 1 : 3));
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (key.downArrow) {
|
|
488
|
+
setWorkspaceMenuIndex((prev) => (prev < 3 ? prev + 1 : 0));
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (key.return) {
|
|
492
|
+
if (workspaceMenuIndex === 0) {
|
|
493
|
+
setWorkspaceMode("new_project");
|
|
494
|
+
setNewProjectStep(0);
|
|
495
|
+
setFormError(null);
|
|
496
|
+
}
|
|
497
|
+
else if (workspaceMenuIndex === 1) {
|
|
498
|
+
setWorkspaceMode("adopt_project");
|
|
499
|
+
setAdoptPath("");
|
|
500
|
+
setFormError(null);
|
|
501
|
+
}
|
|
502
|
+
else if (workspaceMenuIndex === 2) {
|
|
503
|
+
setWorkspaceMode("init_prototype");
|
|
504
|
+
}
|
|
505
|
+
else if (workspaceMenuIndex === 3) {
|
|
506
|
+
rescanWorkspace();
|
|
507
|
+
}
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
if (input === "n" || input === "N") {
|
|
511
|
+
setWorkspaceMode("new_project");
|
|
512
|
+
setNewProjectStep(0);
|
|
513
|
+
setFormError(null);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (input === "a" || input === "A") {
|
|
517
|
+
setWorkspaceMode("adopt_project");
|
|
518
|
+
setAdoptPath("");
|
|
519
|
+
setFormError(null);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
if (input === "i" || input === "I") {
|
|
523
|
+
setWorkspaceMode("init_prototype");
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (input === "r" || input === "R") {
|
|
527
|
+
rescanWorkspace();
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
// Action shortcuts (Global outside form modes)
|
|
224
532
|
if (input === "s" || input === "S") {
|
|
225
533
|
toggleServer();
|
|
226
534
|
}
|
|
@@ -237,21 +545,23 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
237
545
|
runDoctor();
|
|
238
546
|
}
|
|
239
547
|
else if (input === "r" || input === "R") {
|
|
240
|
-
|
|
548
|
+
if (currentTab !== "workspace") {
|
|
549
|
+
syncRepomap();
|
|
550
|
+
}
|
|
241
551
|
}
|
|
242
552
|
else if (input === "l" || input === "L") {
|
|
243
553
|
setLogs([]);
|
|
244
554
|
}
|
|
245
555
|
// Projects tab cursor navigation
|
|
246
|
-
if (currentTab === "projects" &&
|
|
556
|
+
if (currentTab === "projects" && workspaceProjects.length > 0) {
|
|
247
557
|
if (key.upArrow) {
|
|
248
|
-
setSelectedProjectIndex((prev) => (prev > 0 ? prev - 1 :
|
|
558
|
+
setSelectedProjectIndex((prev) => (prev > 0 ? prev - 1 : workspaceProjects.length - 1));
|
|
249
559
|
}
|
|
250
560
|
else if (key.downArrow) {
|
|
251
|
-
setSelectedProjectIndex((prev) => (prev <
|
|
561
|
+
setSelectedProjectIndex((prev) => (prev < workspaceProjects.length - 1 ? prev + 1 : 0));
|
|
252
562
|
}
|
|
253
563
|
else if (input === " ") {
|
|
254
|
-
const chosen =
|
|
564
|
+
const chosen = workspaceProjects[selectedProjectIndex];
|
|
255
565
|
if (chosen) {
|
|
256
566
|
if (chosen.name !== activeProject) {
|
|
257
567
|
switchProject(chosen);
|
|
@@ -270,8 +580,16 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
270
580
|
return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "MOZOLE COCKPIT" }), _jsxs(Text, { dimColor: true, children: ["//", " v", CLI_VERSION] })] }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: "ACTIVE PROJECT:" }), _jsx(Text, { bold: true, color: "green", children: activeProject })] }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: "SERVER:" }), server ? (_jsxs(Text, { bold: true, color: "green", children: ["\u25CF RUNNING (", server.url, ")"] })) : (_jsx(Text, { dimColor: true, children: "\u25CB STOPPED" }))] })] }), _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, gap: 2, children: [_jsx(Text, { bold: true, color: currentTab === "overview" ? "cyan" : "gray", children: currentTab === "overview" ? "● [1] OVERVIEW & ROADMAP" : " [1] OVERVIEW & ROADMAP" }), _jsx(Text, { bold: true, color: currentTab === "servers" ? "cyan" : "gray", children: currentTab === "servers"
|
|
271
581
|
? `● [2] DEV SERVERS (${allRunningServers.length} ACTIVE)`
|
|
272
582
|
: ` [2] DEV SERVERS (${allRunningServers.length})` }), _jsx(Text, { bold: true, color: currentTab === "projects" ? "cyan" : "gray", children: currentTab === "projects"
|
|
273
|
-
? `● [3] PROJECTS (${
|
|
274
|
-
: ` [3] PROJECTS (${
|
|
583
|
+
? `● [3] PROJECTS (${workspaceProjects.length})`
|
|
584
|
+
: ` [3] PROJECTS (${workspaceProjects.length})` }), _jsx(Text, { bold: true, color: currentTab === "logs" ? "cyan" : "gray", children: currentTab === "logs" ? "● [4] LIVE LOGS" : " [4] LIVE LOGS" }), _jsx(Text, { bold: true, color: currentTab === "workspace" ? "cyan" : "gray", children: currentTab === "workspace"
|
|
585
|
+
? "● [5] WORKSPACE & GENERATOR"
|
|
586
|
+
: " [5] WORKSPACE & GENERATOR" }), _jsx(Text, { bold: true, color: currentTab === "tools" ? "cyan" : "gray", children: currentTab === "tools" ? "● [6] TOOLS" : " [6] TOOLS" })] }), currentTab === "tools" && (_jsx(ToolsPanel, { projectRoot: projectRoot, activeProject: activeProject, onBack: () => {
|
|
587
|
+
setToolsEditing(false);
|
|
588
|
+
setCurrentTab("overview");
|
|
589
|
+
}, onTabSelect: (tab) => {
|
|
590
|
+
setToolsEditing(false);
|
|
591
|
+
setCurrentTab(tab);
|
|
592
|
+
}, onEditingChange: setToolsEditing, onLog: addLog })), currentTab === "overview" && (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { flexDirection: "row", width: "100%", children: [_jsxs(Box, { flexDirection: "column", width: "52%", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "ATOMIC ROADMAP & PHASES" }), _jsx(Text, { bold: true, color: "cyan", children: progressBar })] }), PHASES.map((phase) => {
|
|
275
593
|
const pNum = Number.parseInt(phase.id, 10);
|
|
276
594
|
const isDone = pNum < activePhaseNum;
|
|
277
595
|
const isCurrent = phase.id === currentPhase;
|
|
@@ -282,11 +600,39 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
282
600
|
return (_jsxs(Box, { children: [_jsxs(Text, { bold: true, color: "cyan", children: [" ", "[\u25BA] Phase ", phase.id, ":", " "] }), _jsx(Text, { bold: true, color: "white", children: phase.name }), _jsxs(Text, { bold: true, color: "yellow", children: [" ", "[ACTIVE]"] })] }, phase.id));
|
|
283
601
|
}
|
|
284
602
|
return (_jsx(Box, { children: _jsxs(Text, { dimColor: true, children: [" ", "[ ] Phase ", phase.id, ": ", phase.name] }) }, phase.id));
|
|
285
|
-
})] }), _jsxs(Box, { flexDirection: "column", width: "48%", children: [_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "yellow", children: "DEV SERVER" }), server ? (_jsx(Text, { bold: true, color: "green", children: "\u25CF ACTIVE" })) : (_jsx(Text, { dimColor: true, children: "\u25CB INACTIVE" }))] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Port: " }), _jsxs(Text, { bold: true, children: [server ? server.port : "5173", " "] }), _jsx(Text, { dimColor: true, children: "PID: " }), _jsx(Text, { bold: true, children: server ? server.process.pid : "None" })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Target URL: " }), _jsx(Text, { color: server ? "cyan" : "gray", children: server ? server.url : "http://localhost:5173" })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Action: Press " }), _jsx(Text, { bold: true, color: "magenta", children: "[S]" }), _jsxs(Text, { dimColor: true, children: [" to ", server ? "stop" : "start", " server"] })] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "SYSTEM RUNTIMES & QUALITY" }), _jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Node.js Runtime" }), _jsxs(Text, { color: "green", children: [process.version, " (PASS)"] })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Biome Code Standards" }), _jsx(Text, { color: "green", children: "Strict & Clean" })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Design Token CSS" }), _jsx(Text, { color: "green", children: "Tailwind v4 @theme" })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "DOM Geometry Probe" }), _jsx(Text, { color: "cyan", children: "Zero-Screenshot" })] })] })] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, height: 7, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "yellow", children: "ACTIVITY STREAM" }), busyAction ? (_jsxs(Text, { bold: true, color: "magenta", children: ["RUNNING: ", busyAction.toUpperCase(), "..."] })) : (_jsx(Text, { dimColor: true, children: "READY" }))] }), logs.slice(-4).map((log) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: ["[", log.timestamp, "] "] }), _jsxs(Text, { bold: true, color: log.level === "error" ? "red" : log.level === "success" ? "green" : "cyan", children: ["[", log.level.toUpperCase(), "]"] }), _jsxs(Text, { color: log.level === "error" ? "red" : undefined, children: [" ", log.text] })] }, log.id)))] })] })), currentTab === "servers" && (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "WORKSPACE DEVELOPMENT SERVERS" }), _jsxs(Text, { dimColor: true, children: ["Total Active: ", allRunningServers.length] })] }), allRunningServers.length === 0 ? (_jsxs(Box, { paddingY: 1, children: [_jsx(Text, { dimColor: true, children: "No dev servers currently running in this workspace." }), _jsxs(Text, { children: [" ", "Press", " ", _jsx(Text, { bold: true, color: "cyan", children: "[S]" }), " ", "to start server for", " ", _jsx(Text, { bold: true, color: "green", children: activeProject }), "."] })] })) : (allRunningServers.map((srv) => (_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { bold: true, color: "green", children: "\u25CF" }), _jsx(Text, { bold: true, children: srv.projectName }), _jsxs(Text, { dimColor: true, children: ["(", srv.url, ")"] })] }), _jsxs(Box, { gap: 2, children: [_jsxs(Text, { dimColor: true, children: ["Port: ", srv.port] }), _jsxs(Text, { dimColor: true, children: ["PID: ", srv.process.pid] }), srv.projectName === activeProject && (_jsx(Text, { bold: true, color: "cyan", children: "[ACTIVE PROJECT]" }))] })] }, srv.id)))), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsx(Text, { dimColor: true, children: "Shortcuts: " }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "magenta", children: "[S]" }), " ", "Toggle Active Server"] }), allRunningServers.length > 0 && (_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "red", children: "[K]" }), " ", "Stop All Servers"] }))] })] }), _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", height: 13, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellow", children: ["DEV SERVER LOG OUTPUT (", activeProject, ")"] }), server ? (_jsxs(Text, { bold: true, color: "green", children: ["\u25CF STREAMING (", server.port, ")"] })) : (_jsx(Text, { dimColor: true, children: "\u25CB SERVER INACTIVE" }))] }), !server || server.recentLogs.length === 0 ? (_jsx(Box, { paddingY: 1, children: _jsxs(Text, { dimColor: true, children: ["No live server logs recorded yet for ", activeProject, "."] }) })) : (server.recentLogs.slice(-10).map((l, i) => (_jsx(Text, { dimColor: !l.includes("error"), children: l }, `${i}-${l}`))))] })] })), currentTab === "projects" && (_jsx(Box, { flexDirection: "column", width: "100%", children: _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellow", children: ["WORKSPACE CLIENT PROJECTS (",
|
|
603
|
+
})] }), _jsxs(Box, { flexDirection: "column", width: "48%", children: [_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "yellow", children: "DEV SERVER" }), server ? (_jsx(Text, { bold: true, color: "green", children: "\u25CF ACTIVE" })) : (_jsx(Text, { dimColor: true, children: "\u25CB INACTIVE" }))] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Port: " }), _jsxs(Text, { bold: true, children: [server ? server.port : "5173", " "] }), _jsx(Text, { dimColor: true, children: "PID: " }), _jsx(Text, { bold: true, children: server ? server.process.pid : "None" })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Target URL: " }), _jsx(Text, { color: server ? "cyan" : "gray", children: server ? server.url : "http://localhost:5173" })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Action: Press " }), _jsx(Text, { bold: true, color: "magenta", children: "[S]" }), _jsxs(Text, { dimColor: true, children: [" to ", server ? "stop" : "start", " server"] })] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "SYSTEM RUNTIMES & QUALITY" }), _jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Node.js Runtime" }), _jsxs(Text, { color: "green", children: [process.version, " (PASS)"] })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Biome Code Standards" }), _jsx(Text, { color: "green", children: "Strict & Clean" })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Design Token CSS" }), _jsx(Text, { color: "green", children: "Tailwind v4 @theme" })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "DOM Geometry Probe" }), _jsx(Text, { color: "cyan", children: "Zero-Screenshot" })] })] })] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, height: 7, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "yellow", children: "ACTIVITY STREAM" }), busyAction ? (_jsxs(Text, { bold: true, color: "magenta", children: ["RUNNING: ", busyAction.toUpperCase(), "..."] })) : (_jsx(Text, { dimColor: true, children: "READY" }))] }), logs.slice(-4).map((log) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: ["[", log.timestamp, "] "] }), _jsxs(Text, { bold: true, color: log.level === "error" ? "red" : log.level === "success" ? "green" : "cyan", children: ["[", log.level.toUpperCase(), "]"] }), _jsxs(Text, { color: log.level === "error" ? "red" : undefined, children: [" ", log.text] })] }, log.id)))] })] })), currentTab === "servers" && (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "WORKSPACE DEVELOPMENT SERVERS" }), _jsxs(Text, { dimColor: true, children: ["Total Active: ", allRunningServers.length] })] }), allRunningServers.length === 0 ? (_jsxs(Box, { paddingY: 1, children: [_jsx(Text, { dimColor: true, children: "No dev servers currently running in this workspace." }), _jsxs(Text, { children: [" ", "Press", " ", _jsx(Text, { bold: true, color: "cyan", children: "[S]" }), " ", "to start server for", " ", _jsx(Text, { bold: true, color: "green", children: activeProject }), "."] })] })) : (allRunningServers.map((srv) => (_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { bold: true, color: "green", children: "\u25CF" }), _jsx(Text, { bold: true, children: srv.projectName }), _jsxs(Text, { dimColor: true, children: ["(", srv.url, ")"] })] }), _jsxs(Box, { gap: 2, children: [_jsxs(Text, { dimColor: true, children: ["Port: ", srv.port] }), _jsxs(Text, { dimColor: true, children: ["PID: ", srv.process.pid] }), srv.projectName === activeProject && (_jsx(Text, { bold: true, color: "cyan", children: "[ACTIVE PROJECT]" }))] })] }, srv.id)))), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsx(Text, { dimColor: true, children: "Shortcuts: " }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "magenta", children: "[S]" }), " ", "Toggle Active Server"] }), allRunningServers.length > 0 && (_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "red", children: "[K]" }), " ", "Stop All Servers"] }))] })] }), _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", height: 13, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellow", children: ["DEV SERVER LOG OUTPUT (", activeProject, ")"] }), server ? (_jsxs(Text, { bold: true, color: "green", children: ["\u25CF STREAMING (", server.port, ")"] })) : (_jsx(Text, { dimColor: true, children: "\u25CB SERVER INACTIVE" }))] }), !server || server.recentLogs.length === 0 ? (_jsx(Box, { paddingY: 1, children: _jsxs(Text, { dimColor: true, children: ["No live server logs recorded yet for ", activeProject, "."] }) })) : (server.recentLogs.slice(-10).map((l, i) => (_jsx(Text, { dimColor: !l.includes("error"), children: l }, `${i}-${l}`))))] })] })), currentTab === "projects" && (_jsx(Box, { flexDirection: "column", width: "100%", children: _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellow", children: ["WORKSPACE CLIENT PROJECTS (", workspaceProjects.length, " DETECTED)"] }), _jsx(Text, { dimColor: true, children: "Use [\u2191] / [\u2193] to navigate, [Space] to open project" })] }), workspaceProjects.length === 0 ? (_jsx(Box, { paddingY: 1, children: _jsxs(Text, { dimColor: true, children: ["No subprojects detected. Operating in standalone repository mode: ", activeProject] }) })) : (workspaceProjects.map((proj, idx) => {
|
|
286
604
|
const isSelected = idx === selectedProjectIndex;
|
|
287
605
|
const isActive = proj.name === activeProject;
|
|
288
606
|
const isRunning = Boolean(serverManager.getServer(proj.name));
|
|
289
607
|
return (_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsxs(Text, { bold: true, color: isSelected ? "cyan" : "gray", children: [isSelected ? "▶" : " ", " [", idx + 1, "]"] }), _jsx(Text, { bold: isSelected, color: isActive ? "green" : isSelected ? "white" : "gray", children: proj.name }), isActive && (_jsx(Text, { bold: true, color: "green", children: "[CURRENT]" }))] }), _jsxs(Box, { gap: 2, children: [_jsx(Text, { color: isRunning ? "green" : "gray", children: isRunning ? "● DEV RUNNING" : "○ OFF" }), _jsx(Text, { dimColor: true, children: proj.path })] })] }, proj.name));
|
|
290
|
-
})), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press", " ", _jsx(Text, { bold: true, color: "cyan", children: "[Space]" }), " ", "to activate selected project and load its roadmap and contracts."] }) })] }) })), currentTab === "logs" && (_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", height: 19, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "FULL CONSOLE & PROCESS LOG STREAM" }), _jsx(Text, { dimColor: true, children: "Press [L] to clear stream" })] }), logs.slice(-16).map((log) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: ["[", log.timestamp, "] "] }), _jsxs(Text, { bold: true, color: log.level === "error" ? "red" : log.level === "success" ? "green" : "cyan", children: ["[", log.level.toUpperCase(), "]"] }), _jsxs(Text, { color: log.level === "error" ? "red" : undefined, children: [" ", log.text] })] }, log.id)))] })), _jsxs(Box, {
|
|
608
|
+
})), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press", " ", _jsx(Text, { bold: true, color: "cyan", children: "[Space]" }), " ", "to activate selected project and load its roadmap and contracts."] }) })] }) })), currentTab === "logs" && (_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", height: 19, children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "FULL CONSOLE & PROCESS LOG STREAM" }), _jsx(Text, { dimColor: true, children: "Press [L] to clear stream" })] }), logs.slice(-16).map((log) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: ["[", log.timestamp, "] "] }), _jsxs(Text, { bold: true, color: log.level === "error" ? "red" : log.level === "success" ? "green" : "cyan", children: ["[", log.level.toUpperCase(), "]"] }), _jsxs(Text, { color: log.level === "error" ? "red" : undefined, children: [" ", log.text] })] }, log.id)))] })), currentTab === "workspace" && (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "yellow", children: "WORKSPACE ECOSYSTEM & STATUS" }), _jsx(Text, { dimColor: true, children: currentProtoRoot ? "● PROTOTYPE MONOREPO ECOSYSTEM" : "○ STANDALONE PROJECT MODE" })] }), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Root: " }), _jsx(Text, { bold: true, color: currentProtoRoot ? "green" : "white", children: currentProtoRoot ?? projectRoot })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Active Project: " }), _jsx(Text, { bold: true, color: "cyan", children: activeProject })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Detected Projects: " }), _jsx(Text, { bold: true, color: "yellow", children: workspaceProjects.length })] })] })] }), _jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, flexDirection: "column", children: [workspaceMode === "menu" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "WORKSPACE OPERATIONS & PROJECT ACTIONS" }), _jsx(Text, { dimColor: true, children: "Use [\u2191] / [\u2193] + [Enter] or press key" })] }), [
|
|
609
|
+
{
|
|
610
|
+
key: "N",
|
|
611
|
+
title: "GENERATE NEW CLIENT PROJECT",
|
|
612
|
+
desc: "Scaffold verified Standard (React Router 7 SSG) or Flagship (Wouter + Canvas) project",
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
key: "A",
|
|
616
|
+
title: "ADOPT EXISTING DIRECTORY",
|
|
617
|
+
desc: "Inject Mozole policies, 10-step atomic phases, canonical tokens, and repomap fihrist",
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
key: "I",
|
|
621
|
+
title: "INITIALIZE PROTOTYPE WORKSPACE",
|
|
622
|
+
desc: "Setup npm workspaces and shared dependencies with project-owned source code",
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
key: "R",
|
|
626
|
+
title: "RESCAN WORKSPACE PROJECTS",
|
|
627
|
+
desc: "Audit the filesystem and update all detected client projects in the cockpit",
|
|
628
|
+
},
|
|
629
|
+
].map((item, idx) => {
|
|
630
|
+
const isSelected = workspaceMenuIndex === idx;
|
|
631
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Box, { gap: 1, children: [_jsxs(Text, { bold: true, color: isSelected ? "cyan" : "gray", children: [isSelected ? "▶" : " ", " [", item.key, "]"] }), _jsx(Text, { bold: true, color: isSelected ? "white" : "gray", children: item.title })] }), _jsx(Box, { paddingLeft: 6, children: _jsx(Text, { dimColor: true, children: item.desc }) })] }, item.key));
|
|
632
|
+
}), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press", " ", _jsx(Text, { bold: true, color: "cyan", children: "[Enter]" }), " ", "to select, or press", " ", _jsx(Text, { bold: true, color: "yellow", children: "[N]" }), ",", " ", _jsx(Text, { bold: true, color: "yellow", children: "[A]" }), ",", " ", _jsx(Text, { bold: true, color: "yellow", children: "[I]" }), ",", " ", _jsx(Text, { bold: true, color: "yellow", children: "[R]" }), " ", "directly."] }) })] })), workspaceMode === "new_project" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellow", children: ["\u26A1 SCAFFOLD NEW CLIENT PROJECT (Step ", newProjectStep + 1, " of 3)"] }), _jsx(Text, { dimColor: true, children: "Press [Esc] to return" })] }), _jsxs(Box, { gap: 1, marginY: 0, children: [_jsx(Text, { bold: true, color: newProjectStep === 0 ? "cyan" : "gray", children: newProjectStep === 0 ? "▶ 1. Project Name:" : " 1. Project Name:" }), _jsx(Text, { bold: true, color: "white", children: newProjectName || (newProjectStep === 0 ? "_" : "<not set>") }), newProjectStep === 0 && (_jsx(Text, { dimColor: true, children: "(Type name, press [Enter] to confirm)" }))] }), _jsxs(Box, { gap: 1, marginY: 0, marginTop: 1, children: [_jsx(Text, { bold: true, color: newProjectStep === 1 ? "cyan" : "gray", children: newProjectStep === 1 ? "▶ 2. Creative Profile:" : " 2. Creative Profile:" }), _jsxs(Box, { gap: 2, children: [_jsx(Text, { bold: !newProjectFlagship, color: !newProjectFlagship ? "green" : "gray", children: !newProjectFlagship ? "[● Standard (React Router 7 SSG)]" : "[○ Standard]" }), _jsx(Text, { bold: newProjectFlagship, color: newProjectFlagship ? "magenta" : "gray", children: newProjectFlagship ? "[● Flagship (Wouter + Canvas)]" : "[○ Flagship]" })] }), newProjectStep === 1 && (_jsx(Text, { dimColor: true, children: "(Press [Space]/[Tab] to switch, [Enter] to next)" }))] }), _jsxs(Box, { gap: 1, marginY: 0, marginTop: 1, children: [_jsx(Text, { bold: true, color: newProjectStep === 2 ? "cyan" : "gray", children: newProjectStep === 2 ? "▶ 3. Backend Runtime:" : " 3. Backend Runtime:" }), _jsxs(Box, { gap: 2, children: [_jsx(Text, { bold: newProjectBackend === "none", color: newProjectBackend === "none" ? "green" : "gray", children: newProjectBackend === "none" ? "[● None (Pure Frontend)]" : "[○ None]" }), _jsx(Text, { bold: newProjectBackend === "php", color: newProjectBackend === "php" ? "yellow" : "gray", children: newProjectBackend === "php" ? "[● PHP 8.1+ Zero-Dep]" : "[○ PHP]" }), _jsx(Text, { bold: newProjectBackend === "node", color: newProjectBackend === "node" ? "yellow" : "gray", children: newProjectBackend === "node" ? "[● Node.js API]" : "[○ Node]" })] }), newProjectStep === 2 && (_jsx(Text, { dimColor: true, children: "(Press [Space]/[Tab] to switch, [Enter] to generate)" }))] }), _jsxs(Box, { marginTop: 1, paddingLeft: 2, children: [_jsx(Text, { dimColor: true, children: "Target Path: " }), _jsx(Text, { color: "cyan", children: newProjectName
|
|
633
|
+
? currentProtoRoot
|
|
634
|
+
? `${currentProtoRoot}/projects/${newProjectName}`
|
|
635
|
+
: `${projectRoot}/${newProjectName}`
|
|
636
|
+
: "<enter name above>" })] }), formError && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { bold: true, color: "red", children: ["[!] ", formError] }) })), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsx(Text, { dimColor: true, children: "Navigation: " }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[Enter]" }), " ", newProjectStep === 2 ? "Generate Project" : "Next Field"] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[Esc]" }), " ", newProjectStep > 0 ? "Back" : "Cancel"] })] })] })), workspaceMode === "adopt_project" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "\uD83D\uDCE6 ADOPT EXISTING REPOSITORY INTO MOZOLE GOVERNANCE" }), _jsx(Text, { dimColor: true, children: "Press [Esc] to return" })] }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "\u25B6 Target Directory Path:" }), _jsx(Text, { bold: true, color: "white", children: adoptPath || "." })] }), _jsxs(Box, { marginTop: 1, paddingLeft: 2, flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "Will inject: AGENTS.md, docs/phases/status.md, docs/repomap/, and tokens.css" }), _jsx(Text, { dimColor: true, children: "Type directory path (e.g. ../another-project or . for current)." })] }), formError && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { bold: true, color: "red", children: ["[!] ", formError] }) })), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[Enter]" }), " ", "Adopt Directory"] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[Esc]" }), " ", "Cancel"] })] })] })), workspaceMode === "init_prototype" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "\uD83D\uDE80 INITIALIZE PROTOTYPE WORKSPACE ECOSYSTEM" }), _jsx(Text, { dimColor: true, children: "Press [Esc] to return" })] }), _jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsx(Text, { children: "Initialize a multi-project prototype workspace in:" }), _jsx(Text, { bold: true, color: "cyan", children: projectRoot }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "\u2022 Creates mozole.config.json" }), _jsx(Text, { dimColor: true, children: "\u2022 Creates projects/ folder for client projects" }), _jsx(Text, { dimColor: true, children: "\u2022 Shares npm dependencies; keeps UI, tokens and behaviors project-local" }), _jsx(Text, { dimColor: true, children: "\u2022 Injects AGENTS.md governance contract" })] })] }), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "green", children: "[Enter / Y]" }), " ", "Confirm Initialization"] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[Esc / N]" }), " ", "Cancel"] })] })] }))] })] })), _jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { gap: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[1-6]" }), _jsx(Text, { dimColor: true, children: " Tabs" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[Tab]" }), _jsx(Text, { dimColor: true, children: " Next Tab" })] }), currentTab === "tools" && !toolsEditing && (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[C]" }), _jsx(Text, { dimColor: true, children: " Comp" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[O]" }), _jsx(Text, { dimColor: true, children: " Opt" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[R]" }), _jsx(Text, { dimColor: true, children: " Rel" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[Enter]" }), _jsx(Text, { dimColor: true, children: " Configure" })] })] })), currentTab === "projects" && (_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[Space]" }), _jsx(Text, { dimColor: true, children: " Select" })] })), currentTab === "workspace" && workspaceMode === "menu" && (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[N]" }), _jsx(Text, { dimColor: true, children: " New" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[A]" }), _jsx(Text, { dimColor: true, children: " Adopt" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "yellow", children: "[I]" }), _jsx(Text, { dimColor: true, children: " Init" })] })] })), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[S]" }), _jsx(Text, { dimColor: true, children: " Server" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[V]" }), _jsx(Text, { dimColor: true, children: " Verify" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[P]" }), _jsx(Text, { dimColor: true, children: " Phase" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[D]" }), _jsx(Text, { dimColor: true, children: " Doctor" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[R]" }), _jsx(Text, { dimColor: true, children: " Repomap" })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "cyan", children: "[Q]" }), _jsx(Text, { dimColor: true, children: " Quit" })] })] }), _jsx(Box, { children: busyAction ? (_jsxs(Text, { bold: true, color: "magenta", children: ["\u25CF BUSY (", busyAction, ")"] })) : (_jsx(Text, { dimColor: true, children: "READY" })) })] })] }));
|
|
291
637
|
}
|
|
292
638
|
//# sourceMappingURL=CockpitApp.js.map
|