rrce-workflow 0.2.27 → 0.2.29

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 (2) hide show
  1. package/dist/index.js +779 -445
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8,6 +8,22 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/lib/git.ts
12
+ import { execSync } from "child_process";
13
+ function getGitUser() {
14
+ try {
15
+ const result = execSync("git config user.name", { encoding: "utf-8" });
16
+ return result.trim() || null;
17
+ } catch {
18
+ return null;
19
+ }
20
+ }
21
+ var init_git = __esm({
22
+ "src/lib/git.ts"() {
23
+ "use strict";
24
+ }
25
+ });
26
+
11
27
  // src/lib/paths.ts
12
28
  import * as fs from "fs";
13
29
  import * as path from "path";
@@ -366,6 +382,128 @@ var init_prompts = __esm({
366
382
  }
367
383
  });
368
384
 
385
+ // src/commands/wizard/utils.ts
386
+ import * as fs4 from "fs";
387
+ import * as path4 from "path";
388
+ function copyPromptsToDir(prompts, targetDir, extension) {
389
+ for (const prompt of prompts) {
390
+ const baseName = path4.basename(prompt.filePath, ".md");
391
+ const targetName = baseName + extension;
392
+ const targetPath = path4.join(targetDir, targetName);
393
+ const content = fs4.readFileSync(prompt.filePath, "utf-8");
394
+ fs4.writeFileSync(targetPath, content);
395
+ }
396
+ }
397
+ function copyDirRecursive(src, dest) {
398
+ const entries = fs4.readdirSync(src, { withFileTypes: true });
399
+ for (const entry of entries) {
400
+ const srcPath = path4.join(src, entry.name);
401
+ const destPath = path4.join(dest, entry.name);
402
+ if (entry.isDirectory()) {
403
+ ensureDir(destPath);
404
+ copyDirRecursive(srcPath, destPath);
405
+ } else {
406
+ fs4.copyFileSync(srcPath, destPath);
407
+ }
408
+ }
409
+ }
410
+ var init_utils = __esm({
411
+ "src/commands/wizard/utils.ts"() {
412
+ "use strict";
413
+ init_paths();
414
+ }
415
+ });
416
+
417
+ // src/commands/wizard/vscode.ts
418
+ import * as fs5 from "fs";
419
+ import * as path5 from "path";
420
+ function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
421
+ const workspaceFilePath = path5.join(workspacePath, `${workspaceName}.code-workspace`);
422
+ let workspace;
423
+ if (fs5.existsSync(workspaceFilePath)) {
424
+ try {
425
+ const content = fs5.readFileSync(workspaceFilePath, "utf-8");
426
+ workspace = JSON.parse(content);
427
+ } catch {
428
+ workspace = { folders: [], settings: {} };
429
+ }
430
+ } else {
431
+ workspace = { folders: [], settings: {} };
432
+ }
433
+ if (!workspace.settings) {
434
+ workspace.settings = {};
435
+ }
436
+ workspace.folders = workspace.folders.filter(
437
+ (f) => f.path === "." || !f.name?.startsWith("\u{1F4C1}") && !f.name?.startsWith("\u{1F4DA}") && !f.name?.startsWith("\u{1F4CE}") && !f.name?.startsWith("\u{1F4CB}")
438
+ );
439
+ const mainFolderIndex = workspace.folders.findIndex((f) => f.path === ".");
440
+ if (mainFolderIndex === -1) {
441
+ workspace.folders.unshift({
442
+ path: ".",
443
+ name: `\u{1F3E0} ${workspaceName} (workspace)`
444
+ });
445
+ } else {
446
+ workspace.folders[mainFolderIndex] = {
447
+ path: ".",
448
+ name: `\u{1F3E0} ${workspaceName} (workspace)`
449
+ };
450
+ }
451
+ const referenceFolderPaths = [];
452
+ const isDetectedProjects = linkedProjects.length > 0 && typeof linkedProjects[0] === "object";
453
+ if (isDetectedProjects) {
454
+ const projects = linkedProjects;
455
+ for (const project of projects) {
456
+ const sourceLabel = project.source === "global" ? "global" : "local";
457
+ const folderPath = project.dataPath;
458
+ if (fs5.existsSync(folderPath)) {
459
+ referenceFolderPaths.push(folderPath);
460
+ workspace.folders.push({
461
+ path: folderPath,
462
+ name: `\u{1F4C1} ${project.name} [${sourceLabel}]`
463
+ });
464
+ }
465
+ }
466
+ } else {
467
+ const projectNames = linkedProjects;
468
+ const rrceHome = customGlobalPath || getRRCEHome();
469
+ for (const projectName of projectNames) {
470
+ const folderPath = path5.join(rrceHome, "workspaces", projectName);
471
+ if (fs5.existsSync(folderPath)) {
472
+ referenceFolderPaths.push(folderPath);
473
+ workspace.folders.push({
474
+ path: folderPath,
475
+ name: `\u{1F4C1} ${projectName} [global]`
476
+ });
477
+ }
478
+ }
479
+ }
480
+ if (referenceFolderPaths.length > 0) {
481
+ const readonlyPatterns = {};
482
+ for (const folderPath of referenceFolderPaths) {
483
+ readonlyPatterns[`${folderPath}/**`] = true;
484
+ }
485
+ const existingReadonly = workspace.settings["files.readonlyInclude"] || {};
486
+ const cleanedReadonly = {};
487
+ for (const [pattern, value] of Object.entries(existingReadonly)) {
488
+ if (!pattern.includes(".rrce-workflow") && !pattern.includes("rrce-workflow/workspaces")) {
489
+ cleanedReadonly[pattern] = value;
490
+ }
491
+ }
492
+ workspace.settings["files.readonlyInclude"] = {
493
+ ...cleanedReadonly,
494
+ ...readonlyPatterns
495
+ };
496
+ }
497
+ fs5.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, 2));
498
+ }
499
+ var init_vscode = __esm({
500
+ "src/commands/wizard/vscode.ts"() {
501
+ "use strict";
502
+ init_paths();
503
+ init_detection();
504
+ }
505
+ });
506
+
369
507
  // src/lib/autocomplete-prompt.ts
370
508
  import * as fs6 from "fs";
371
509
  import * as path6 from "path";
@@ -583,20 +721,20 @@ var init_types = __esm({
583
721
  });
584
722
 
585
723
  // src/mcp/config.ts
586
- import * as fs12 from "fs";
587
- import * as path11 from "path";
724
+ import * as fs7 from "fs";
725
+ import * as path8 from "path";
588
726
  function getMCPConfigPath() {
589
727
  const workspaceRoot = detectWorkspaceRoot();
590
728
  const rrceHome = getEffectiveRRCEHome(workspaceRoot);
591
- return path11.join(rrceHome, "mcp.yaml");
729
+ return path8.join(rrceHome, "mcp.yaml");
592
730
  }
593
731
  function ensureMCPGlobalPath() {
594
732
  const workspaceRoot = detectWorkspaceRoot();
595
733
  const rrceHome = getEffectiveRRCEHome(workspaceRoot);
596
734
  if (rrceHome.startsWith(".") || rrceHome.includes(".rrce-workflow/")) {
597
- const configPath = path11.join(workspaceRoot, ".rrce-workflow", "config.yaml");
598
- if (fs12.existsSync(configPath)) {
599
- const content = fs12.readFileSync(configPath, "utf-8");
735
+ const configPath = path8.join(workspaceRoot, ".rrce-workflow", "config.yaml");
736
+ if (fs7.existsSync(configPath)) {
737
+ const content = fs7.readFileSync(configPath, "utf-8");
600
738
  const modeMatch = content.match(/mode:\s*(global|workspace)/);
601
739
  if (modeMatch?.[1] === "workspace") {
602
740
  return {
@@ -614,11 +752,11 @@ function ensureMCPGlobalPath() {
614
752
  }
615
753
  function loadMCPConfig() {
616
754
  const configPath = getMCPConfigPath();
617
- if (!fs12.existsSync(configPath)) {
755
+ if (!fs7.existsSync(configPath)) {
618
756
  return { ...DEFAULT_MCP_CONFIG };
619
757
  }
620
758
  try {
621
- const content = fs12.readFileSync(configPath, "utf-8");
759
+ const content = fs7.readFileSync(configPath, "utf-8");
622
760
  return parseMCPConfig(content);
623
761
  } catch {
624
762
  return { ...DEFAULT_MCP_CONFIG };
@@ -626,12 +764,12 @@ function loadMCPConfig() {
626
764
  }
627
765
  function saveMCPConfig(config) {
628
766
  const configPath = getMCPConfigPath();
629
- const dir = path11.dirname(configPath);
630
- if (!fs12.existsSync(dir)) {
631
- fs12.mkdirSync(dir, { recursive: true });
767
+ const dir = path8.dirname(configPath);
768
+ if (!fs7.existsSync(dir)) {
769
+ fs7.mkdirSync(dir, { recursive: true });
632
770
  }
633
771
  const content = serializeMCPConfig(config);
634
- fs12.writeFileSync(configPath, content);
772
+ fs7.writeFileSync(configPath, content);
635
773
  }
636
774
  function parseMCPConfig(content) {
637
775
  const config = { ...DEFAULT_MCP_CONFIG, projects: [] };
@@ -794,12 +932,12 @@ __export(logger_exports, {
794
932
  getLogFilePath: () => getLogFilePath,
795
933
  logger: () => logger
796
934
  });
797
- import * as fs13 from "fs";
798
- import * as path12 from "path";
935
+ import * as fs8 from "fs";
936
+ import * as path9 from "path";
799
937
  function getLogFilePath() {
800
938
  const workspaceRoot = detectWorkspaceRoot();
801
939
  const rrceHome = getEffectiveRRCEHome(workspaceRoot);
802
- return path12.join(rrceHome, "mcp-server.log");
940
+ return path9.join(rrceHome, "mcp-server.log");
803
941
  }
804
942
  var Logger, logger;
805
943
  var init_logger = __esm({
@@ -830,11 +968,11 @@ ${JSON.stringify(data, null, 2)}`;
830
968
  }
831
969
  logMessage += "\n";
832
970
  try {
833
- const dir = path12.dirname(this.logPath);
834
- if (!fs13.existsSync(dir)) {
835
- fs13.mkdirSync(dir, { recursive: true });
971
+ const dir = path9.dirname(this.logPath);
972
+ if (!fs8.existsSync(dir)) {
973
+ fs8.mkdirSync(dir, { recursive: true });
836
974
  }
837
- fs13.appendFileSync(this.logPath, logMessage);
975
+ fs8.appendFileSync(this.logPath, logMessage);
838
976
  } catch (e) {
839
977
  console.error(`[Logger Failure] Could not write to ${this.logPath}`, e);
840
978
  console.error(logMessage);
@@ -858,8 +996,8 @@ ${JSON.stringify(data, null, 2)}`;
858
996
  });
859
997
 
860
998
  // src/mcp/resources.ts
861
- import * as fs14 from "fs";
862
- import * as path13 from "path";
999
+ import * as fs9 from "fs";
1000
+ import * as path10 from "path";
863
1001
  function getExposedProjects() {
864
1002
  const config = loadMCPConfig();
865
1003
  const allProjects = scanForProjects();
@@ -886,11 +1024,11 @@ function getProjectContext(projectName) {
886
1024
  if (!project?.knowledgePath) {
887
1025
  return null;
888
1026
  }
889
- const contextPath = path13.join(project.knowledgePath, "project-context.md");
890
- if (!fs14.existsSync(contextPath)) {
1027
+ const contextPath = path10.join(project.knowledgePath, "project-context.md");
1028
+ if (!fs9.existsSync(contextPath)) {
891
1029
  return null;
892
1030
  }
893
- return fs14.readFileSync(contextPath, "utf-8");
1031
+ return fs9.readFileSync(contextPath, "utf-8");
894
1032
  }
895
1033
  function getProjectTasks(projectName) {
896
1034
  const config = loadMCPConfig();
@@ -903,18 +1041,18 @@ function getProjectTasks(projectName) {
903
1041
  }
904
1042
  const projects = scanForProjects();
905
1043
  const project = projects.find((p) => p.name === projectName);
906
- if (!project?.tasksPath || !fs14.existsSync(project.tasksPath)) {
1044
+ if (!project?.tasksPath || !fs9.existsSync(project.tasksPath)) {
907
1045
  return [];
908
1046
  }
909
1047
  const tasks = [];
910
1048
  try {
911
- const taskDirs = fs14.readdirSync(project.tasksPath, { withFileTypes: true });
1049
+ const taskDirs = fs9.readdirSync(project.tasksPath, { withFileTypes: true });
912
1050
  for (const dir of taskDirs) {
913
1051
  if (!dir.isDirectory()) continue;
914
- const metaPath = path13.join(project.tasksPath, dir.name, "meta.json");
915
- if (fs14.existsSync(metaPath)) {
1052
+ const metaPath = path10.join(project.tasksPath, dir.name, "meta.json");
1053
+ if (fs9.existsSync(metaPath)) {
916
1054
  try {
917
- const meta = JSON.parse(fs14.readFileSync(metaPath, "utf-8"));
1055
+ const meta = JSON.parse(fs9.readFileSync(metaPath, "utf-8"));
918
1056
  tasks.push(meta);
919
1057
  } catch {
920
1058
  }
@@ -933,11 +1071,11 @@ function searchKnowledge(query) {
933
1071
  const permissions = getProjectPermissions(config, project.name);
934
1072
  if (!permissions.knowledge || !project.knowledgePath) continue;
935
1073
  try {
936
- const files = fs14.readdirSync(project.knowledgePath);
1074
+ const files = fs9.readdirSync(project.knowledgePath);
937
1075
  for (const file of files) {
938
1076
  if (!file.endsWith(".md")) continue;
939
- const filePath = path13.join(project.knowledgePath, file);
940
- const content = fs14.readFileSync(filePath, "utf-8");
1077
+ const filePath = path10.join(project.knowledgePath, file);
1078
+ const content = fs9.readFileSync(filePath, "utf-8");
941
1079
  const lines = content.split("\n");
942
1080
  const matches = [];
943
1081
  for (const line of lines) {
@@ -1105,8 +1243,9 @@ function registerResourceHandlers(server) {
1105
1243
  };
1106
1244
  }
1107
1245
  const projectMatch = uri.match(/^rrce:\/\/projects\/([^/]+)\/(.+)$/);
1108
- if (projectMatch) {
1109
- const [, projectName, resourceType] = projectMatch;
1246
+ if (projectMatch && projectMatch[1] && projectMatch[2]) {
1247
+ const projectName = projectMatch[1];
1248
+ const resourceType = projectMatch[2];
1110
1249
  const content = resourceType === "context" ? getProjectContext(projectName) : JSON.stringify(getProjectTasks(projectName), null, 2);
1111
1250
  if (content === null) throw new Error(`Resource not found: ${uri}`);
1112
1251
  return {
@@ -1357,34 +1496,81 @@ var init_server = __esm({
1357
1496
  });
1358
1497
 
1359
1498
  // src/mcp/install.ts
1360
- import * as fs15 from "fs";
1361
- import * as path14 from "path";
1499
+ import * as fs10 from "fs";
1500
+ import * as path11 from "path";
1362
1501
  import * as os from "os";
1363
- function checkInstallStatus() {
1502
+ function checkInstallStatus(workspacePath) {
1364
1503
  return {
1365
- antigravity: checkConfigFile(ANTIGRAVITY_CONFIG),
1366
- claude: checkConfigFile(CLAUDE_CONFIG)
1504
+ antigravity: checkAntigravityConfig(),
1505
+ claude: checkClaudeConfig(),
1506
+ vscodeGlobal: checkVSCodeGlobalConfig(),
1507
+ vscodeWorkspace: workspacePath ? checkVSCodeWorkspaceConfig(workspacePath) : false
1367
1508
  };
1368
1509
  }
1369
- function checkConfigFile(configPath) {
1370
- if (!fs15.existsSync(configPath)) return false;
1510
+ function checkAntigravityConfig() {
1511
+ if (!fs10.existsSync(ANTIGRAVITY_CONFIG)) return false;
1512
+ try {
1513
+ const content = JSON.parse(fs10.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
1514
+ return !!content.mcpServers?.["rrce"];
1515
+ } catch {
1516
+ return false;
1517
+ }
1518
+ }
1519
+ function checkClaudeConfig() {
1520
+ if (!fs10.existsSync(CLAUDE_CONFIG)) return false;
1371
1521
  try {
1372
- const content = JSON.parse(fs15.readFileSync(configPath, "utf-8"));
1522
+ const content = JSON.parse(fs10.readFileSync(CLAUDE_CONFIG, "utf-8"));
1373
1523
  return !!content.mcpServers?.["rrce"];
1374
1524
  } catch {
1375
1525
  return false;
1376
1526
  }
1377
1527
  }
1378
- function installToConfig(target) {
1379
- const configPath = target === "antigravity" ? ANTIGRAVITY_CONFIG : CLAUDE_CONFIG;
1380
- const dir = path14.dirname(configPath);
1381
- if (!fs15.existsSync(dir)) {
1382
- fs15.mkdirSync(dir, { recursive: true });
1528
+ function checkVSCodeGlobalConfig() {
1529
+ if (!fs10.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
1530
+ try {
1531
+ const content = JSON.parse(fs10.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
1532
+ return !!content["mcp.servers"]?.["rrce"];
1533
+ } catch {
1534
+ return false;
1535
+ }
1536
+ }
1537
+ function checkVSCodeWorkspaceConfig(workspacePath) {
1538
+ const configPath = path11.join(workspacePath, ".vscode", "mcp.json");
1539
+ if (!fs10.existsSync(configPath)) return false;
1540
+ try {
1541
+ const content = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
1542
+ return !!content.servers?.["rrce"];
1543
+ } catch {
1544
+ return false;
1545
+ }
1546
+ }
1547
+ function isInstalledAnywhere(workspacePath) {
1548
+ const status = checkInstallStatus(workspacePath);
1549
+ return status.antigravity || status.claude || status.vscodeGlobal || status.vscodeWorkspace;
1550
+ }
1551
+ function installToConfig(target, workspacePath) {
1552
+ switch (target) {
1553
+ case "antigravity":
1554
+ return installToAntigravity();
1555
+ case "claude":
1556
+ return installToClaude();
1557
+ case "vscode-global":
1558
+ return installToVSCodeGlobal();
1559
+ case "vscode-workspace":
1560
+ return workspacePath ? installToVSCodeWorkspace(workspacePath) : false;
1561
+ default:
1562
+ return false;
1563
+ }
1564
+ }
1565
+ function installToAntigravity() {
1566
+ const dir = path11.dirname(ANTIGRAVITY_CONFIG);
1567
+ if (!fs10.existsSync(dir)) {
1568
+ fs10.mkdirSync(dir, { recursive: true });
1383
1569
  }
1384
1570
  let config = { mcpServers: {} };
1385
- if (fs15.existsSync(configPath)) {
1571
+ if (fs10.existsSync(ANTIGRAVITY_CONFIG)) {
1386
1572
  try {
1387
- config = JSON.parse(fs15.readFileSync(configPath, "utf-8"));
1573
+ config = JSON.parse(fs10.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
1388
1574
  } catch {
1389
1575
  }
1390
1576
  }
@@ -1392,21 +1578,108 @@ function installToConfig(target) {
1392
1578
  config.mcpServers["rrce"] = {
1393
1579
  command: "npx",
1394
1580
  args: ["-y", "rrce-workflow", "mcp", "start"]
1395
- // -y to avoid interactive prompts
1396
1581
  };
1397
1582
  try {
1398
- fs15.writeFileSync(configPath, JSON.stringify(config, null, 2));
1583
+ fs10.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
1584
+ return true;
1585
+ } catch {
1586
+ return false;
1587
+ }
1588
+ }
1589
+ function installToClaude() {
1590
+ const dir = path11.dirname(CLAUDE_CONFIG);
1591
+ if (!fs10.existsSync(dir)) {
1592
+ fs10.mkdirSync(dir, { recursive: true });
1593
+ }
1594
+ let config = { mcpServers: {} };
1595
+ if (fs10.existsSync(CLAUDE_CONFIG)) {
1596
+ try {
1597
+ config = JSON.parse(fs10.readFileSync(CLAUDE_CONFIG, "utf-8"));
1598
+ } catch {
1599
+ }
1600
+ }
1601
+ if (!config.mcpServers) config.mcpServers = {};
1602
+ config.mcpServers["rrce"] = {
1603
+ command: "npx",
1604
+ args: ["-y", "rrce-workflow", "mcp", "start"]
1605
+ };
1606
+ try {
1607
+ fs10.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
1608
+ return true;
1609
+ } catch {
1610
+ return false;
1611
+ }
1612
+ }
1613
+ function installToVSCodeGlobal() {
1614
+ const dir = path11.dirname(VSCODE_GLOBAL_CONFIG);
1615
+ if (!fs10.existsSync(dir)) {
1616
+ fs10.mkdirSync(dir, { recursive: true });
1617
+ }
1618
+ let settings = {};
1619
+ if (fs10.existsSync(VSCODE_GLOBAL_CONFIG)) {
1620
+ try {
1621
+ settings = JSON.parse(fs10.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
1622
+ } catch {
1623
+ }
1624
+ }
1625
+ if (!settings["mcp.servers"]) settings["mcp.servers"] = {};
1626
+ settings["mcp.servers"]["rrce"] = {
1627
+ command: "npx",
1628
+ args: ["-y", "rrce-workflow", "mcp", "start"]
1629
+ };
1630
+ try {
1631
+ fs10.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
1632
+ return true;
1633
+ } catch {
1634
+ return false;
1635
+ }
1636
+ }
1637
+ function installToVSCodeWorkspace(workspacePath) {
1638
+ const vscodeDir = path11.join(workspacePath, ".vscode");
1639
+ const configPath = path11.join(vscodeDir, "mcp.json");
1640
+ if (!fs10.existsSync(vscodeDir)) {
1641
+ fs10.mkdirSync(vscodeDir, { recursive: true });
1642
+ }
1643
+ let config = { servers: {} };
1644
+ if (fs10.existsSync(configPath)) {
1645
+ try {
1646
+ config = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
1647
+ } catch {
1648
+ }
1649
+ }
1650
+ if (!config.servers) config.servers = {};
1651
+ config.servers["rrce"] = {
1652
+ command: "npx",
1653
+ args: ["-y", "rrce-workflow", "mcp", "start"]
1654
+ };
1655
+ try {
1656
+ fs10.writeFileSync(configPath, JSON.stringify(config, null, 2));
1399
1657
  return true;
1400
1658
  } catch {
1401
1659
  return false;
1402
1660
  }
1403
1661
  }
1404
- var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG;
1662
+ function getTargetLabel(target) {
1663
+ switch (target) {
1664
+ case "antigravity":
1665
+ return "Antigravity IDE";
1666
+ case "claude":
1667
+ return "Claude Desktop";
1668
+ case "vscode-global":
1669
+ return "VSCode (Global)";
1670
+ case "vscode-workspace":
1671
+ return "VSCode (Workspace)";
1672
+ default:
1673
+ return target;
1674
+ }
1675
+ }
1676
+ var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG, VSCODE_GLOBAL_CONFIG;
1405
1677
  var init_install = __esm({
1406
1678
  "src/mcp/install.ts"() {
1407
1679
  "use strict";
1408
- ANTIGRAVITY_CONFIG = path14.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
1409
- CLAUDE_CONFIG = path14.join(os.homedir(), ".config/claude/claude_desktop_config.json");
1680
+ ANTIGRAVITY_CONFIG = path11.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
1681
+ CLAUDE_CONFIG = path11.join(os.homedir(), ".config/claude/claude_desktop_config.json");
1682
+ VSCODE_GLOBAL_CONFIG = path11.join(os.homedir(), ".config/Code/User/settings.json");
1410
1683
  }
1411
1684
  });
1412
1685
 
@@ -1415,8 +1688,8 @@ var mcp_exports = {};
1415
1688
  __export(mcp_exports, {
1416
1689
  runMCP: () => runMCP
1417
1690
  });
1418
- import { intro as intro2, outro as outro6, select as select4, multiselect as multiselect3, confirm as confirm4, spinner as spinner6, note as note7, cancel as cancel6, isCancel as isCancel7, text as text2 } from "@clack/prompts";
1419
- import pc8 from "picocolors";
1691
+ import { intro, outro, select as select2, multiselect, confirm, spinner, note as note2, cancel, isCancel as isCancel2, text } from "@clack/prompts";
1692
+ import pc3 from "picocolors";
1420
1693
  async function runMCP(subcommand2) {
1421
1694
  if (subcommand2) {
1422
1695
  switch (subcommand2) {
@@ -1436,42 +1709,72 @@ async function runMCP(subcommand2) {
1436
1709
  return;
1437
1710
  }
1438
1711
  }
1439
- intro2(pc8.bgCyan(pc8.black(" RRCE MCP Hub ")));
1712
+ intro(pc3.bgCyan(pc3.black(" RRCE MCP Hub ")));
1713
+ const workspacePath = detectWorkspaceRoot();
1440
1714
  const globalPathCheck = await ensureMCPGlobalPath();
1441
1715
  if (!globalPathCheck.configured) {
1442
1716
  const configured = await handleConfigureGlobalPath();
1443
1717
  if (!configured) {
1444
- outro6(pc8.yellow("MCP requires a global storage path. Setup cancelled."));
1718
+ outro(pc3.yellow("MCP requires a global storage path. Setup cancelled."));
1445
1719
  return;
1446
1720
  }
1447
1721
  }
1448
- const status = checkInstallStatus();
1449
- if (!status.antigravity && !status.claude) {
1450
- const shouldInstall = await confirm4({
1451
- message: "MCP server is not installed in your IDEs. Install now?",
1722
+ const installed = isInstalledAnywhere(workspacePath);
1723
+ if (!installed) {
1724
+ note2(
1725
+ `${pc3.bold("Welcome to RRCE MCP Hub!")}
1726
+
1727
+ MCP (Model Context Protocol) allows AI assistants to access your
1728
+ project knowledge in real-time. Let's get you set up.`,
1729
+ "Getting Started"
1730
+ );
1731
+ const shouldInstall = await confirm({
1732
+ message: "Install MCP server to your IDE(s)?",
1452
1733
  initialValue: true
1453
1734
  });
1454
- if (shouldInstall && !isCancel7(shouldInstall)) {
1455
- await handleInstallWizard();
1735
+ if (shouldInstall && !isCancel2(shouldInstall)) {
1736
+ await handleInstallWizard(workspacePath);
1737
+ const config2 = loadMCPConfig();
1738
+ const exposedCount2 = config2.projects.filter((p) => p.expose).length;
1739
+ if (exposedCount2 === 0) {
1740
+ await handleConfigure();
1741
+ }
1742
+ const shouldStart = await confirm({
1743
+ message: "Start the MCP server now?",
1744
+ initialValue: true
1745
+ });
1746
+ if (shouldStart && !isCancel2(shouldStart)) {
1747
+ await handleStartServer();
1748
+ }
1456
1749
  }
1750
+ outro(pc3.green("MCP Hub setup complete!"));
1751
+ return;
1752
+ }
1753
+ const config = loadMCPConfig();
1754
+ const exposedCount = config.projects.filter((p) => p.expose).length;
1755
+ if (exposedCount === 0 && !config.defaults.includeNew) {
1756
+ note2("MCP is installed but no projects are exposed. Let's configure that.", "Configuration Needed");
1757
+ await handleConfigure();
1457
1758
  }
1458
1759
  let running = true;
1459
1760
  while (running) {
1460
1761
  const serverStatus = getMCPServerStatus();
1461
- const serverLabel = serverStatus.running ? pc8.green("Running") : pc8.dim("Stopped");
1462
- const action = await select4({
1762
+ const serverLabel = serverStatus.running ? pc3.green("\u25CF Running") : pc3.dim("\u25CB Stopped");
1763
+ const currentStatus = checkInstallStatus(workspacePath);
1764
+ const installedCount = [currentStatus.antigravity, currentStatus.claude, currentStatus.vscodeGlobal, currentStatus.vscodeWorkspace].filter(Boolean).length;
1765
+ const action = await select2({
1463
1766
  message: "What would you like to do?",
1464
1767
  options: [
1465
- { value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: `Current status: ${serverLabel}` },
1768
+ { value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: serverLabel },
1466
1769
  { value: "configure", label: "\u2699\uFE0F Configure projects", hint: "Choose which projects to expose" },
1467
- { value: "install", label: "\u{1F4E5} Install to IDE", hint: "Add to Antigravity or Claude Desktop" },
1770
+ { value: "install", label: "\u{1F4E5} Install to IDE", hint: `${installedCount} IDE(s) configured` },
1468
1771
  { value: "status", label: "\u{1F4CB} View status", hint: "See details" },
1469
1772
  { value: "help", label: "\u2753 Help", hint: "Learn about MCP Hub" },
1470
1773
  { value: "exit", label: "\u21A9 Exit", hint: "Return to shell" }
1471
1774
  ]
1472
1775
  });
1473
- if (isCancel7(action)) {
1474
- cancel6("MCP Hub closed.");
1776
+ if (isCancel2(action)) {
1777
+ cancel("MCP Hub closed.");
1475
1778
  return;
1476
1779
  }
1477
1780
  switch (action) {
@@ -1482,7 +1785,7 @@ async function runMCP(subcommand2) {
1482
1785
  await handleConfigure();
1483
1786
  break;
1484
1787
  case "install":
1485
- await handleInstallWizard();
1788
+ await handleInstallWizard(workspacePath);
1486
1789
  break;
1487
1790
  case "status":
1488
1791
  await handleShowStatus();
@@ -1495,140 +1798,227 @@ async function runMCP(subcommand2) {
1495
1798
  break;
1496
1799
  }
1497
1800
  }
1498
- outro6(pc8.green("MCP Hub closed."));
1801
+ outro(pc3.green("MCP Hub closed."));
1499
1802
  }
1500
- async function handleInstallWizard() {
1501
- const status = checkInstallStatus();
1803
+ async function handleInstallWizard(workspacePath) {
1804
+ const status = checkInstallStatus(workspacePath);
1502
1805
  const options = [
1503
- { value: "antigravity", label: "Antigravity IDE", hint: status.antigravity ? "Installed" : "Not installed" },
1504
- { value: "claude", label: "Claude Desktop", hint: status.claude ? "Installed" : "Not installed" }
1806
+ {
1807
+ value: "antigravity",
1808
+ label: "Antigravity IDE",
1809
+ hint: status.antigravity ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
1810
+ },
1811
+ {
1812
+ value: "vscode-global",
1813
+ label: "VSCode (Global Settings)",
1814
+ hint: status.vscodeGlobal ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
1815
+ },
1816
+ {
1817
+ value: "vscode-workspace",
1818
+ label: "VSCode (Workspace Config)",
1819
+ hint: status.vscodeWorkspace ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
1820
+ },
1821
+ {
1822
+ value: "claude",
1823
+ label: "Claude Desktop",
1824
+ hint: status.claude ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
1825
+ }
1505
1826
  ];
1506
- const selected = await multiselect3({
1827
+ const selected = await multiselect({
1507
1828
  message: "Select where to install RRCE MCP Server:",
1508
1829
  options,
1509
1830
  initialValues: [
1510
1831
  ...status.antigravity ? ["antigravity"] : [],
1832
+ ...status.vscodeGlobal ? ["vscode-global"] : [],
1833
+ ...status.vscodeWorkspace ? ["vscode-workspace"] : [],
1511
1834
  ...status.claude ? ["claude"] : []
1512
1835
  ],
1513
1836
  required: false
1514
1837
  });
1515
- if (isCancel7(selected)) return;
1838
+ if (isCancel2(selected)) return;
1516
1839
  const targets = selected;
1517
1840
  const results = [];
1518
1841
  for (const target of targets) {
1519
- const success = installToConfig(target);
1520
- results.push(`${target}: ${success ? pc8.green("Success") : pc8.red("Failed")}`);
1842
+ const success = installToConfig(target, workspacePath);
1843
+ const label = getTargetLabel(target);
1844
+ results.push(`${label}: ${success ? pc3.green("\u2713 Success") : pc3.red("\u2717 Failed")}`);
1521
1845
  }
1522
1846
  if (results.length > 0) {
1523
- note7(results.join("\n"), "Installation Results");
1847
+ note2(results.join("\n"), "Installation Results");
1524
1848
  }
1525
1849
  }
1526
1850
  async function handleStartServer() {
1527
1851
  const fs16 = await import("fs");
1528
1852
  const { getLogFilePath: getLogFilePath2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
1529
1853
  const config = loadMCPConfig();
1530
- const exposedCount = config.projects.filter((p) => p.expose).length;
1531
- if (exposedCount === 0 && !config.defaults.includeNew) {
1532
- const shouldConfig = await confirm4({
1854
+ const projects = scanForProjects();
1855
+ const exposedProjects = projects.filter((p) => {
1856
+ const cfg = config.projects.find((c) => c.name === p.name);
1857
+ return cfg?.expose ?? config.defaults.includeNew;
1858
+ });
1859
+ if (exposedProjects.length === 0) {
1860
+ const shouldConfig = await confirm({
1533
1861
  message: "No projects are currently exposed. Configure now?",
1534
1862
  initialValue: true
1535
1863
  });
1536
- if (shouldConfig && !isCancel7(shouldConfig)) {
1864
+ if (shouldConfig && !isCancel2(shouldConfig)) {
1537
1865
  await handleConfigure();
1866
+ return handleStartServer();
1538
1867
  }
1539
1868
  }
1540
- const portInput = await text2({
1541
- message: "Select port for MCP Server",
1542
- initialValue: config.server.port.toString(),
1543
- placeholder: "3200",
1544
- validate(value) {
1545
- if (isNaN(Number(value))) return "Port must be a number";
1869
+ const status = getMCPServerStatus();
1870
+ let newPort = config.server.port;
1871
+ if (!status.running) {
1872
+ const portInput = await text({
1873
+ message: "Select port for MCP Server",
1874
+ initialValue: config.server.port.toString(),
1875
+ placeholder: "3200",
1876
+ validate(value) {
1877
+ if (isNaN(Number(value))) return "Port must be a number";
1878
+ }
1879
+ });
1880
+ if (isCancel2(portInput)) return;
1881
+ newPort = parseInt(portInput, 10);
1882
+ if (newPort !== config.server.port) {
1883
+ config.server.port = newPort;
1884
+ saveMCPConfig(config);
1546
1885
  }
1547
- });
1548
- if (isCancel7(portInput)) return;
1549
- const newPort = parseInt(portInput, 10);
1550
- if (newPort !== config.server.port) {
1551
- config.server.port = newPort;
1552
- saveMCPConfig(config);
1886
+ } else {
1887
+ newPort = status.port || newPort;
1888
+ note2(`Server is already running on port ${newPort}`, "Info");
1553
1889
  }
1554
1890
  console.clear();
1555
1891
  const logPath = getLogFilePath2();
1556
- const renderHeader = () => {
1892
+ const exposedNames = exposedProjects.map((p) => p.name).slice(0, 5);
1893
+ const exposedLabel = exposedNames.length > 0 ? exposedNames.join(", ") + (exposedProjects.length > 5 ? ` (+${exposedProjects.length - 5} more)` : "") : pc3.dim("(none)");
1894
+ const render = (logs = []) => {
1557
1895
  console.clear();
1558
- console.log(pc8.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
1559
- console.log(pc8.cyan("\u2551 RRCE MCP Hub Running \u2551"));
1560
- console.log(pc8.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
1561
- console.log(pc8.dim("Server is running in Stdio mode (JSON-RPC)."));
1562
- console.log(pc8.dim(`Port: ${newPort} | PID: ${process.pid}`));
1563
- console.log(pc8.dim(`Logging to: ${logPath}`));
1564
- console.log(pc8.dim("---------------------------------------------"));
1565
- };
1566
- const renderFooter = () => {
1567
- console.log(pc8.dim("---------------------------------------------"));
1568
- console.log(pc8.bgBlue(pc8.white(pc8.bold(" COMMANDS "))));
1569
- console.log(`${pc8.bold("q")}: Stop & Quit ${pc8.bold("g")}: Configure Projects ${pc8.bold("p")}: Change Port`);
1896
+ console.log(pc3.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
1897
+ console.log(pc3.cyan("\u2551") + pc3.bold(pc3.white(" RRCE MCP Hub Running ")) + pc3.cyan("\u2551"));
1898
+ console.log(pc3.cyan("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
1899
+ const logLines = logs.slice(-10);
1900
+ const emptyLines = 10 - logLines.length;
1901
+ for (let i = 0; i < emptyLines; i++) {
1902
+ console.log(pc3.cyan("\u2551") + " ".repeat(63) + pc3.cyan("\u2551"));
1903
+ }
1904
+ for (const line of logLines) {
1905
+ const cleanLine = line.replace(/\u001b\[\d+m/g, "");
1906
+ const truncated = cleanLine.substring(0, 61).padEnd(61);
1907
+ console.log(pc3.cyan("\u2551") + " " + pc3.dim(truncated) + " " + pc3.cyan("\u2551"));
1908
+ }
1909
+ console.log(pc3.cyan("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
1910
+ const infoLine = ` \u{1F4CB} ${exposedLabel} \u2502 Port: ${newPort} \u2502 PID: ${process.pid || "?"}`.substring(0, 61).padEnd(61);
1911
+ console.log(pc3.cyan("\u2551") + pc3.yellow(infoLine) + " " + pc3.cyan("\u2551"));
1912
+ console.log(pc3.cyan("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
1913
+ const cmdLine = ` q:Quit p:Projects i:Install r:Reload c:Clear ?:Help`;
1914
+ console.log(pc3.cyan("\u2551") + pc3.dim(cmdLine.padEnd(63)) + pc3.cyan("\u2551"));
1915
+ console.log(pc3.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
1570
1916
  };
1571
- renderHeader();
1572
- renderFooter();
1917
+ let logBuffer = [];
1918
+ render(logBuffer);
1573
1919
  try {
1574
- await startMCPServer();
1920
+ if (!status.running) {
1921
+ await startMCPServer();
1922
+ }
1575
1923
  let lastSize = 0;
1576
1924
  if (fs16.existsSync(logPath)) {
1577
1925
  const stats = fs16.statSync(logPath);
1578
1926
  lastSize = stats.size;
1579
1927
  }
1580
1928
  let isRunning = true;
1929
+ let interval;
1581
1930
  if (process.stdin.setRawMode) {
1582
1931
  process.stdin.setRawMode(true);
1583
1932
  process.stdin.resume();
1584
1933
  process.stdin.setEncoding("utf8");
1585
1934
  }
1586
1935
  return new Promise((resolve) => {
1936
+ const cleanup = (shouldStopServer) => {
1937
+ isRunning = false;
1938
+ clearInterval(interval);
1939
+ if (process.stdin.setRawMode) {
1940
+ process.stdin.setRawMode(false);
1941
+ }
1942
+ process.stdin.removeListener("data", onKey);
1943
+ process.stdin.pause();
1944
+ if (shouldStopServer) {
1945
+ stopMCPServer();
1946
+ }
1947
+ console.log("");
1948
+ };
1587
1949
  const onKey = async (key) => {
1588
1950
  if (key === "" || key.toLowerCase() === "q") {
1589
- cleanup();
1951
+ cleanup(true);
1952
+ resolve();
1953
+ return;
1954
+ }
1955
+ if (key.toLowerCase() === "p") {
1956
+ cleanup(false);
1957
+ console.clear();
1958
+ await handleConfigure();
1959
+ await handleStartServer();
1590
1960
  resolve();
1961
+ return;
1591
1962
  }
1592
- if (key.toLowerCase() === "p" || key.toLowerCase() === "g") {
1593
- cleanup();
1963
+ if (key.toLowerCase() === "i") {
1964
+ cleanup(false);
1965
+ console.clear();
1966
+ await handleInstallWizard(detectWorkspaceRoot());
1967
+ await handleStartServer();
1594
1968
  resolve();
1969
+ return;
1970
+ }
1971
+ if (key.toLowerCase() === "r") {
1972
+ logBuffer.push("[INFO] Reloading configuration...");
1973
+ render(logBuffer);
1974
+ return;
1975
+ }
1976
+ if (key.toLowerCase() === "c") {
1977
+ logBuffer = [];
1978
+ render(logBuffer);
1979
+ return;
1980
+ }
1981
+ if (key === "?") {
1982
+ logBuffer.push("\u2500".repeat(40));
1983
+ logBuffer.push("Commands:");
1984
+ logBuffer.push(" q - Stop server and return to menu");
1985
+ logBuffer.push(" p - Reconfigure exposed projects");
1986
+ logBuffer.push(" i - Install to additional IDEs");
1987
+ logBuffer.push(" r - Reload configuration");
1988
+ logBuffer.push(" c - Clear log display");
1989
+ logBuffer.push(" ? - Show this help");
1990
+ logBuffer.push("\u2500".repeat(40));
1991
+ render(logBuffer);
1992
+ return;
1595
1993
  }
1596
1994
  };
1597
1995
  process.stdin.on("data", onKey);
1598
- const interval = setInterval(() => {
1996
+ interval = setInterval(() => {
1599
1997
  if (!isRunning) return;
1600
1998
  if (fs16.existsSync(logPath)) {
1601
1999
  const stats = fs16.statSync(logPath);
1602
2000
  if (stats.size > lastSize) {
1603
- const stream = fs16.createReadStream(logPath, {
1604
- start: lastSize,
1605
- end: stats.size,
1606
- encoding: "utf-8"
1607
- });
1608
- stream.on("data", (chunk) => {
1609
- process.stderr.write(chunk);
1610
- });
2001
+ const buffer = Buffer.alloc(stats.size - lastSize);
2002
+ const fd = fs16.openSync(logPath, "r");
2003
+ fs16.readSync(fd, buffer, 0, buffer.length, lastSize);
2004
+ fs16.closeSync(fd);
2005
+ const newContent = buffer.toString("utf-8");
2006
+ const newLines = newContent.split("\n").filter((l) => l.trim());
2007
+ logBuffer.push(...newLines);
2008
+ if (logBuffer.length > 100) {
2009
+ logBuffer = logBuffer.slice(-100);
2010
+ }
1611
2011
  lastSize = stats.size;
2012
+ render(logBuffer);
1612
2013
  }
1613
2014
  }
1614
2015
  }, 500);
1615
- const cleanup = () => {
1616
- isRunning = false;
1617
- clearInterval(interval);
1618
- if (process.stdin.setRawMode) {
1619
- process.stdin.setRawMode(false);
1620
- }
1621
- process.stdin.removeListener("data", onKey);
1622
- process.stdin.pause();
1623
- stopMCPServer();
1624
- console.log("");
1625
- };
1626
2016
  });
1627
2017
  } catch (error) {
1628
2018
  if (process.stdin.setRawMode) {
1629
2019
  process.stdin.setRawMode(false);
1630
2020
  }
1631
- console.error(pc8.red("\nFailed to start server:"));
2021
+ console.error(pc3.red("\nFailed to start/monitor server:"));
1632
2022
  console.error(error);
1633
2023
  }
1634
2024
  }
@@ -1636,11 +2026,11 @@ async function handleConfigureGlobalPath() {
1636
2026
  const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
1637
2027
  const fs16 = await import("fs");
1638
2028
  const path16 = await import("path");
1639
- note7(
1640
- `MCP Hub requires a ${pc8.bold("global storage path")} to store its configuration
2029
+ note2(
2030
+ `MCP Hub requires a ${pc3.bold("global storage path")} to store its configuration
1641
2031
  and coordinate across projects.
1642
2032
 
1643
- Your current setup uses ${pc8.cyan("workspace")} mode, which stores data
2033
+ Your current setup uses ${pc3.cyan("workspace")} mode, which stores data
1644
2034
  locally in each project. MCP needs a central location.`,
1645
2035
  "Global Path Required"
1646
2036
  );
@@ -1654,8 +2044,8 @@ locally in each project. MCP needs a central location.`,
1654
2044
  }
1655
2045
  const config = loadMCPConfig();
1656
2046
  saveMCPConfig(config);
1657
- note7(
1658
- `${pc8.green("\u2713")} Global path configured: ${pc8.cyan(resolvedPath)}
2047
+ note2(
2048
+ `${pc3.green("\u2713")} Global path configured: ${pc3.cyan(resolvedPath)}
1659
2049
 
1660
2050
  MCP config will be stored at:
1661
2051
  ${path16.join(resolvedPath, "mcp.yaml")}`,
@@ -1663,54 +2053,63 @@ ${path16.join(resolvedPath, "mcp.yaml")}`,
1663
2053
  );
1664
2054
  return true;
1665
2055
  } catch (error) {
1666
- note7(
1667
- `${pc8.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
2056
+ note2(
2057
+ `${pc3.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
1668
2058
  "Error"
1669
2059
  );
1670
2060
  return false;
1671
2061
  }
1672
2062
  }
1673
2063
  async function handleShowStatus() {
1674
- const s = spinner6();
2064
+ const s = spinner();
1675
2065
  s.start("Loading projects...");
1676
2066
  const config = loadMCPConfig();
1677
2067
  const projects = scanForProjects();
2068
+ const workspacePath = detectWorkspaceRoot();
2069
+ const installStatus = checkInstallStatus(workspacePath);
1678
2070
  s.stop("Projects loaded");
1679
2071
  if (projects.length === 0) {
1680
- note7('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
2072
+ note2('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
1681
2073
  return;
1682
2074
  }
1683
2075
  const lines = [
1684
- `${pc8.bold("Project Status")}`,
2076
+ `${pc3.bold("Installation Status")}`,
2077
+ "",
2078
+ ` Antigravity: ${installStatus.antigravity ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
2079
+ ` VSCode (Global): ${installStatus.vscodeGlobal ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
2080
+ ` VSCode (Workspace): ${installStatus.vscodeWorkspace ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
2081
+ ` Claude Desktop: ${installStatus.claude ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
2082
+ "",
2083
+ `${pc3.bold("Project Status")}`,
1685
2084
  ""
1686
2085
  ];
1687
2086
  for (const project of projects) {
1688
2087
  const projectConfig = config.projects.find((p) => p.name === project.name);
1689
2088
  const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
1690
- const status = isExposed ? pc8.green("\u2713 exposed") : pc8.dim("\u25CB hidden");
1691
- const source = pc8.dim(`(${project.source})`);
2089
+ const status = isExposed ? pc3.green("\u2713 exposed") : pc3.dim("\u25CB hidden");
2090
+ const source = pc3.dim(`(${project.source})`);
1692
2091
  lines.push(` ${status} ${project.name} ${source}`);
1693
2092
  }
1694
2093
  lines.push("");
1695
- lines.push(pc8.dim(`Config: ${getMCPConfigPath()}`));
2094
+ lines.push(pc3.dim(`Config: ${getMCPConfigPath()}`));
1696
2095
  const serverStatus = getMCPServerStatus();
1697
2096
  if (serverStatus.running) {
1698
- lines.push(pc8.green(`Server: running on port ${serverStatus.port}`));
2097
+ lines.push(pc3.green(`Server: running on port ${serverStatus.port}`));
1699
2098
  } else {
1700
- lines.push(pc8.dim("Server: not running"));
2099
+ lines.push(pc3.dim("Server: not running"));
1701
2100
  }
1702
- note7(lines.join("\n"), "MCP Hub Status");
2101
+ note2(lines.join("\n"), "MCP Hub Status");
1703
2102
  }
1704
2103
  async function handleConfigure() {
1705
2104
  const { logger: logger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
1706
- const s = spinner6();
2105
+ const s = spinner();
1707
2106
  s.start("Scanning for projects...");
1708
2107
  const config = loadMCPConfig();
1709
2108
  const projects = scanForProjects();
1710
2109
  logger2.info("Configure: Loaded config", { projects: config.projects, defaultMode: config.defaults.includeNew });
1711
2110
  s.stop("Projects found");
1712
2111
  if (projects.length === 0) {
1713
- note7('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
2112
+ note2('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
1714
2113
  return;
1715
2114
  }
1716
2115
  const options = projects.map((project) => {
@@ -1718,7 +2117,7 @@ async function handleConfigure() {
1718
2117
  const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
1719
2118
  return {
1720
2119
  value: project.name,
1721
- label: `${project.name} ${pc8.dim(`(${project.source})`)}`,
2120
+ label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
1722
2121
  hint: project.dataPath
1723
2122
  };
1724
2123
  });
@@ -1726,13 +2125,13 @@ async function handleConfigure() {
1726
2125
  const cfg = config.projects.find((c) => c.name === p.name);
1727
2126
  return cfg?.expose ?? config.defaults.includeNew;
1728
2127
  }).map((p) => p.name);
1729
- const selected = await multiselect3({
2128
+ const selected = await multiselect({
1730
2129
  message: "Select projects to expose via MCP:",
1731
2130
  options,
1732
2131
  initialValues: currentlyExposed,
1733
2132
  required: false
1734
2133
  });
1735
- if (isCancel7(selected)) {
2134
+ if (isCancel2(selected)) {
1736
2135
  return;
1737
2136
  }
1738
2137
  const selectedNames = selected;
@@ -1744,8 +2143,8 @@ async function handleConfigure() {
1744
2143
  saveMCPConfig(config);
1745
2144
  logger2.info("Configure: Config saved", config);
1746
2145
  const exposedCount = selectedNames.length;
1747
- note7(
1748
- `${pc8.green("\u2713")} Configuration saved!
2146
+ note2(
2147
+ `${pc3.green("\u2713")} Configuration saved!
1749
2148
 
1750
2149
  Exposed projects: ${exposedCount}
1751
2150
  Hidden projects: ${projects.length - exposedCount}`,
@@ -1755,65 +2154,57 @@ Hidden projects: ${projects.length - exposedCount}`,
1755
2154
  async function handleStopServer() {
1756
2155
  const status = getMCPServerStatus();
1757
2156
  if (!status.running) {
1758
- note7("MCP server is not running.", "Status");
2157
+ note2("MCP server is not running.", "Status");
1759
2158
  return;
1760
2159
  }
1761
- const confirmed = await confirm4({
2160
+ const confirmed = await confirm({
1762
2161
  message: "Stop the MCP server?",
1763
2162
  initialValue: true
1764
2163
  });
1765
- if (isCancel7(confirmed) || !confirmed) {
2164
+ if (isCancel2(confirmed) || !confirmed) {
1766
2165
  return;
1767
2166
  }
1768
2167
  stopMCPServer();
1769
- note7(pc8.green("MCP server stopped."), "Server Stopped");
2168
+ note2(pc3.green("MCP server stopped."), "Server Stopped");
1770
2169
  }
1771
2170
  function showHelp() {
1772
2171
  const help = `
1773
- ${pc8.bold("RRCE MCP Hub")} - Cross-project AI assistant server
2172
+ ${pc3.bold("RRCE MCP Hub")} - Cross-project AI assistant server
1774
2173
 
1775
- ${pc8.bold("ABOUT")}
2174
+ ${pc3.bold("ABOUT")}
1776
2175
  MCP (Model Context Protocol) allows AI assistants like Claude to
1777
2176
  access your project knowledge in real-time. The RRCE MCP Hub
1778
2177
  provides a central server that exposes selected projects.
1779
2178
 
1780
- ${pc8.bold("MENU OPTIONS")}
1781
- ${pc8.cyan("View project status")} See which projects are exposed
1782
- ${pc8.cyan("Configure projects")} Choose which projects to expose
1783
- ${pc8.cyan("Start MCP server")} Start the server for AI access
1784
- ${pc8.cyan("Stop MCP server")} Stop the running server
2179
+ ${pc3.bold("MENU OPTIONS")}
2180
+ ${pc3.cyan("Start MCP server")} Start the server for AI access
2181
+ ${pc3.cyan("Configure projects")} Choose which projects to expose
2182
+ ${pc3.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
2183
+ ${pc3.cyan("View status")} See which projects are exposed
1785
2184
 
1786
- ${pc8.bold("DIRECT COMMANDS")}
1787
- ${pc8.dim("rrce-workflow mcp start")} Start server directly
1788
- ${pc8.dim("rrce-workflow mcp stop")} Stop server directly
1789
- ${pc8.dim("rrce-workflow mcp status")} Show status directly
1790
- ${pc8.dim("rrce-workflow mcp help")} Show this help
2185
+ ${pc3.bold("DIRECT COMMANDS")}
2186
+ ${pc3.dim("rrce-workflow mcp start")} Start server directly
2187
+ ${pc3.dim("rrce-workflow mcp stop")} Stop server directly
2188
+ ${pc3.dim("rrce-workflow mcp status")} Show status directly
2189
+ ${pc3.dim("rrce-workflow mcp help")} Show this help
1791
2190
 
1792
- ${pc8.bold("CLAUDE DESKTOP SETUP")}
1793
- Add to ${pc8.cyan("~/.config/claude/claude_desktop_config.json")}:
1794
- ${pc8.dim(`{
1795
- "mcpServers": {
1796
- "rrce": {
1797
- "command": "npx",
1798
- "args": ["rrce-workflow", "mcp", "start"]
1799
- }
1800
- }
1801
- }`)}
2191
+ ${pc3.bold("IDE INSTALLATION")}
2192
+ ${pc3.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
2193
+ ${pc3.cyan("VSCode Global")} ~/.config/Code/User/settings.json
2194
+ ${pc3.cyan("VSCode Workspace")} .vscode/mcp.json
2195
+ ${pc3.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
1802
2196
 
1803
- ${pc8.bold("RESOURCES EXPOSED")}
1804
- ${pc8.cyan("rrce://projects")} List all exposed projects
1805
- ${pc8.cyan("rrce://projects/{name}/context")} Get project context
1806
- ${pc8.cyan("rrce://projects/{name}/tasks")} Get project tasks
2197
+ ${pc3.bold("SERVER COMMANDS")} (while running)
2198
+ ${pc3.cyan("q")} Stop and quit ${pc3.cyan("p")} Reconfigure projects
2199
+ ${pc3.cyan("i")} Install to IDE ${pc3.cyan("r")} Reload config
2200
+ ${pc3.cyan("c")} Clear logs ${pc3.cyan("?")} Show help
1807
2201
 
1808
- ${pc8.bold("PROMPTS (Agent Commands)")}
1809
- ${pc8.cyan("init")} Initialize project context
1810
- ${pc8.cyan("research")} Research requirements for a task
1811
- ${pc8.cyan("plan")} Create execution plan
1812
- ${pc8.cyan("execute")} Implement planned work
1813
- ${pc8.cyan("docs")} Generate documentation
1814
- ${pc8.cyan("sync")} Sync knowledge with codebase
2202
+ ${pc3.bold("RESOURCES EXPOSED")}
2203
+ ${pc3.cyan("rrce://projects")} List all exposed projects
2204
+ ${pc3.cyan("rrce://projects/{name}/context")} Get project context
2205
+ ${pc3.cyan("rrce://projects/{name}/tasks")} Get project tasks
1815
2206
  `;
1816
- note7(help.trim(), "Help");
2207
+ note2(help.trim(), "Help");
1817
2208
  }
1818
2209
  var init_mcp = __esm({
1819
2210
  "src/mcp/index.ts"() {
@@ -1822,157 +2213,20 @@ var init_mcp = __esm({
1822
2213
  init_detection();
1823
2214
  init_server();
1824
2215
  init_install();
2216
+ init_paths();
1825
2217
  }
1826
2218
  });
1827
2219
 
1828
- // src/commands/wizard/index.ts
1829
- import { intro, select as select3, spinner as spinner5, note as note6, outro as outro5, isCancel as isCancel6 } from "@clack/prompts";
1830
- import pc7 from "picocolors";
1831
- import * as fs11 from "fs";
1832
-
1833
- // src/lib/git.ts
1834
- import { execSync } from "child_process";
1835
- function getGitUser() {
1836
- try {
1837
- const result = execSync("git config user.name", { encoding: "utf-8" });
1838
- return result.trim() || null;
1839
- } catch {
1840
- return null;
1841
- }
1842
- }
1843
-
1844
- // src/commands/wizard/index.ts
1845
- init_paths();
1846
- init_detection();
1847
-
1848
2220
  // src/commands/wizard/setup-flow.ts
1849
- init_paths();
1850
- init_prompts();
1851
- import { group, select as select2, multiselect, confirm, spinner, note as note2, outro, cancel } from "@clack/prompts";
1852
- import pc3 from "picocolors";
1853
- import * as fs7 from "fs";
1854
- import * as path8 from "path";
1855
-
1856
- // src/commands/wizard/utils.ts
1857
- init_paths();
1858
- import * as fs4 from "fs";
1859
- import * as path4 from "path";
1860
- function copyPromptsToDir(prompts, targetDir, extension) {
1861
- for (const prompt of prompts) {
1862
- const baseName = path4.basename(prompt.filePath, ".md");
1863
- const targetName = baseName + extension;
1864
- const targetPath = path4.join(targetDir, targetName);
1865
- const content = fs4.readFileSync(prompt.filePath, "utf-8");
1866
- fs4.writeFileSync(targetPath, content);
1867
- }
1868
- }
1869
- function copyDirRecursive(src, dest) {
1870
- const entries = fs4.readdirSync(src, { withFileTypes: true });
1871
- for (const entry of entries) {
1872
- const srcPath = path4.join(src, entry.name);
1873
- const destPath = path4.join(dest, entry.name);
1874
- if (entry.isDirectory()) {
1875
- ensureDir(destPath);
1876
- copyDirRecursive(srcPath, destPath);
1877
- } else {
1878
- fs4.copyFileSync(srcPath, destPath);
1879
- }
1880
- }
1881
- }
1882
-
1883
- // src/commands/wizard/vscode.ts
1884
- init_paths();
1885
- init_detection();
1886
- import * as fs5 from "fs";
1887
- import * as path5 from "path";
1888
- function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
1889
- const workspaceFilePath = path5.join(workspacePath, `${workspaceName}.code-workspace`);
1890
- let workspace;
1891
- if (fs5.existsSync(workspaceFilePath)) {
1892
- try {
1893
- const content = fs5.readFileSync(workspaceFilePath, "utf-8");
1894
- workspace = JSON.parse(content);
1895
- } catch {
1896
- workspace = { folders: [], settings: {} };
1897
- }
1898
- } else {
1899
- workspace = { folders: [], settings: {} };
1900
- }
1901
- if (!workspace.settings) {
1902
- workspace.settings = {};
1903
- }
1904
- workspace.folders = workspace.folders.filter(
1905
- (f) => f.path === "." || !f.name?.startsWith("\u{1F4C1}") && !f.name?.startsWith("\u{1F4DA}") && !f.name?.startsWith("\u{1F4CE}") && !f.name?.startsWith("\u{1F4CB}")
1906
- );
1907
- const mainFolderIndex = workspace.folders.findIndex((f) => f.path === ".");
1908
- if (mainFolderIndex === -1) {
1909
- workspace.folders.unshift({
1910
- path: ".",
1911
- name: `\u{1F3E0} ${workspaceName} (workspace)`
1912
- });
1913
- } else {
1914
- workspace.folders[mainFolderIndex] = {
1915
- path: ".",
1916
- name: `\u{1F3E0} ${workspaceName} (workspace)`
1917
- };
1918
- }
1919
- const referenceFolderPaths = [];
1920
- const isDetectedProjects = linkedProjects.length > 0 && typeof linkedProjects[0] === "object";
1921
- if (isDetectedProjects) {
1922
- const projects = linkedProjects;
1923
- for (const project of projects) {
1924
- const sourceLabel = project.source === "global" ? "global" : "local";
1925
- const folderPath = project.dataPath;
1926
- if (fs5.existsSync(folderPath)) {
1927
- referenceFolderPaths.push(folderPath);
1928
- workspace.folders.push({
1929
- path: folderPath,
1930
- name: `\u{1F4C1} ${project.name} [${sourceLabel}]`
1931
- });
1932
- }
1933
- }
1934
- } else {
1935
- const projectNames = linkedProjects;
1936
- const rrceHome = customGlobalPath || getRRCEHome();
1937
- for (const projectName of projectNames) {
1938
- const folderPath = path5.join(rrceHome, "workspaces", projectName);
1939
- if (fs5.existsSync(folderPath)) {
1940
- referenceFolderPaths.push(folderPath);
1941
- workspace.folders.push({
1942
- path: folderPath,
1943
- name: `\u{1F4C1} ${projectName} [global]`
1944
- });
1945
- }
1946
- }
1947
- }
1948
- if (referenceFolderPaths.length > 0) {
1949
- const readonlyPatterns = {};
1950
- for (const folderPath of referenceFolderPaths) {
1951
- readonlyPatterns[`${folderPath}/**`] = true;
1952
- }
1953
- const existingReadonly = workspace.settings["files.readonlyInclude"] || {};
1954
- const cleanedReadonly = {};
1955
- for (const [pattern, value] of Object.entries(existingReadonly)) {
1956
- if (!pattern.includes(".rrce-workflow") && !pattern.includes("rrce-workflow/workspaces")) {
1957
- cleanedReadonly[pattern] = value;
1958
- }
1959
- }
1960
- workspace.settings["files.readonlyInclude"] = {
1961
- ...cleanedReadonly,
1962
- ...readonlyPatterns
1963
- };
1964
- }
1965
- fs5.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, 2));
1966
- }
1967
-
1968
- // src/commands/wizard/setup-flow.ts
1969
- init_detection();
1970
- init_tui_utils();
2221
+ import { group, select as select3, multiselect as multiselect2, confirm as confirm2, spinner as spinner2, note as note3, outro as outro2, cancel as cancel2, isCancel as isCancel3 } from "@clack/prompts";
2222
+ import pc4 from "picocolors";
2223
+ import * as fs11 from "fs";
2224
+ import * as path12 from "path";
1971
2225
  async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
1972
- const s = spinner();
2226
+ const s = spinner2();
1973
2227
  const config = await group(
1974
2228
  {
1975
- storageMode: () => select2({
2229
+ storageMode: () => select3({
1976
2230
  message: "Where should workflow data be stored?",
1977
2231
  options: [
1978
2232
  { value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
@@ -1980,7 +2234,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
1980
2234
  ],
1981
2235
  initialValue: "global"
1982
2236
  }),
1983
- tools: () => multiselect({
2237
+ tools: () => multiselect2({
1984
2238
  message: "Which AI tools do you use?",
1985
2239
  options: [
1986
2240
  { value: "copilot", label: "GitHub Copilot", hint: "VSCode" },
@@ -1992,44 +2246,44 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
1992
2246
  if (existingProjects.length === 0) {
1993
2247
  return Promise.resolve([]);
1994
2248
  }
1995
- return multiselect({
2249
+ return multiselect2({
1996
2250
  message: "Link knowledge from other projects?",
1997
2251
  options: existingProjects.map((project) => ({
1998
2252
  value: `${project.name}:${project.source}`,
1999
2253
  // Unique key
2000
- label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
2001
- hint: pc3.dim(
2254
+ label: `${project.name} ${pc4.dim(`(${project.source})`)}`,
2255
+ hint: pc4.dim(
2002
2256
  project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
2003
2257
  )
2004
2258
  })),
2005
2259
  required: false
2006
2260
  });
2007
2261
  },
2008
- addToGitignore: () => confirm({
2262
+ addToGitignore: () => confirm2({
2009
2263
  message: "Add generated folders to .gitignore? (as comments - uncomment if needed)",
2010
2264
  initialValue: true
2011
2265
  }),
2012
- confirm: () => confirm({
2266
+ confirm: () => confirm2({
2013
2267
  message: "Create configuration?",
2014
2268
  initialValue: true
2015
2269
  })
2016
2270
  },
2017
2271
  {
2018
2272
  onCancel: () => {
2019
- cancel("Setup process cancelled.");
2273
+ cancel2("Setup process cancelled.");
2020
2274
  process.exit(0);
2021
2275
  }
2022
2276
  }
2023
2277
  );
2024
2278
  if (!config.confirm) {
2025
- outro("Setup cancelled by user.");
2279
+ outro2("Setup cancelled by user.");
2026
2280
  process.exit(0);
2027
2281
  }
2028
2282
  let customGlobalPath;
2029
2283
  if (config.storageMode === "global") {
2030
2284
  customGlobalPath = await resolveGlobalPath();
2031
2285
  if (!customGlobalPath) {
2032
- cancel("Setup cancelled - no writable global path available.");
2286
+ cancel2("Setup cancelled - no writable global path available.");
2033
2287
  process.exit(1);
2034
2288
  }
2035
2289
  }
@@ -2053,7 +2307,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
2053
2307
  `Storage: ${config.storageMode}`
2054
2308
  ];
2055
2309
  if (customGlobalPath && customGlobalPath !== getDefaultRRCEHome()) {
2056
- summary.push(`Global path: ${pc3.cyan(customGlobalPath)}`);
2310
+ summary.push(`Global path: ${pc4.cyan(customGlobalPath)}`);
2057
2311
  }
2058
2312
  if (dataPaths.length > 0) {
2059
2313
  summary.push(`Data paths:`);
@@ -2066,17 +2320,26 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
2066
2320
  const linkedProjects = config.linkedProjects;
2067
2321
  if (linkedProjects.length > 0) {
2068
2322
  summary.push(`Linked projects: ${linkedProjects.join(", ")}`);
2069
- summary.push(`Workspace file: ${pc3.cyan(`${workspaceName}.code-workspace`)}`);
2323
+ summary.push(`Workspace file: ${pc4.cyan(`${workspaceName}.code-workspace`)}`);
2070
2324
  }
2071
- note2(summary.join("\n"), "Setup Summary");
2072
- if (linkedProjects.length > 0) {
2073
- outro(pc3.green(`\u2713 Setup complete! Open ${pc3.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
2325
+ note3(summary.join("\n"), "Setup Summary");
2326
+ const shouldConfigureMCP = await confirm2({
2327
+ message: "Would you like to configure the MCP server now?",
2328
+ initialValue: true
2329
+ });
2330
+ if (shouldConfigureMCP && !isCancel3(shouldConfigureMCP)) {
2331
+ const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
2332
+ await runMCP2();
2074
2333
  } else {
2075
- outro(pc3.green(`\u2713 Setup complete! Your agents are ready to use.`));
2334
+ if (linkedProjects.length > 0) {
2335
+ outro2(pc4.green(`\u2713 Setup complete! Open ${pc4.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
2336
+ } else {
2337
+ outro2(pc4.green(`\u2713 Setup complete! Your agents are ready to use.`));
2338
+ }
2076
2339
  }
2077
2340
  } catch (error) {
2078
2341
  s.stop("Error occurred");
2079
- cancel(`Failed to setup: ${error instanceof Error ? error.message : String(error)}`);
2342
+ cancel2(`Failed to setup: ${error instanceof Error ? error.message : String(error)}`);
2080
2343
  process.exit(1);
2081
2344
  }
2082
2345
  }
@@ -2084,14 +2347,14 @@ async function generateConfiguration(config, workspacePath, workspaceName, allPr
2084
2347
  const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
2085
2348
  for (const dataPath of dataPaths) {
2086
2349
  ensureDir(dataPath);
2087
- ensureDir(path8.join(dataPath, "knowledge"));
2088
- ensureDir(path8.join(dataPath, "refs"));
2089
- ensureDir(path8.join(dataPath, "tasks"));
2090
- ensureDir(path8.join(dataPath, "templates"));
2350
+ ensureDir(path12.join(dataPath, "knowledge"));
2351
+ ensureDir(path12.join(dataPath, "refs"));
2352
+ ensureDir(path12.join(dataPath, "tasks"));
2353
+ ensureDir(path12.join(dataPath, "templates"));
2091
2354
  }
2092
2355
  const agentCoreDir = getAgentCoreDir();
2093
2356
  syncMetadataToAll(agentCoreDir, dataPaths);
2094
- copyDirToAllStoragePaths(path8.join(agentCoreDir, "templates"), "templates", dataPaths);
2357
+ copyDirToAllStoragePaths(path12.join(agentCoreDir, "templates"), "templates", dataPaths);
2095
2358
  const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
2096
2359
  if (config.tools.includes("copilot")) {
2097
2360
  const copilotPath = getAgentPromptPath(workspacePath, "copilot");
@@ -2103,8 +2366,8 @@ async function generateConfiguration(config, workspacePath, workspaceName, allPr
2103
2366
  ensureDir(antigravityPath);
2104
2367
  copyPromptsToDir(prompts, antigravityPath, ".md");
2105
2368
  }
2106
- const workspaceConfigPath = path8.join(workspacePath, ".rrce-workflow", "config.yaml");
2107
- ensureDir(path8.dirname(workspaceConfigPath));
2369
+ const workspaceConfigPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
2370
+ ensureDir(path12.dirname(workspaceConfigPath));
2108
2371
  let configContent = `# RRCE-Workflow Configuration
2109
2372
  version: 1
2110
2373
 
@@ -2132,7 +2395,7 @@ linked_projects:
2132
2395
  `;
2133
2396
  });
2134
2397
  }
2135
- fs7.writeFileSync(workspaceConfigPath, configContent);
2398
+ fs11.writeFileSync(workspaceConfigPath, configContent);
2136
2399
  if (config.addToGitignore) {
2137
2400
  updateGitignore(workspacePath, config.storageMode, config.tools);
2138
2401
  }
@@ -2144,8 +2407,8 @@ linked_projects:
2144
2407
  }
2145
2408
  }
2146
2409
  function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
2147
- const globalPath = path8.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
2148
- const workspacePath = path8.join(workspaceRoot, ".rrce-workflow");
2410
+ const globalPath = path12.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
2411
+ const workspacePath = path12.join(workspaceRoot, ".rrce-workflow");
2149
2412
  switch (mode) {
2150
2413
  case "global":
2151
2414
  return [globalPath];
@@ -2156,7 +2419,7 @@ function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
2156
2419
  }
2157
2420
  }
2158
2421
  function updateGitignore(workspacePath, storageMode, tools) {
2159
- const gitignorePath = path8.join(workspacePath, ".gitignore");
2422
+ const gitignorePath = path12.join(workspacePath, ".gitignore");
2160
2423
  const entries = [];
2161
2424
  if (storageMode === "workspace") {
2162
2425
  entries.push(".rrce-workflow/");
@@ -2172,8 +2435,8 @@ function updateGitignore(workspacePath, storageMode, tools) {
2172
2435
  }
2173
2436
  try {
2174
2437
  let content = "";
2175
- if (fs7.existsSync(gitignorePath)) {
2176
- content = fs7.readFileSync(gitignorePath, "utf-8");
2438
+ if (fs11.existsSync(gitignorePath)) {
2439
+ content = fs11.readFileSync(gitignorePath, "utf-8");
2177
2440
  }
2178
2441
  const lines = content.split("\n").map((line) => line.trim());
2179
2442
  const newEntries = [];
@@ -2198,57 +2461,66 @@ function updateGitignore(workspacePath, storageMode, tools) {
2198
2461
  newContent += "\n# rrce-workflow generated folders (uncomment to ignore)\n";
2199
2462
  }
2200
2463
  newContent += newEntries.map((e) => `# ${e}`).join("\n") + "\n";
2201
- fs7.writeFileSync(gitignorePath, newContent);
2464
+ fs11.writeFileSync(gitignorePath, newContent);
2202
2465
  return true;
2203
2466
  } catch {
2204
2467
  return false;
2205
2468
  }
2206
2469
  }
2470
+ var init_setup_flow = __esm({
2471
+ "src/commands/wizard/setup-flow.ts"() {
2472
+ "use strict";
2473
+ init_paths();
2474
+ init_prompts();
2475
+ init_utils();
2476
+ init_vscode();
2477
+ init_detection();
2478
+ init_tui_utils();
2479
+ }
2480
+ });
2207
2481
 
2208
2482
  // src/commands/wizard/link-flow.ts
2209
- init_paths();
2210
- import { multiselect as multiselect2, spinner as spinner2, note as note3, outro as outro2, cancel as cancel2, isCancel as isCancel3 } from "@clack/prompts";
2211
- import pc4 from "picocolors";
2212
- import * as fs8 from "fs";
2213
- init_detection();
2483
+ import { multiselect as multiselect3, spinner as spinner3, note as note4, outro as outro3, cancel as cancel3, isCancel as isCancel4 } from "@clack/prompts";
2484
+ import pc5 from "picocolors";
2485
+ import * as fs12 from "fs";
2214
2486
  async function runLinkProjectsFlow(workspacePath, workspaceName) {
2215
2487
  const projects = scanForProjects({
2216
2488
  excludeWorkspace: workspaceName,
2217
2489
  workspacePath
2218
2490
  });
2219
2491
  if (projects.length === 0) {
2220
- outro2(pc4.yellow("No other projects found. Try setting up another project first."));
2492
+ outro3(pc5.yellow("No other projects found. Try setting up another project first."));
2221
2493
  return;
2222
2494
  }
2223
2495
  const customGlobalPath = getEffectiveRRCEHome(workspacePath);
2224
- const linkedProjects = await multiselect2({
2496
+ const linkedProjects = await multiselect3({
2225
2497
  message: "Select projects to link:",
2226
2498
  options: projects.map((project) => ({
2227
2499
  value: `${project.name}:${project.source}`,
2228
2500
  // Unique key
2229
- label: `${project.name} ${pc4.dim(`(${project.source})`)}`,
2230
- hint: pc4.dim(
2501
+ label: `${project.name} ${pc5.dim(`(${project.source})`)}`,
2502
+ hint: pc5.dim(
2231
2503
  project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
2232
2504
  )
2233
2505
  })),
2234
2506
  required: true
2235
2507
  });
2236
- if (isCancel3(linkedProjects)) {
2237
- cancel2("Cancelled.");
2508
+ if (isCancel4(linkedProjects)) {
2509
+ cancel3("Cancelled.");
2238
2510
  process.exit(0);
2239
2511
  }
2240
2512
  const selectedKeys = linkedProjects;
2241
2513
  if (selectedKeys.length === 0) {
2242
- outro2("No projects selected.");
2514
+ outro3("No projects selected.");
2243
2515
  return;
2244
2516
  }
2245
2517
  const selectedProjects = projects.filter(
2246
2518
  (p) => selectedKeys.includes(`${p.name}:${p.source}`)
2247
2519
  );
2248
- const s = spinner2();
2520
+ const s = spinner3();
2249
2521
  s.start("Linking projects");
2250
2522
  const configFilePath = getConfigPath(workspacePath);
2251
- let configContent = fs8.readFileSync(configFilePath, "utf-8");
2523
+ let configContent = fs12.readFileSync(configFilePath, "utf-8");
2252
2524
  if (configContent.includes("linked_projects:")) {
2253
2525
  const lines = configContent.split("\n");
2254
2526
  const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
@@ -2275,60 +2547,67 @@ linked_projects:
2275
2547
  `;
2276
2548
  });
2277
2549
  }
2278
- fs8.writeFileSync(configFilePath, configContent);
2550
+ fs12.writeFileSync(configFilePath, configContent);
2279
2551
  generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
2280
2552
  s.stop("Projects linked");
2281
2553
  const workspaceFile = `${workspaceName}.code-workspace`;
2282
2554
  const summary = [
2283
2555
  `Linked projects:`,
2284
- ...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc4.dim(`(${p.source})`)}`),
2556
+ ...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc5.dim(`(${p.source})`)}`),
2285
2557
  ``,
2286
- `Workspace file: ${pc4.cyan(workspaceFile)}`
2558
+ `Workspace file: ${pc5.cyan(workspaceFile)}`
2287
2559
  ];
2288
- note3(summary.join("\n"), "Link Summary");
2289
- outro2(pc4.green(`\u2713 Projects linked! Open ${pc4.bold(workspaceFile)} in VSCode to access linked data.`));
2560
+ note4(summary.join("\n"), "Link Summary");
2561
+ outro3(pc5.green(`\u2713 Projects linked! Open ${pc5.bold(workspaceFile)} in VSCode to access linked data.`));
2290
2562
  }
2563
+ var init_link_flow = __esm({
2564
+ "src/commands/wizard/link-flow.ts"() {
2565
+ "use strict";
2566
+ init_paths();
2567
+ init_vscode();
2568
+ init_detection();
2569
+ }
2570
+ });
2291
2571
 
2292
2572
  // src/commands/wizard/sync-flow.ts
2293
- init_paths();
2294
- import { confirm as confirm2, spinner as spinner3, note as note4, outro as outro3, cancel as cancel3, isCancel as isCancel4 } from "@clack/prompts";
2295
- import pc5 from "picocolors";
2296
- import * as fs9 from "fs";
2297
- import * as path9 from "path";
2573
+ import { confirm as confirm3, spinner as spinner4, note as note5, outro as outro4, cancel as cancel4, isCancel as isCancel5 } from "@clack/prompts";
2574
+ import pc6 from "picocolors";
2575
+ import * as fs13 from "fs";
2576
+ import * as path13 from "path";
2298
2577
  async function runSyncToGlobalFlow(workspacePath, workspaceName) {
2299
2578
  const localPath = getLocalWorkspacePath(workspacePath);
2300
2579
  const customGlobalPath = getEffectiveRRCEHome(workspacePath);
2301
- const globalPath = path9.join(customGlobalPath, "workspaces", workspaceName);
2580
+ const globalPath = path13.join(customGlobalPath, "workspaces", workspaceName);
2302
2581
  const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
2303
2582
  const existingDirs = subdirs.filter(
2304
- (dir) => fs9.existsSync(path9.join(localPath, dir))
2583
+ (dir) => fs13.existsSync(path13.join(localPath, dir))
2305
2584
  );
2306
2585
  if (existingDirs.length === 0) {
2307
- outro3(pc5.yellow("No data found in workspace storage to sync."));
2586
+ outro4(pc6.yellow("No data found in workspace storage to sync."));
2308
2587
  return;
2309
2588
  }
2310
- note4(
2589
+ note5(
2311
2590
  `The following will be copied to global storage:
2312
2591
  ${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
2313
2592
 
2314
- Destination: ${pc5.cyan(globalPath)}`,
2593
+ Destination: ${pc6.cyan(globalPath)}`,
2315
2594
  "Sync Preview"
2316
2595
  );
2317
- const shouldSync = await confirm2({
2596
+ const shouldSync = await confirm3({
2318
2597
  message: "Proceed with sync to global storage?",
2319
2598
  initialValue: true
2320
2599
  });
2321
- if (isCancel4(shouldSync) || !shouldSync) {
2322
- outro3("Sync cancelled.");
2600
+ if (isCancel5(shouldSync) || !shouldSync) {
2601
+ outro4("Sync cancelled.");
2323
2602
  return;
2324
2603
  }
2325
- const s = spinner3();
2604
+ const s = spinner4();
2326
2605
  s.start("Syncing to global storage");
2327
2606
  try {
2328
2607
  ensureDir(globalPath);
2329
2608
  for (const dir of existingDirs) {
2330
- const srcDir = path9.join(localPath, dir);
2331
- const destDir = path9.join(globalPath, dir);
2609
+ const srcDir = path13.join(localPath, dir);
2610
+ const destDir = path13.join(globalPath, dir);
2332
2611
  ensureDir(destDir);
2333
2612
  copyDirRecursive(srcDir, destDir);
2334
2613
  }
@@ -2337,28 +2616,33 @@ Destination: ${pc5.cyan(globalPath)}`,
2337
2616
  `Synced directories:`,
2338
2617
  ...existingDirs.map((d) => ` \u2713 ${d}/`),
2339
2618
  ``,
2340
- `Global path: ${pc5.cyan(globalPath)}`,
2619
+ `Global path: ${pc6.cyan(globalPath)}`,
2341
2620
  ``,
2342
2621
  `Other projects can now link this knowledge!`
2343
2622
  ];
2344
- note4(summary.join("\n"), "Sync Summary");
2345
- outro3(pc5.green("\u2713 Workspace knowledge synced to global storage!"));
2623
+ note5(summary.join("\n"), "Sync Summary");
2624
+ outro4(pc6.green("\u2713 Workspace knowledge synced to global storage!"));
2346
2625
  } catch (error) {
2347
2626
  s.stop("Error occurred");
2348
- cancel3(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
2627
+ cancel4(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
2349
2628
  process.exit(1);
2350
2629
  }
2351
2630
  }
2631
+ var init_sync_flow = __esm({
2632
+ "src/commands/wizard/sync-flow.ts"() {
2633
+ "use strict";
2634
+ init_paths();
2635
+ init_utils();
2636
+ }
2637
+ });
2352
2638
 
2353
2639
  // src/commands/wizard/update-flow.ts
2354
- init_paths();
2355
- init_prompts();
2356
- import { confirm as confirm3, spinner as spinner4, note as note5, outro as outro4, cancel as cancel4, isCancel as isCancel5 } from "@clack/prompts";
2357
- import pc6 from "picocolors";
2358
- import * as fs10 from "fs";
2359
- import * as path10 from "path";
2640
+ import { confirm as confirm4, spinner as spinner5, note as note6, outro as outro5, cancel as cancel5, isCancel as isCancel6 } from "@clack/prompts";
2641
+ import pc7 from "picocolors";
2642
+ import * as fs14 from "fs";
2643
+ import * as path14 from "path";
2360
2644
  async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
2361
- const s = spinner4();
2645
+ const s = spinner5();
2362
2646
  s.start("Checking for updates");
2363
2647
  try {
2364
2648
  const agentCoreDir = getAgentCoreDir();
@@ -2367,7 +2651,7 @@ async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
2367
2651
  const customGlobalPath = getEffectiveRRCEHome(workspacePath);
2368
2652
  const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
2369
2653
  s.stop("Updates found");
2370
- note5(
2654
+ note6(
2371
2655
  `The following will be updated from the package:
2372
2656
  \u2022 prompts/ (${prompts.length} agent prompts)
2373
2657
  \u2022 templates/ (output templates)
@@ -2376,20 +2660,20 @@ Target locations:
2376
2660
  ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
2377
2661
  "Update Preview"
2378
2662
  );
2379
- const shouldUpdate = await confirm3({
2663
+ const shouldUpdate = await confirm4({
2380
2664
  message: "Proceed with update?",
2381
2665
  initialValue: true
2382
2666
  });
2383
- if (isCancel5(shouldUpdate) || !shouldUpdate) {
2384
- outro4("Update cancelled.");
2667
+ if (isCancel6(shouldUpdate) || !shouldUpdate) {
2668
+ outro5("Update cancelled.");
2385
2669
  return;
2386
2670
  }
2387
2671
  s.start("Updating from package");
2388
2672
  for (const dataPath of dataPaths) {
2389
- copyDirToAllStoragePaths(path10.join(agentCoreDir, "templates"), "templates", [dataPath]);
2673
+ copyDirToAllStoragePaths(path14.join(agentCoreDir, "templates"), "templates", [dataPath]);
2390
2674
  }
2391
2675
  const configFilePath = getConfigPath(workspacePath);
2392
- const configContent = fs10.readFileSync(configFilePath, "utf-8");
2676
+ const configContent = fs14.readFileSync(configFilePath, "utf-8");
2393
2677
  if (configContent.includes("copilot: true")) {
2394
2678
  const copilotPath = getAgentPromptPath(workspacePath, "copilot");
2395
2679
  ensureDir(copilotPath);
@@ -2408,17 +2692,17 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
2408
2692
  ``,
2409
2693
  `Your configuration and knowledge files were preserved.`
2410
2694
  ];
2411
- note5(summary.join("\n"), "Update Summary");
2412
- outro4(pc6.green("\u2713 Successfully updated from package!"));
2695
+ note6(summary.join("\n"), "Update Summary");
2696
+ outro5(pc7.green("\u2713 Successfully updated from package!"));
2413
2697
  } catch (error) {
2414
2698
  s.stop("Error occurred");
2415
- cancel4(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
2699
+ cancel5(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
2416
2700
  process.exit(1);
2417
2701
  }
2418
2702
  }
2419
2703
  function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
2420
- const globalPath = path10.join(customGlobalPath, "workspaces", workspaceName);
2421
- const workspacePath = path10.join(workspaceRoot, ".rrce-workflow");
2704
+ const globalPath = path14.join(customGlobalPath, "workspaces", workspaceName);
2705
+ const workspacePath = path14.join(workspaceRoot, ".rrce-workflow");
2422
2706
  switch (mode) {
2423
2707
  case "global":
2424
2708
  return [globalPath];
@@ -2428,20 +2712,35 @@ function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot,
2428
2712
  return [globalPath];
2429
2713
  }
2430
2714
  }
2715
+ var init_update_flow = __esm({
2716
+ "src/commands/wizard/update-flow.ts"() {
2717
+ "use strict";
2718
+ init_paths();
2719
+ init_prompts();
2720
+ init_utils();
2721
+ }
2722
+ });
2431
2723
 
2432
2724
  // src/commands/wizard/index.ts
2725
+ var wizard_exports = {};
2726
+ __export(wizard_exports, {
2727
+ runWizard: () => runWizard
2728
+ });
2729
+ import { intro as intro2, select as select4, spinner as spinner6, note as note7, outro as outro6, isCancel as isCancel7 } from "@clack/prompts";
2730
+ import pc8 from "picocolors";
2731
+ import * as fs15 from "fs";
2433
2732
  async function runWizard() {
2434
- intro(pc7.cyan(pc7.inverse(" RRCE-Workflow Setup ")));
2435
- const s = spinner5();
2733
+ intro2(pc8.cyan(pc8.inverse(" RRCE-Workflow Setup ")));
2734
+ const s = spinner6();
2436
2735
  s.start("Detecting environment");
2437
2736
  const workspacePath = detectWorkspaceRoot();
2438
2737
  const workspaceName = getWorkspaceName(workspacePath);
2439
2738
  const gitUser = getGitUser();
2440
2739
  await new Promise((r) => setTimeout(r, 800));
2441
2740
  s.stop("Environment detected");
2442
- note6(
2443
- `Git User: ${pc7.bold(gitUser || "(not found)")}
2444
- Workspace: ${pc7.bold(workspaceName)}`,
2741
+ note7(
2742
+ `Git User: ${pc8.bold(gitUser || "(not found)")}
2743
+ Workspace: ${pc8.bold(workspaceName)}`,
2445
2744
  "Context"
2446
2745
  );
2447
2746
  const detectedProjects = scanForProjects({
@@ -2449,44 +2748,53 @@ Workspace: ${pc7.bold(workspaceName)}`,
2449
2748
  workspacePath
2450
2749
  });
2451
2750
  const configFilePath = getConfigPath(workspacePath);
2452
- const isAlreadyConfigured = fs11.existsSync(configFilePath);
2751
+ const isAlreadyConfigured = fs15.existsSync(configFilePath);
2453
2752
  let currentStorageMode = null;
2454
2753
  if (isAlreadyConfigured) {
2455
2754
  try {
2456
- const configContent = fs11.readFileSync(configFilePath, "utf-8");
2755
+ const configContent = fs15.readFileSync(configFilePath, "utf-8");
2457
2756
  const modeMatch = configContent.match(/mode:\s*(global|workspace)/);
2458
2757
  currentStorageMode = modeMatch?.[1] ?? null;
2459
2758
  } catch {
2460
2759
  }
2461
2760
  }
2462
2761
  const localDataPath = getLocalWorkspacePath(workspacePath);
2463
- const hasLocalData = fs11.existsSync(localDataPath);
2762
+ const hasLocalData = fs15.existsSync(localDataPath);
2464
2763
  if (isAlreadyConfigured) {
2465
2764
  const menuOptions = [];
2765
+ menuOptions.push({
2766
+ value: "mcp",
2767
+ label: "\u{1F50C} Configure MCP Server",
2768
+ hint: "Expose projects to AI assistants (VSCode, Antigravity, Claude)"
2769
+ });
2466
2770
  if (detectedProjects.length > 0) {
2467
2771
  menuOptions.push({
2468
2772
  value: "link",
2469
- label: "Link other project knowledge",
2773
+ label: "\u{1F517} Link other project knowledge",
2470
2774
  hint: `${detectedProjects.length} projects detected (global + sibling)`
2471
2775
  });
2472
2776
  }
2473
2777
  if (currentStorageMode === "workspace" && hasLocalData) {
2474
2778
  menuOptions.push({
2475
2779
  value: "sync-global",
2476
- label: "Sync to global storage",
2780
+ label: "\u2601\uFE0F Sync to global storage",
2477
2781
  hint: "Share knowledge with other projects"
2478
2782
  });
2479
2783
  }
2480
- menuOptions.push({ value: "update", label: "Update from package", hint: "Get latest prompts & templates" });
2481
- menuOptions.push({ value: "exit", label: "Exit" });
2482
- const action = await select3({
2784
+ menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
2785
+ menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
2786
+ const action = await select4({
2483
2787
  message: "This workspace is already configured. What would you like to do?",
2484
2788
  options: menuOptions
2485
2789
  });
2486
- if (isCancel6(action) || action === "exit") {
2487
- outro5("Exited.");
2790
+ if (isCancel7(action) || action === "exit") {
2791
+ outro6("Exited.");
2488
2792
  process.exit(0);
2489
2793
  }
2794
+ if (action === "mcp") {
2795
+ await runMCP();
2796
+ return;
2797
+ }
2490
2798
  if (action === "link") {
2491
2799
  await runLinkProjectsFlow(workspacePath, workspaceName);
2492
2800
  return;
@@ -2502,6 +2810,22 @@ Workspace: ${pc7.bold(workspaceName)}`,
2502
2810
  }
2503
2811
  await runSetupFlow(workspacePath, workspaceName, detectedProjects);
2504
2812
  }
2813
+ var init_wizard = __esm({
2814
+ "src/commands/wizard/index.ts"() {
2815
+ "use strict";
2816
+ init_git();
2817
+ init_paths();
2818
+ init_detection();
2819
+ init_setup_flow();
2820
+ init_link_flow();
2821
+ init_sync_flow();
2822
+ init_update_flow();
2823
+ init_mcp();
2824
+ }
2825
+ });
2826
+
2827
+ // src/index.ts
2828
+ init_wizard();
2505
2829
 
2506
2830
  // src/commands/selector.ts
2507
2831
  init_prompts();
@@ -2521,9 +2845,14 @@ async function runSelector() {
2521
2845
  options: [
2522
2846
  {
2523
2847
  value: "mcp",
2524
- label: "Manage MCP Hub",
2848
+ label: "\u{1F50C} Manage MCP Hub",
2525
2849
  hint: "Configure & Start MCP Server"
2526
2850
  },
2851
+ {
2852
+ value: "wizard",
2853
+ label: "\u2728 Run Setup Wizard",
2854
+ hint: "Configure workspace & agents"
2855
+ },
2527
2856
  ...prompts.map((p) => ({
2528
2857
  value: p,
2529
2858
  label: p.frontmatter.name,
@@ -2540,6 +2869,11 @@ async function runSelector() {
2540
2869
  await runMCP2();
2541
2870
  return;
2542
2871
  }
2872
+ if (selection === "wizard") {
2873
+ const { runWizard: runWizard2 } = await Promise.resolve().then(() => (init_wizard(), wizard_exports));
2874
+ await runWizard2();
2875
+ return;
2876
+ }
2543
2877
  const prompt = selection;
2544
2878
  note8(
2545
2879
  `Use this agent in your IDE by invoking: