@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.
Files changed (96) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +109 -15
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/add.d.ts +7 -0
  5. package/dist/commands/add.d.ts.map +1 -0
  6. package/dist/commands/add.js +87 -0
  7. package/dist/commands/add.js.map +1 -0
  8. package/dist/commands/adopt.d.ts +2 -0
  9. package/dist/commands/adopt.d.ts.map +1 -1
  10. package/dist/commands/adopt.js +243 -45
  11. package/dist/commands/adopt.js.map +1 -1
  12. package/dist/commands/assets.d.ts +28 -0
  13. package/dist/commands/assets.d.ts.map +1 -0
  14. package/dist/commands/assets.js +176 -0
  15. package/dist/commands/assets.js.map +1 -0
  16. package/dist/commands/backend.d.ts +5 -0
  17. package/dist/commands/backend.d.ts.map +1 -0
  18. package/dist/commands/backend.js +68 -0
  19. package/dist/commands/backend.js.map +1 -0
  20. package/dist/commands/new.d.ts +1 -1
  21. package/dist/commands/new.d.ts.map +1 -1
  22. package/dist/commands/new.js +13 -5
  23. package/dist/commands/new.js.map +1 -1
  24. package/dist/commands/prototype.d.ts.map +1 -1
  25. package/dist/commands/prototype.js +68 -20
  26. package/dist/commands/prototype.js.map +1 -1
  27. package/dist/commands/release.d.ts +10 -0
  28. package/dist/commands/release.d.ts.map +1 -0
  29. package/dist/commands/release.js +181 -0
  30. package/dist/commands/release.js.map +1 -0
  31. package/dist/commands/ui.d.ts +5 -0
  32. package/dist/commands/ui.d.ts.map +1 -1
  33. package/dist/commands/ui.js +49 -0
  34. package/dist/commands/ui.js.map +1 -1
  35. package/dist/scaffold/agents.d.ts.map +1 -1
  36. package/dist/scaffold/agents.js +40 -6
  37. package/dist/scaffold/agents.js.map +1 -1
  38. package/dist/scaffold/backend.d.ts +1 -1
  39. package/dist/scaffold/backend.d.ts.map +1 -1
  40. package/dist/scaffold/backend.js +63 -31
  41. package/dist/scaffold/backend.js.map +1 -1
  42. package/dist/scaffold/components.d.ts +8 -0
  43. package/dist/scaffold/components.d.ts.map +1 -0
  44. package/dist/scaffold/components.js +305 -0
  45. package/dist/scaffold/components.js.map +1 -0
  46. package/dist/scaffold/design.d.ts.map +1 -1
  47. package/dist/scaffold/design.js +47 -25
  48. package/dist/scaffold/design.js.map +1 -1
  49. package/dist/scaffold/flagship.d.ts +5 -0
  50. package/dist/scaffold/flagship.d.ts.map +1 -1
  51. package/dist/scaffold/flagship.js +161 -102
  52. package/dist/scaffold/flagship.js.map +1 -1
  53. package/dist/scaffold/index.d.ts +1 -1
  54. package/dist/scaffold/index.d.ts.map +1 -1
  55. package/dist/scaffold/index.js +22 -7
  56. package/dist/scaffold/index.js.map +1 -1
  57. package/dist/scaffold/library.d.ts +3 -0
  58. package/dist/scaffold/library.d.ts.map +1 -0
  59. package/dist/scaffold/library.js +98 -0
  60. package/dist/scaffold/library.js.map +1 -0
  61. package/dist/scaffold/phases.d.ts.map +1 -1
  62. package/dist/scaffold/phases.js +19 -14
  63. package/dist/scaffold/phases.js.map +1 -1
  64. package/dist/scaffold/repomap.d.ts +3 -3
  65. package/dist/scaffold/repomap.d.ts.map +1 -1
  66. package/dist/scaffold/repomap.js +22 -10
  67. package/dist/scaffold/repomap.js.map +1 -1
  68. package/dist/scaffold/standard.d.ts.map +1 -1
  69. package/dist/scaffold/standard.js +3 -2
  70. package/dist/scaffold/standard.js.map +1 -1
  71. package/dist/scaffold/tools-guide.d.ts +3 -0
  72. package/dist/scaffold/tools-guide.d.ts.map +1 -0
  73. package/dist/scaffold/tools-guide.js +117 -0
  74. package/dist/scaffold/tools-guide.js.map +1 -0
  75. package/dist/scaffold/workflow.d.ts +5 -0
  76. package/dist/scaffold/workflow.d.ts.map +1 -0
  77. package/dist/scaffold/workflow.js +221 -0
  78. package/dist/scaffold/workflow.js.map +1 -0
  79. package/dist/ui/CockpitApp.d.ts +2 -2
  80. package/dist/ui/CockpitApp.d.ts.map +1 -1
  81. package/dist/ui/CockpitApp.js +361 -15
  82. package/dist/ui/CockpitApp.js.map +1 -1
  83. package/dist/ui/ToolsPanel.d.ts +9 -0
  84. package/dist/ui/ToolsPanel.d.ts.map +1 -0
  85. package/dist/ui/ToolsPanel.js +230 -0
  86. package/dist/ui/ToolsPanel.js.map +1 -0
  87. package/dist/utils/fs.d.ts.map +1 -1
  88. package/dist/utils/fs.js +42 -6
  89. package/dist/utils/fs.js.map +1 -1
  90. package/dist/utils/project-files.d.ts +4 -0
  91. package/dist/utils/project-files.d.ts.map +1 -0
  92. package/dist/utils/project-files.js +49 -0
  93. package/dist/utils/project-files.js.map +1 -0
  94. package/dist/version.d.ts +1 -1
  95. package/dist/version.js +1 -1
  96. package/package.json +29 -4
@@ -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
- else if (input === "2")
442
+ }
443
+ else if (input === "2") {
444
+ setToolsEditing(false);
207
445
  setCurrentTab("servers");
208
- else if (input === "3")
446
+ }
447
+ else if (input === "3") {
448
+ setToolsEditing(false);
209
449
  setCurrentTab("projects");
210
- else if (input === "4")
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
- // Action shortcuts
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
- syncRepomap();
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" && projects.length > 0) {
556
+ if (currentTab === "projects" && workspaceProjects.length > 0) {
247
557
  if (key.upArrow) {
248
- setSelectedProjectIndex((prev) => (prev > 0 ? prev - 1 : projects.length - 1));
558
+ setSelectedProjectIndex((prev) => (prev > 0 ? prev - 1 : workspaceProjects.length - 1));
249
559
  }
250
560
  else if (key.downArrow) {
251
- setSelectedProjectIndex((prev) => (prev < projects.length - 1 ? prev + 1 : 0));
561
+ setSelectedProjectIndex((prev) => (prev < workspaceProjects.length - 1 ? prev + 1 : 0));
252
562
  }
253
563
  else if (input === " ") {
254
- const chosen = projects[selectedProjectIndex];
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 (${projects.length})`
274
- : ` [3] PROJECTS (${projects.length})` }), _jsx(Text, { bold: true, color: currentTab === "logs" ? "cyan" : "gray", children: currentTab === "logs" ? "● [4] LIVE LOGS" : " [4] LIVE LOGS" })] }), 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) => {
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 (", projects.length, " DETECTED)"] }), _jsx(Text, { dimColor: true, children: "Use [\u2191] / [\u2193] to navigate, [Space] to open project" })] }), projects.length === 0 ? (_jsx(Box, { paddingY: 1, children: _jsxs(Text, { dimColor: true, children: ["No subprojects detected. Operating in standalone repository mode: ", activeProject] }) })) : (projects.map((proj, idx) => {
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, { 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-4]" }), _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" })] })), _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" })) })] })] }));
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