@mozole/cli 2.0.0 → 2.1.0
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 +331 -11
- package/dist/ui/CockpitApp.js.map +1 -1
- package/dist/ui/ToolsPanel.d.ts +6 -0
- package/dist/ui/ToolsPanel.d.ts.map +1 -0
- package/dist/ui/ToolsPanel.js +128 -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,36 @@
|
|
|
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);
|
|
16
34
|
const [selectedProjectIndex, setSelectedProjectIndex] = useState(() => {
|
|
17
35
|
const idx = projects.findIndex((p) => p.name === initialActiveProject);
|
|
18
36
|
return idx >= 0 ? idx : 0;
|
|
@@ -193,8 +211,220 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
193
211
|
setBusyAction(null);
|
|
194
212
|
}
|
|
195
213
|
}, [busyAction, activeProject, projectRoot, addLog]);
|
|
214
|
+
// Rescan Workspace Projects
|
|
215
|
+
const rescanWorkspace = useCallback(async () => {
|
|
216
|
+
try {
|
|
217
|
+
const pRoot = currentProtoRoot ?? (await findPrototypeRoot(projectRoot));
|
|
218
|
+
if (pRoot) {
|
|
219
|
+
setCurrentProtoRoot(pRoot);
|
|
220
|
+
const discovered = await discoverWorkspaceProjects(pRoot);
|
|
221
|
+
setWorkspaceProjects(discovered);
|
|
222
|
+
addLog(`Workspace rescan found ${discovered.length} client project(s).`, "info");
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
addLog("Rescan: Standalone repository mode, no prototype workspace root found.", "info");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
addLog(`Rescan error: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
230
|
+
}
|
|
231
|
+
}, [currentProtoRoot, projectRoot, addLog]);
|
|
232
|
+
// Create New Project
|
|
233
|
+
const handleCreateProject = useCallback(async () => {
|
|
234
|
+
const trimmedName = newProjectName.trim().toLowerCase();
|
|
235
|
+
if (!trimmedName) {
|
|
236
|
+
setFormError("Project name cannot be empty.");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(trimmedName)) {
|
|
240
|
+
setFormError("Project name must use lowercase alphanumeric characters and hyphens.");
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
setBusyAction("Scaffolding Project");
|
|
244
|
+
addLog(`Scaffolding new client project: ${trimmedName}...`, "info");
|
|
245
|
+
try {
|
|
246
|
+
const target = await createNewProject({
|
|
247
|
+
name: trimmedName,
|
|
248
|
+
flagship: newProjectFlagship,
|
|
249
|
+
backend: newProjectBackend,
|
|
250
|
+
cwd: currentProtoRoot ?? projectRoot,
|
|
251
|
+
});
|
|
252
|
+
addLog(`Project generated successfully at: ${target}`, "success");
|
|
253
|
+
setNewProjectName("");
|
|
254
|
+
setNewProjectFlagship(false);
|
|
255
|
+
setNewProjectBackend("none");
|
|
256
|
+
setNewProjectStep(0);
|
|
257
|
+
setWorkspaceMode("menu");
|
|
258
|
+
setFormError(null);
|
|
259
|
+
// Rescan and activate new project
|
|
260
|
+
const pRoot = currentProtoRoot ?? (await findPrototypeRoot(projectRoot));
|
|
261
|
+
if (pRoot) {
|
|
262
|
+
setCurrentProtoRoot(pRoot);
|
|
263
|
+
const discovered = await discoverWorkspaceProjects(pRoot);
|
|
264
|
+
setWorkspaceProjects(discovered);
|
|
265
|
+
const found = discovered.find((p) => p.name === trimmedName || p.path === target);
|
|
266
|
+
if (found) {
|
|
267
|
+
switchProject(found);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
setActiveProject(trimmedName);
|
|
272
|
+
setProjectRoot(target);
|
|
273
|
+
refreshPhase(target);
|
|
274
|
+
}
|
|
275
|
+
setCurrentTab("overview");
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
279
|
+
setFormError(msg);
|
|
280
|
+
addLog(`Project creation failed: ${msg}`, "error");
|
|
281
|
+
}
|
|
282
|
+
finally {
|
|
283
|
+
setBusyAction(null);
|
|
284
|
+
}
|
|
285
|
+
}, [
|
|
286
|
+
newProjectName,
|
|
287
|
+
newProjectFlagship,
|
|
288
|
+
newProjectBackend,
|
|
289
|
+
currentProtoRoot,
|
|
290
|
+
projectRoot,
|
|
291
|
+
addLog,
|
|
292
|
+
switchProject,
|
|
293
|
+
refreshPhase,
|
|
294
|
+
]);
|
|
295
|
+
// Adopt Project
|
|
296
|
+
const handleAdoptProject = useCallback(async () => {
|
|
297
|
+
const target = adoptPath.trim() || ".";
|
|
298
|
+
setBusyAction("Adopting Project");
|
|
299
|
+
addLog(`Adopting project at path: ${target}...`, "info");
|
|
300
|
+
try {
|
|
301
|
+
await adoptProject({ targetDir: target });
|
|
302
|
+
addLog(`Successfully adopted project into Mozole governance: ${target}`, "success");
|
|
303
|
+
setAdoptPath("");
|
|
304
|
+
setWorkspaceMode("menu");
|
|
305
|
+
setFormError(null);
|
|
306
|
+
await rescanWorkspace();
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
310
|
+
setFormError(msg);
|
|
311
|
+
addLog(`Project adoption failed: ${msg}`, "error");
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
setBusyAction(null);
|
|
315
|
+
}
|
|
316
|
+
}, [adoptPath, addLog, rescanWorkspace]);
|
|
317
|
+
// Init Prototype Workspace
|
|
318
|
+
const handleInitPrototype = useCallback(async () => {
|
|
319
|
+
setBusyAction("Initializing Prototype");
|
|
320
|
+
addLog(`Initializing prototype workspace ecosystem in ${projectRoot}...`, "info");
|
|
321
|
+
try {
|
|
322
|
+
await prototypeInit({ cwd: projectRoot });
|
|
323
|
+
setCurrentProtoRoot(projectRoot);
|
|
324
|
+
addLog("Prototype workspace initialized successfully.", "success");
|
|
325
|
+
setWorkspaceMode("menu");
|
|
326
|
+
await rescanWorkspace();
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
addLog(`Prototype initialization failed: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
330
|
+
}
|
|
331
|
+
finally {
|
|
332
|
+
setBusyAction(null);
|
|
333
|
+
}
|
|
334
|
+
}, [projectRoot, addLog, rescanWorkspace]);
|
|
196
335
|
// Keyboard navigation
|
|
197
336
|
useInput((input, key) => {
|
|
337
|
+
if (currentTab === "tools")
|
|
338
|
+
return;
|
|
339
|
+
// Form interaction inside Workspace tab
|
|
340
|
+
if (currentTab === "workspace" && workspaceMode !== "menu") {
|
|
341
|
+
if (key.escape) {
|
|
342
|
+
if (workspaceMode === "new_project" && newProjectStep > 0) {
|
|
343
|
+
setNewProjectStep((prev) => prev - 1);
|
|
344
|
+
setFormError(null);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
setWorkspaceMode("menu");
|
|
348
|
+
setFormError(null);
|
|
349
|
+
}
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (workspaceMode === "new_project") {
|
|
353
|
+
if (newProjectStep === 0) {
|
|
354
|
+
if (key.return) {
|
|
355
|
+
const name = newProjectName.trim();
|
|
356
|
+
if (!name) {
|
|
357
|
+
setFormError("Please enter a project name.");
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(name)) {
|
|
361
|
+
setFormError("Alphanumeric characters, hyphens, and dots only.");
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
setFormError(null);
|
|
365
|
+
setNewProjectStep(1);
|
|
366
|
+
}
|
|
367
|
+
else if (key.backspace || key.delete) {
|
|
368
|
+
setNewProjectName((prev) => prev.slice(0, -1));
|
|
369
|
+
setFormError(null);
|
|
370
|
+
}
|
|
371
|
+
else if (input &&
|
|
372
|
+
input.length === 1 &&
|
|
373
|
+
!key.ctrl &&
|
|
374
|
+
!key.meta &&
|
|
375
|
+
/[a-z0-9._-]/i.test(input)) {
|
|
376
|
+
setNewProjectName((prev) => prev + input.toLowerCase());
|
|
377
|
+
setFormError(null);
|
|
378
|
+
}
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (newProjectStep === 1) {
|
|
382
|
+
if (key.return) {
|
|
383
|
+
setNewProjectStep(2);
|
|
384
|
+
}
|
|
385
|
+
else if (key.leftArrow || key.rightArrow || key.tab || input === " ") {
|
|
386
|
+
setNewProjectFlagship((prev) => !prev);
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (newProjectStep === 2) {
|
|
391
|
+
if (key.return) {
|
|
392
|
+
handleCreateProject();
|
|
393
|
+
}
|
|
394
|
+
else if (key.leftArrow) {
|
|
395
|
+
setNewProjectBackend((prev) => prev === "none" ? "node" : prev === "php" ? "none" : "php");
|
|
396
|
+
}
|
|
397
|
+
else if (key.rightArrow || key.tab || input === " ") {
|
|
398
|
+
setNewProjectBackend((prev) => prev === "none" ? "php" : prev === "php" ? "node" : "none");
|
|
399
|
+
}
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (workspaceMode === "adopt_project") {
|
|
404
|
+
if (key.return) {
|
|
405
|
+
handleAdoptProject();
|
|
406
|
+
}
|
|
407
|
+
else if (key.backspace || key.delete) {
|
|
408
|
+
setAdoptPath((prev) => prev.slice(0, -1));
|
|
409
|
+
setFormError(null);
|
|
410
|
+
}
|
|
411
|
+
else if (input && input.length === 1 && !key.ctrl && !key.meta) {
|
|
412
|
+
setAdoptPath((prev) => prev + input);
|
|
413
|
+
setFormError(null);
|
|
414
|
+
}
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
if (workspaceMode === "init_prototype") {
|
|
418
|
+
if (key.return || input === "y" || input === "Y") {
|
|
419
|
+
handleInitPrototype();
|
|
420
|
+
}
|
|
421
|
+
else if (input === "n" || input === "N") {
|
|
422
|
+
setWorkspaceMode("menu");
|
|
423
|
+
}
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
198
428
|
if (key.escape || input === "q" || input === "Q") {
|
|
199
429
|
onExit?.();
|
|
200
430
|
exit();
|
|
@@ -209,6 +439,10 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
209
439
|
setCurrentTab("projects");
|
|
210
440
|
else if (input === "4")
|
|
211
441
|
setCurrentTab("logs");
|
|
442
|
+
else if (input === "5")
|
|
443
|
+
setCurrentTab("workspace");
|
|
444
|
+
else if (input === "6")
|
|
445
|
+
setCurrentTab("tools");
|
|
212
446
|
else if (key.tab) {
|
|
213
447
|
setCurrentTab((prev) => {
|
|
214
448
|
if (prev === "overview")
|
|
@@ -217,10 +451,64 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
217
451
|
return "projects";
|
|
218
452
|
if (prev === "projects")
|
|
219
453
|
return "logs";
|
|
454
|
+
if (prev === "logs")
|
|
455
|
+
return "workspace";
|
|
456
|
+
if (prev === "workspace")
|
|
457
|
+
return "tools";
|
|
220
458
|
return "overview";
|
|
221
459
|
});
|
|
222
460
|
}
|
|
223
|
-
//
|
|
461
|
+
// Workspace menu navigation
|
|
462
|
+
if (currentTab === "workspace" && workspaceMode === "menu") {
|
|
463
|
+
if (key.upArrow) {
|
|
464
|
+
setWorkspaceMenuIndex((prev) => (prev > 0 ? prev - 1 : 3));
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
if (key.downArrow) {
|
|
468
|
+
setWorkspaceMenuIndex((prev) => (prev < 3 ? prev + 1 : 0));
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
if (key.return) {
|
|
472
|
+
if (workspaceMenuIndex === 0) {
|
|
473
|
+
setWorkspaceMode("new_project");
|
|
474
|
+
setNewProjectStep(0);
|
|
475
|
+
setFormError(null);
|
|
476
|
+
}
|
|
477
|
+
else if (workspaceMenuIndex === 1) {
|
|
478
|
+
setWorkspaceMode("adopt_project");
|
|
479
|
+
setAdoptPath("");
|
|
480
|
+
setFormError(null);
|
|
481
|
+
}
|
|
482
|
+
else if (workspaceMenuIndex === 2) {
|
|
483
|
+
setWorkspaceMode("init_prototype");
|
|
484
|
+
}
|
|
485
|
+
else if (workspaceMenuIndex === 3) {
|
|
486
|
+
rescanWorkspace();
|
|
487
|
+
}
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
if (input === "n" || input === "N") {
|
|
491
|
+
setWorkspaceMode("new_project");
|
|
492
|
+
setNewProjectStep(0);
|
|
493
|
+
setFormError(null);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
if (input === "a" || input === "A") {
|
|
497
|
+
setWorkspaceMode("adopt_project");
|
|
498
|
+
setAdoptPath("");
|
|
499
|
+
setFormError(null);
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (input === "i" || input === "I") {
|
|
503
|
+
setWorkspaceMode("init_prototype");
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
if (input === "r" || input === "R") {
|
|
507
|
+
rescanWorkspace();
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
// Action shortcuts (Global outside form modes)
|
|
224
512
|
if (input === "s" || input === "S") {
|
|
225
513
|
toggleServer();
|
|
226
514
|
}
|
|
@@ -237,21 +525,23 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
237
525
|
runDoctor();
|
|
238
526
|
}
|
|
239
527
|
else if (input === "r" || input === "R") {
|
|
240
|
-
|
|
528
|
+
if (currentTab !== "workspace") {
|
|
529
|
+
syncRepomap();
|
|
530
|
+
}
|
|
241
531
|
}
|
|
242
532
|
else if (input === "l" || input === "L") {
|
|
243
533
|
setLogs([]);
|
|
244
534
|
}
|
|
245
535
|
// Projects tab cursor navigation
|
|
246
|
-
if (currentTab === "projects" &&
|
|
536
|
+
if (currentTab === "projects" && workspaceProjects.length > 0) {
|
|
247
537
|
if (key.upArrow) {
|
|
248
|
-
setSelectedProjectIndex((prev) => (prev > 0 ? prev - 1 :
|
|
538
|
+
setSelectedProjectIndex((prev) => (prev > 0 ? prev - 1 : workspaceProjects.length - 1));
|
|
249
539
|
}
|
|
250
540
|
else if (key.downArrow) {
|
|
251
|
-
setSelectedProjectIndex((prev) => (prev <
|
|
541
|
+
setSelectedProjectIndex((prev) => (prev < workspaceProjects.length - 1 ? prev + 1 : 0));
|
|
252
542
|
}
|
|
253
543
|
else if (input === " ") {
|
|
254
|
-
const chosen =
|
|
544
|
+
const chosen = workspaceProjects[selectedProjectIndex];
|
|
255
545
|
if (chosen) {
|
|
256
546
|
if (chosen.name !== activeProject) {
|
|
257
547
|
switchProject(chosen);
|
|
@@ -270,8 +560,10 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
270
560
|
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
561
|
? `● [2] DEV SERVERS (${allRunningServers.length} ACTIVE)`
|
|
272
562
|
: ` [2] DEV SERVERS (${allRunningServers.length})` }), _jsx(Text, { bold: true, color: currentTab === "projects" ? "cyan" : "gray", children: currentTab === "projects"
|
|
273
|
-
? `● [3] PROJECTS (${
|
|
274
|
-
: ` [3] PROJECTS (${
|
|
563
|
+
? `● [3] PROJECTS (${workspaceProjects.length})`
|
|
564
|
+
: ` [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"
|
|
565
|
+
? "● [5] WORKSPACE & GENERATOR"
|
|
566
|
+
: " [5] WORKSPACE & GENERATOR" }), _jsx(Text, { bold: true, color: currentTab === "tools" ? "cyan" : "gray", children: "[6] TOOLS" })] }), currentTab === "tools" && (_jsx(ToolsPanel, { projectRoot: projectRoot, onBack: () => setCurrentTab("overview"), 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
567
|
const pNum = Number.parseInt(phase.id, 10);
|
|
276
568
|
const isDone = pNum < activePhaseNum;
|
|
277
569
|
const isCurrent = phase.id === currentPhase;
|
|
@@ -282,11 +574,39 @@ export function CockpitApp({ projectRoot: initialProjectRoot, activeProject: ini
|
|
|
282
574
|
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
575
|
}
|
|
284
576
|
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 (",
|
|
577
|
+
})] }), _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
578
|
const isSelected = idx === selectedProjectIndex;
|
|
287
579
|
const isActive = proj.name === activeProject;
|
|
288
580
|
const isRunning = Boolean(serverManager.getServer(proj.name));
|
|
289
581
|
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, {
|
|
582
|
+
})), _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" })] }), [
|
|
583
|
+
{
|
|
584
|
+
key: "N",
|
|
585
|
+
title: "GENERATE NEW CLIENT PROJECT",
|
|
586
|
+
desc: "Scaffold verified Standard (React Router 7 SSG) or Flagship (Wouter + Canvas) project",
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
key: "A",
|
|
590
|
+
title: "ADOPT EXISTING DIRECTORY",
|
|
591
|
+
desc: "Inject Mozole policies, 10-step atomic phases, canonical tokens, and repomap fihrist",
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
key: "I",
|
|
595
|
+
title: "INITIALIZE PROTOTYPE WORKSPACE",
|
|
596
|
+
desc: "Setup npm workspaces and shared dependencies with project-owned source code",
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
key: "R",
|
|
600
|
+
title: "RESCAN WORKSPACE PROJECTS",
|
|
601
|
+
desc: "Audit the filesystem and update all detected client projects in the cockpit",
|
|
602
|
+
},
|
|
603
|
+
].map((item, idx) => {
|
|
604
|
+
const isSelected = workspaceMenuIndex === idx;
|
|
605
|
+
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));
|
|
606
|
+
}), _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
|
|
607
|
+
? currentProtoRoot
|
|
608
|
+
? `${currentProtoRoot}/projects/${newProjectName}`
|
|
609
|
+
: `${projectRoot}/${newProjectName}`
|
|
610
|
+
: "<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-5]" }), _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 === "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
611
|
}
|
|
292
612
|
//# sourceMappingURL=CockpitApp.js.map
|