rrce-workflow 0.2.27 → 0.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +426 -180
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -583,7 +583,7 @@ var init_types = __esm({
|
|
|
583
583
|
});
|
|
584
584
|
|
|
585
585
|
// src/mcp/config.ts
|
|
586
|
-
import * as
|
|
586
|
+
import * as fs11 from "fs";
|
|
587
587
|
import * as path11 from "path";
|
|
588
588
|
function getMCPConfigPath() {
|
|
589
589
|
const workspaceRoot = detectWorkspaceRoot();
|
|
@@ -595,8 +595,8 @@ function ensureMCPGlobalPath() {
|
|
|
595
595
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
596
596
|
if (rrceHome.startsWith(".") || rrceHome.includes(".rrce-workflow/")) {
|
|
597
597
|
const configPath = path11.join(workspaceRoot, ".rrce-workflow", "config.yaml");
|
|
598
|
-
if (
|
|
599
|
-
const content =
|
|
598
|
+
if (fs11.existsSync(configPath)) {
|
|
599
|
+
const content = fs11.readFileSync(configPath, "utf-8");
|
|
600
600
|
const modeMatch = content.match(/mode:\s*(global|workspace)/);
|
|
601
601
|
if (modeMatch?.[1] === "workspace") {
|
|
602
602
|
return {
|
|
@@ -614,11 +614,11 @@ function ensureMCPGlobalPath() {
|
|
|
614
614
|
}
|
|
615
615
|
function loadMCPConfig() {
|
|
616
616
|
const configPath = getMCPConfigPath();
|
|
617
|
-
if (!
|
|
617
|
+
if (!fs11.existsSync(configPath)) {
|
|
618
618
|
return { ...DEFAULT_MCP_CONFIG };
|
|
619
619
|
}
|
|
620
620
|
try {
|
|
621
|
-
const content =
|
|
621
|
+
const content = fs11.readFileSync(configPath, "utf-8");
|
|
622
622
|
return parseMCPConfig(content);
|
|
623
623
|
} catch {
|
|
624
624
|
return { ...DEFAULT_MCP_CONFIG };
|
|
@@ -627,11 +627,11 @@ function loadMCPConfig() {
|
|
|
627
627
|
function saveMCPConfig(config) {
|
|
628
628
|
const configPath = getMCPConfigPath();
|
|
629
629
|
const dir = path11.dirname(configPath);
|
|
630
|
-
if (!
|
|
631
|
-
|
|
630
|
+
if (!fs11.existsSync(dir)) {
|
|
631
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
632
632
|
}
|
|
633
633
|
const content = serializeMCPConfig(config);
|
|
634
|
-
|
|
634
|
+
fs11.writeFileSync(configPath, content);
|
|
635
635
|
}
|
|
636
636
|
function parseMCPConfig(content) {
|
|
637
637
|
const config = { ...DEFAULT_MCP_CONFIG, projects: [] };
|
|
@@ -794,7 +794,7 @@ __export(logger_exports, {
|
|
|
794
794
|
getLogFilePath: () => getLogFilePath,
|
|
795
795
|
logger: () => logger
|
|
796
796
|
});
|
|
797
|
-
import * as
|
|
797
|
+
import * as fs12 from "fs";
|
|
798
798
|
import * as path12 from "path";
|
|
799
799
|
function getLogFilePath() {
|
|
800
800
|
const workspaceRoot = detectWorkspaceRoot();
|
|
@@ -831,10 +831,10 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
831
831
|
logMessage += "\n";
|
|
832
832
|
try {
|
|
833
833
|
const dir = path12.dirname(this.logPath);
|
|
834
|
-
if (!
|
|
835
|
-
|
|
834
|
+
if (!fs12.existsSync(dir)) {
|
|
835
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
836
836
|
}
|
|
837
|
-
|
|
837
|
+
fs12.appendFileSync(this.logPath, logMessage);
|
|
838
838
|
} catch (e) {
|
|
839
839
|
console.error(`[Logger Failure] Could not write to ${this.logPath}`, e);
|
|
840
840
|
console.error(logMessage);
|
|
@@ -858,7 +858,7 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
858
858
|
});
|
|
859
859
|
|
|
860
860
|
// src/mcp/resources.ts
|
|
861
|
-
import * as
|
|
861
|
+
import * as fs13 from "fs";
|
|
862
862
|
import * as path13 from "path";
|
|
863
863
|
function getExposedProjects() {
|
|
864
864
|
const config = loadMCPConfig();
|
|
@@ -887,10 +887,10 @@ function getProjectContext(projectName) {
|
|
|
887
887
|
return null;
|
|
888
888
|
}
|
|
889
889
|
const contextPath = path13.join(project.knowledgePath, "project-context.md");
|
|
890
|
-
if (!
|
|
890
|
+
if (!fs13.existsSync(contextPath)) {
|
|
891
891
|
return null;
|
|
892
892
|
}
|
|
893
|
-
return
|
|
893
|
+
return fs13.readFileSync(contextPath, "utf-8");
|
|
894
894
|
}
|
|
895
895
|
function getProjectTasks(projectName) {
|
|
896
896
|
const config = loadMCPConfig();
|
|
@@ -903,18 +903,18 @@ function getProjectTasks(projectName) {
|
|
|
903
903
|
}
|
|
904
904
|
const projects = scanForProjects();
|
|
905
905
|
const project = projects.find((p) => p.name === projectName);
|
|
906
|
-
if (!project?.tasksPath || !
|
|
906
|
+
if (!project?.tasksPath || !fs13.existsSync(project.tasksPath)) {
|
|
907
907
|
return [];
|
|
908
908
|
}
|
|
909
909
|
const tasks = [];
|
|
910
910
|
try {
|
|
911
|
-
const taskDirs =
|
|
911
|
+
const taskDirs = fs13.readdirSync(project.tasksPath, { withFileTypes: true });
|
|
912
912
|
for (const dir of taskDirs) {
|
|
913
913
|
if (!dir.isDirectory()) continue;
|
|
914
914
|
const metaPath = path13.join(project.tasksPath, dir.name, "meta.json");
|
|
915
|
-
if (
|
|
915
|
+
if (fs13.existsSync(metaPath)) {
|
|
916
916
|
try {
|
|
917
|
-
const meta = JSON.parse(
|
|
917
|
+
const meta = JSON.parse(fs13.readFileSync(metaPath, "utf-8"));
|
|
918
918
|
tasks.push(meta);
|
|
919
919
|
} catch {
|
|
920
920
|
}
|
|
@@ -933,11 +933,11 @@ function searchKnowledge(query) {
|
|
|
933
933
|
const permissions = getProjectPermissions(config, project.name);
|
|
934
934
|
if (!permissions.knowledge || !project.knowledgePath) continue;
|
|
935
935
|
try {
|
|
936
|
-
const files =
|
|
936
|
+
const files = fs13.readdirSync(project.knowledgePath);
|
|
937
937
|
for (const file of files) {
|
|
938
938
|
if (!file.endsWith(".md")) continue;
|
|
939
939
|
const filePath = path13.join(project.knowledgePath, file);
|
|
940
|
-
const content =
|
|
940
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
941
941
|
const lines = content.split("\n");
|
|
942
942
|
const matches = [];
|
|
943
943
|
for (const line of lines) {
|
|
@@ -1357,34 +1357,105 @@ var init_server = __esm({
|
|
|
1357
1357
|
});
|
|
1358
1358
|
|
|
1359
1359
|
// src/mcp/install.ts
|
|
1360
|
-
import * as
|
|
1360
|
+
import * as fs14 from "fs";
|
|
1361
1361
|
import * as path14 from "path";
|
|
1362
1362
|
import * as os from "os";
|
|
1363
|
-
function checkInstallStatus() {
|
|
1363
|
+
function checkInstallStatus(workspacePath) {
|
|
1364
1364
|
return {
|
|
1365
|
-
antigravity:
|
|
1366
|
-
claude:
|
|
1365
|
+
antigravity: checkAntigravityConfig(),
|
|
1366
|
+
claude: checkClaudeConfig(),
|
|
1367
|
+
vscodeGlobal: checkVSCodeGlobalConfig(),
|
|
1368
|
+
vscodeWorkspace: workspacePath ? checkVSCodeWorkspaceConfig(workspacePath) : false
|
|
1367
1369
|
};
|
|
1368
1370
|
}
|
|
1369
|
-
function
|
|
1370
|
-
if (!
|
|
1371
|
+
function checkAntigravityConfig() {
|
|
1372
|
+
if (!fs14.existsSync(ANTIGRAVITY_CONFIG)) return false;
|
|
1373
|
+
try {
|
|
1374
|
+
const content = JSON.parse(fs14.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
1375
|
+
return !!content.mcpServers?.["rrce"];
|
|
1376
|
+
} catch {
|
|
1377
|
+
return false;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
function checkClaudeConfig() {
|
|
1381
|
+
if (!fs14.existsSync(CLAUDE_CONFIG)) return false;
|
|
1371
1382
|
try {
|
|
1372
|
-
const content = JSON.parse(
|
|
1383
|
+
const content = JSON.parse(fs14.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
1373
1384
|
return !!content.mcpServers?.["rrce"];
|
|
1374
1385
|
} catch {
|
|
1375
1386
|
return false;
|
|
1376
1387
|
}
|
|
1377
1388
|
}
|
|
1378
|
-
function
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1389
|
+
function checkVSCodeGlobalConfig() {
|
|
1390
|
+
if (!fs14.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
|
|
1391
|
+
try {
|
|
1392
|
+
const content = JSON.parse(fs14.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
1393
|
+
return !!content["mcp.servers"]?.["rrce"];
|
|
1394
|
+
} catch {
|
|
1395
|
+
return false;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
function checkVSCodeWorkspaceConfig(workspacePath) {
|
|
1399
|
+
const configPath = path14.join(workspacePath, ".vscode", "mcp.json");
|
|
1400
|
+
if (!fs14.existsSync(configPath)) return false;
|
|
1401
|
+
try {
|
|
1402
|
+
const content = JSON.parse(fs14.readFileSync(configPath, "utf-8"));
|
|
1403
|
+
return !!content.servers?.["rrce"];
|
|
1404
|
+
} catch {
|
|
1405
|
+
return false;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function isInstalledAnywhere(workspacePath) {
|
|
1409
|
+
const status = checkInstallStatus(workspacePath);
|
|
1410
|
+
return status.antigravity || status.claude || status.vscodeGlobal || status.vscodeWorkspace;
|
|
1411
|
+
}
|
|
1412
|
+
function installToConfig(target, workspacePath) {
|
|
1413
|
+
switch (target) {
|
|
1414
|
+
case "antigravity":
|
|
1415
|
+
return installToAntigravity();
|
|
1416
|
+
case "claude":
|
|
1417
|
+
return installToClaude();
|
|
1418
|
+
case "vscode-global":
|
|
1419
|
+
return installToVSCodeGlobal();
|
|
1420
|
+
case "vscode-workspace":
|
|
1421
|
+
return workspacePath ? installToVSCodeWorkspace(workspacePath) : false;
|
|
1422
|
+
default:
|
|
1423
|
+
return false;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
function installToAntigravity() {
|
|
1427
|
+
const dir = path14.dirname(ANTIGRAVITY_CONFIG);
|
|
1428
|
+
if (!fs14.existsSync(dir)) {
|
|
1429
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
1430
|
+
}
|
|
1431
|
+
let config = { mcpServers: {} };
|
|
1432
|
+
if (fs14.existsSync(ANTIGRAVITY_CONFIG)) {
|
|
1433
|
+
try {
|
|
1434
|
+
config = JSON.parse(fs14.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
1435
|
+
} catch {
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
1439
|
+
config.mcpServers["rrce"] = {
|
|
1440
|
+
command: "npx",
|
|
1441
|
+
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1442
|
+
};
|
|
1443
|
+
try {
|
|
1444
|
+
fs14.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
|
|
1445
|
+
return true;
|
|
1446
|
+
} catch {
|
|
1447
|
+
return false;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
function installToClaude() {
|
|
1451
|
+
const dir = path14.dirname(CLAUDE_CONFIG);
|
|
1452
|
+
if (!fs14.existsSync(dir)) {
|
|
1453
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
1383
1454
|
}
|
|
1384
1455
|
let config = { mcpServers: {} };
|
|
1385
|
-
if (
|
|
1456
|
+
if (fs14.existsSync(CLAUDE_CONFIG)) {
|
|
1386
1457
|
try {
|
|
1387
|
-
config = JSON.parse(
|
|
1458
|
+
config = JSON.parse(fs14.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
1388
1459
|
} catch {
|
|
1389
1460
|
}
|
|
1390
1461
|
}
|
|
@@ -1392,21 +1463,84 @@ function installToConfig(target) {
|
|
|
1392
1463
|
config.mcpServers["rrce"] = {
|
|
1393
1464
|
command: "npx",
|
|
1394
1465
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1395
|
-
// -y to avoid interactive prompts
|
|
1396
1466
|
};
|
|
1397
1467
|
try {
|
|
1398
|
-
|
|
1468
|
+
fs14.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
|
|
1469
|
+
return true;
|
|
1470
|
+
} catch {
|
|
1471
|
+
return false;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
function installToVSCodeGlobal() {
|
|
1475
|
+
const dir = path14.dirname(VSCODE_GLOBAL_CONFIG);
|
|
1476
|
+
if (!fs14.existsSync(dir)) {
|
|
1477
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
1478
|
+
}
|
|
1479
|
+
let settings = {};
|
|
1480
|
+
if (fs14.existsSync(VSCODE_GLOBAL_CONFIG)) {
|
|
1481
|
+
try {
|
|
1482
|
+
settings = JSON.parse(fs14.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
1483
|
+
} catch {
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
if (!settings["mcp.servers"]) settings["mcp.servers"] = {};
|
|
1487
|
+
settings["mcp.servers"]["rrce"] = {
|
|
1488
|
+
command: "npx",
|
|
1489
|
+
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1490
|
+
};
|
|
1491
|
+
try {
|
|
1492
|
+
fs14.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
|
|
1399
1493
|
return true;
|
|
1400
1494
|
} catch {
|
|
1401
1495
|
return false;
|
|
1402
1496
|
}
|
|
1403
1497
|
}
|
|
1404
|
-
|
|
1498
|
+
function installToVSCodeWorkspace(workspacePath) {
|
|
1499
|
+
const vscodeDir = path14.join(workspacePath, ".vscode");
|
|
1500
|
+
const configPath = path14.join(vscodeDir, "mcp.json");
|
|
1501
|
+
if (!fs14.existsSync(vscodeDir)) {
|
|
1502
|
+
fs14.mkdirSync(vscodeDir, { recursive: true });
|
|
1503
|
+
}
|
|
1504
|
+
let config = { servers: {} };
|
|
1505
|
+
if (fs14.existsSync(configPath)) {
|
|
1506
|
+
try {
|
|
1507
|
+
config = JSON.parse(fs14.readFileSync(configPath, "utf-8"));
|
|
1508
|
+
} catch {
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
if (!config.servers) config.servers = {};
|
|
1512
|
+
config.servers["rrce"] = {
|
|
1513
|
+
command: "npx",
|
|
1514
|
+
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1515
|
+
};
|
|
1516
|
+
try {
|
|
1517
|
+
fs14.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
1518
|
+
return true;
|
|
1519
|
+
} catch {
|
|
1520
|
+
return false;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
function getTargetLabel(target) {
|
|
1524
|
+
switch (target) {
|
|
1525
|
+
case "antigravity":
|
|
1526
|
+
return "Antigravity IDE";
|
|
1527
|
+
case "claude":
|
|
1528
|
+
return "Claude Desktop";
|
|
1529
|
+
case "vscode-global":
|
|
1530
|
+
return "VSCode (Global)";
|
|
1531
|
+
case "vscode-workspace":
|
|
1532
|
+
return "VSCode (Workspace)";
|
|
1533
|
+
default:
|
|
1534
|
+
return target;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG, VSCODE_GLOBAL_CONFIG;
|
|
1405
1538
|
var init_install = __esm({
|
|
1406
1539
|
"src/mcp/install.ts"() {
|
|
1407
1540
|
"use strict";
|
|
1408
1541
|
ANTIGRAVITY_CONFIG = path14.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
|
|
1409
1542
|
CLAUDE_CONFIG = path14.join(os.homedir(), ".config/claude/claude_desktop_config.json");
|
|
1543
|
+
VSCODE_GLOBAL_CONFIG = path14.join(os.homedir(), ".config/Code/User/settings.json");
|
|
1410
1544
|
}
|
|
1411
1545
|
});
|
|
1412
1546
|
|
|
@@ -1415,8 +1549,8 @@ var mcp_exports = {};
|
|
|
1415
1549
|
__export(mcp_exports, {
|
|
1416
1550
|
runMCP: () => runMCP
|
|
1417
1551
|
});
|
|
1418
|
-
import { intro
|
|
1419
|
-
import
|
|
1552
|
+
import { intro, outro as outro5, select as select3, multiselect as multiselect3, confirm as confirm4, spinner as spinner5, note as note6, cancel as cancel5, isCancel as isCancel6, text as text2 } from "@clack/prompts";
|
|
1553
|
+
import pc7 from "picocolors";
|
|
1420
1554
|
async function runMCP(subcommand2) {
|
|
1421
1555
|
if (subcommand2) {
|
|
1422
1556
|
switch (subcommand2) {
|
|
@@ -1436,42 +1570,69 @@ async function runMCP(subcommand2) {
|
|
|
1436
1570
|
return;
|
|
1437
1571
|
}
|
|
1438
1572
|
}
|
|
1439
|
-
|
|
1573
|
+
intro(pc7.bgCyan(pc7.black(" RRCE MCP Hub ")));
|
|
1574
|
+
const workspacePath = detectWorkspaceRoot();
|
|
1440
1575
|
const globalPathCheck = await ensureMCPGlobalPath();
|
|
1441
1576
|
if (!globalPathCheck.configured) {
|
|
1442
1577
|
const configured = await handleConfigureGlobalPath();
|
|
1443
1578
|
if (!configured) {
|
|
1444
|
-
|
|
1579
|
+
outro5(pc7.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
1445
1580
|
return;
|
|
1446
1581
|
}
|
|
1447
1582
|
}
|
|
1448
|
-
const status = checkInstallStatus();
|
|
1449
|
-
|
|
1583
|
+
const status = checkInstallStatus(workspacePath);
|
|
1584
|
+
const installed = isInstalledAnywhere(workspacePath);
|
|
1585
|
+
if (!installed) {
|
|
1586
|
+
note6(
|
|
1587
|
+
`${pc7.bold("Welcome to RRCE MCP Hub!")}
|
|
1588
|
+
|
|
1589
|
+
MCP (Model Context Protocol) allows AI assistants to access your
|
|
1590
|
+
project knowledge in real-time. Let's get you set up.`,
|
|
1591
|
+
"Getting Started"
|
|
1592
|
+
);
|
|
1450
1593
|
const shouldInstall = await confirm4({
|
|
1451
|
-
message: "MCP server
|
|
1594
|
+
message: "Install MCP server to your IDE(s)?",
|
|
1452
1595
|
initialValue: true
|
|
1453
1596
|
});
|
|
1454
|
-
if (shouldInstall && !
|
|
1455
|
-
await handleInstallWizard();
|
|
1597
|
+
if (shouldInstall && !isCancel6(shouldInstall)) {
|
|
1598
|
+
await handleInstallWizard(workspacePath);
|
|
1599
|
+
await handleConfigure();
|
|
1600
|
+
const shouldStart = await confirm4({
|
|
1601
|
+
message: "Start the MCP server now?",
|
|
1602
|
+
initialValue: true
|
|
1603
|
+
});
|
|
1604
|
+
if (shouldStart && !isCancel6(shouldStart)) {
|
|
1605
|
+
await handleStartServer();
|
|
1606
|
+
}
|
|
1456
1607
|
}
|
|
1608
|
+
outro5(pc7.green("MCP Hub setup complete!"));
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
const config = loadMCPConfig();
|
|
1612
|
+
const exposedCount = config.projects.filter((p) => p.expose).length;
|
|
1613
|
+
if (exposedCount === 0 && !config.defaults.includeNew) {
|
|
1614
|
+
note6("MCP is installed but no projects are exposed. Let's configure that.", "Configuration Needed");
|
|
1615
|
+
await handleConfigure();
|
|
1457
1616
|
}
|
|
1458
1617
|
let running = true;
|
|
1459
1618
|
while (running) {
|
|
1460
1619
|
const serverStatus = getMCPServerStatus();
|
|
1461
|
-
const serverLabel = serverStatus.running ?
|
|
1462
|
-
const
|
|
1620
|
+
const serverLabel = serverStatus.running ? pc7.green("\u25CF Running") : pc7.dim("\u25CB Stopped");
|
|
1621
|
+
const currentStatus = checkInstallStatus(workspacePath);
|
|
1622
|
+
const installedCount = [currentStatus.antigravity, currentStatus.claude, currentStatus.vscodeGlobal, currentStatus.vscodeWorkspace].filter(Boolean).length;
|
|
1623
|
+
const action = await select3({
|
|
1463
1624
|
message: "What would you like to do?",
|
|
1464
1625
|
options: [
|
|
1465
|
-
{ value: "start", label: `\u25B6\uFE0F Start MCP server`, hint:
|
|
1626
|
+
{ value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: serverLabel },
|
|
1466
1627
|
{ value: "configure", label: "\u2699\uFE0F Configure projects", hint: "Choose which projects to expose" },
|
|
1467
|
-
{ value: "install", label: "\u{1F4E5} Install to IDE", hint:
|
|
1628
|
+
{ value: "install", label: "\u{1F4E5} Install to IDE", hint: `${installedCount} IDE(s) configured` },
|
|
1468
1629
|
{ value: "status", label: "\u{1F4CB} View status", hint: "See details" },
|
|
1469
1630
|
{ value: "help", label: "\u2753 Help", hint: "Learn about MCP Hub" },
|
|
1470
1631
|
{ value: "exit", label: "\u21A9 Exit", hint: "Return to shell" }
|
|
1471
1632
|
]
|
|
1472
1633
|
});
|
|
1473
|
-
if (
|
|
1474
|
-
|
|
1634
|
+
if (isCancel6(action)) {
|
|
1635
|
+
cancel5("MCP Hub closed.");
|
|
1475
1636
|
return;
|
|
1476
1637
|
}
|
|
1477
1638
|
switch (action) {
|
|
@@ -1482,7 +1643,7 @@ async function runMCP(subcommand2) {
|
|
|
1482
1643
|
await handleConfigure();
|
|
1483
1644
|
break;
|
|
1484
1645
|
case "install":
|
|
1485
|
-
await handleInstallWizard();
|
|
1646
|
+
await handleInstallWizard(workspacePath);
|
|
1486
1647
|
break;
|
|
1487
1648
|
case "status":
|
|
1488
1649
|
await handleShowStatus();
|
|
@@ -1495,46 +1656,72 @@ async function runMCP(subcommand2) {
|
|
|
1495
1656
|
break;
|
|
1496
1657
|
}
|
|
1497
1658
|
}
|
|
1498
|
-
|
|
1659
|
+
outro5(pc7.green("MCP Hub closed."));
|
|
1499
1660
|
}
|
|
1500
|
-
async function handleInstallWizard() {
|
|
1501
|
-
const status = checkInstallStatus();
|
|
1661
|
+
async function handleInstallWizard(workspacePath) {
|
|
1662
|
+
const status = checkInstallStatus(workspacePath);
|
|
1502
1663
|
const options = [
|
|
1503
|
-
{
|
|
1504
|
-
|
|
1664
|
+
{
|
|
1665
|
+
value: "antigravity",
|
|
1666
|
+
label: "Antigravity IDE",
|
|
1667
|
+
hint: status.antigravity ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
value: "vscode-global",
|
|
1671
|
+
label: "VSCode (Global)",
|
|
1672
|
+
hint: status.vscodeGlobal ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")
|
|
1673
|
+
},
|
|
1674
|
+
{
|
|
1675
|
+
value: "vscode-workspace",
|
|
1676
|
+
label: "VSCode (This Workspace)",
|
|
1677
|
+
hint: status.vscodeWorkspace ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
value: "claude",
|
|
1681
|
+
label: "Claude Desktop",
|
|
1682
|
+
hint: status.claude ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")
|
|
1683
|
+
}
|
|
1505
1684
|
];
|
|
1506
1685
|
const selected = await multiselect3({
|
|
1507
1686
|
message: "Select where to install RRCE MCP Server:",
|
|
1508
1687
|
options,
|
|
1509
1688
|
initialValues: [
|
|
1510
1689
|
...status.antigravity ? ["antigravity"] : [],
|
|
1690
|
+
...status.vscodeGlobal ? ["vscode-global"] : [],
|
|
1691
|
+
...status.vscodeWorkspace ? ["vscode-workspace"] : [],
|
|
1511
1692
|
...status.claude ? ["claude"] : []
|
|
1512
1693
|
],
|
|
1513
1694
|
required: false
|
|
1514
1695
|
});
|
|
1515
|
-
if (
|
|
1696
|
+
if (isCancel6(selected)) return;
|
|
1516
1697
|
const targets = selected;
|
|
1517
1698
|
const results = [];
|
|
1518
1699
|
for (const target of targets) {
|
|
1519
|
-
const success = installToConfig(target);
|
|
1520
|
-
|
|
1700
|
+
const success = installToConfig(target, workspacePath);
|
|
1701
|
+
const label = getTargetLabel(target);
|
|
1702
|
+
results.push(`${label}: ${success ? pc7.green("\u2713 Success") : pc7.red("\u2717 Failed")}`);
|
|
1521
1703
|
}
|
|
1522
1704
|
if (results.length > 0) {
|
|
1523
|
-
|
|
1705
|
+
note6(results.join("\n"), "Installation Results");
|
|
1524
1706
|
}
|
|
1525
1707
|
}
|
|
1526
1708
|
async function handleStartServer() {
|
|
1527
1709
|
const fs16 = await import("fs");
|
|
1528
1710
|
const { getLogFilePath: getLogFilePath2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
1529
1711
|
const config = loadMCPConfig();
|
|
1530
|
-
const
|
|
1531
|
-
|
|
1712
|
+
const projects = scanForProjects();
|
|
1713
|
+
const exposedProjects = projects.filter((p) => {
|
|
1714
|
+
const cfg = config.projects.find((c) => c.name === p.name);
|
|
1715
|
+
return cfg?.expose ?? config.defaults.includeNew;
|
|
1716
|
+
});
|
|
1717
|
+
if (exposedProjects.length === 0) {
|
|
1532
1718
|
const shouldConfig = await confirm4({
|
|
1533
1719
|
message: "No projects are currently exposed. Configure now?",
|
|
1534
1720
|
initialValue: true
|
|
1535
1721
|
});
|
|
1536
|
-
if (shouldConfig && !
|
|
1722
|
+
if (shouldConfig && !isCancel6(shouldConfig)) {
|
|
1537
1723
|
await handleConfigure();
|
|
1724
|
+
return handleStartServer();
|
|
1538
1725
|
}
|
|
1539
1726
|
}
|
|
1540
1727
|
const portInput = await text2({
|
|
@@ -1545,7 +1732,7 @@ async function handleStartServer() {
|
|
|
1545
1732
|
if (isNaN(Number(value))) return "Port must be a number";
|
|
1546
1733
|
}
|
|
1547
1734
|
});
|
|
1548
|
-
if (
|
|
1735
|
+
if (isCancel6(portInput)) return;
|
|
1549
1736
|
const newPort = parseInt(portInput, 10);
|
|
1550
1737
|
if (newPort !== config.server.port) {
|
|
1551
1738
|
config.server.port = newPort;
|
|
@@ -1553,23 +1740,33 @@ async function handleStartServer() {
|
|
|
1553
1740
|
}
|
|
1554
1741
|
console.clear();
|
|
1555
1742
|
const logPath = getLogFilePath2();
|
|
1556
|
-
const
|
|
1743
|
+
const workspacePath = detectWorkspaceRoot();
|
|
1744
|
+
const exposedNames = exposedProjects.map((p) => p.name).slice(0, 5);
|
|
1745
|
+
const exposedLabel = exposedNames.length > 0 ? exposedNames.join(", ") + (exposedProjects.length > 5 ? ` (+${exposedProjects.length - 5} more)` : "") : pc7.dim("(none)");
|
|
1746
|
+
const render = (logs = []) => {
|
|
1557
1747
|
console.clear();
|
|
1558
|
-
console.log(
|
|
1559
|
-
console.log(
|
|
1560
|
-
console.log(
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1748
|
+
console.log(pc7.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"));
|
|
1749
|
+
console.log(pc7.cyan("\u2551") + pc7.bold(pc7.white(" RRCE MCP Hub Running ")) + pc7.cyan("\u2551"));
|
|
1750
|
+
console.log(pc7.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"));
|
|
1751
|
+
const logLines = logs.slice(-10);
|
|
1752
|
+
const emptyLines = 10 - logLines.length;
|
|
1753
|
+
for (let i = 0; i < emptyLines; i++) {
|
|
1754
|
+
console.log(pc7.cyan("\u2551") + " ".repeat(63) + pc7.cyan("\u2551"));
|
|
1755
|
+
}
|
|
1756
|
+
for (const line of logLines) {
|
|
1757
|
+
const truncated = line.substring(0, 61).padEnd(61);
|
|
1758
|
+
console.log(pc7.cyan("\u2551") + " " + pc7.dim(truncated) + " " + pc7.cyan("\u2551"));
|
|
1759
|
+
}
|
|
1760
|
+
console.log(pc7.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"));
|
|
1761
|
+
const infoLine = ` \u{1F4CB} ${exposedLabel} \u2502 Port: ${newPort} \u2502 PID: ${process.pid}`.substring(0, 61).padEnd(61);
|
|
1762
|
+
console.log(pc7.cyan("\u2551") + pc7.yellow(infoLine) + " " + pc7.cyan("\u2551"));
|
|
1763
|
+
console.log(pc7.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"));
|
|
1764
|
+
const cmdLine = ` q:Quit p:Projects i:Install r:Reload c:Clear ?:Help`;
|
|
1765
|
+
console.log(pc7.cyan("\u2551") + pc7.dim(cmdLine.padEnd(63)) + pc7.cyan("\u2551"));
|
|
1766
|
+
console.log(pc7.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"));
|
|
1565
1767
|
};
|
|
1566
|
-
|
|
1567
|
-
|
|
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`);
|
|
1570
|
-
};
|
|
1571
|
-
renderHeader();
|
|
1572
|
-
renderFooter();
|
|
1768
|
+
let logBuffer = [];
|
|
1769
|
+
render(logBuffer);
|
|
1573
1770
|
try {
|
|
1574
1771
|
await startMCPServer();
|
|
1575
1772
|
let lastSize = 0;
|
|
@@ -1584,14 +1781,59 @@ async function handleStartServer() {
|
|
|
1584
1781
|
process.stdin.setEncoding("utf8");
|
|
1585
1782
|
}
|
|
1586
1783
|
return new Promise((resolve) => {
|
|
1784
|
+
const cleanup = () => {
|
|
1785
|
+
isRunning = false;
|
|
1786
|
+
clearInterval(interval);
|
|
1787
|
+
if (process.stdin.setRawMode) {
|
|
1788
|
+
process.stdin.setRawMode(false);
|
|
1789
|
+
}
|
|
1790
|
+
process.stdin.removeListener("data", onKey);
|
|
1791
|
+
process.stdin.pause();
|
|
1792
|
+
stopMCPServer();
|
|
1793
|
+
console.log("");
|
|
1794
|
+
};
|
|
1587
1795
|
const onKey = async (key) => {
|
|
1588
1796
|
if (key === "" || key.toLowerCase() === "q") {
|
|
1589
1797
|
cleanup();
|
|
1590
1798
|
resolve();
|
|
1799
|
+
return;
|
|
1800
|
+
}
|
|
1801
|
+
if (key.toLowerCase() === "p") {
|
|
1802
|
+
cleanup();
|
|
1803
|
+
console.clear();
|
|
1804
|
+
await handleConfigure();
|
|
1805
|
+
resolve();
|
|
1806
|
+
return;
|
|
1591
1807
|
}
|
|
1592
|
-
if (key.toLowerCase() === "
|
|
1808
|
+
if (key.toLowerCase() === "i") {
|
|
1593
1809
|
cleanup();
|
|
1810
|
+
console.clear();
|
|
1811
|
+
await handleInstallWizard(workspacePath);
|
|
1594
1812
|
resolve();
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
if (key.toLowerCase() === "r") {
|
|
1816
|
+
logBuffer.push("[INFO] Reloading configuration...");
|
|
1817
|
+
render(logBuffer);
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
if (key.toLowerCase() === "c") {
|
|
1821
|
+
logBuffer = [];
|
|
1822
|
+
render(logBuffer);
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
if (key === "?") {
|
|
1826
|
+
logBuffer.push("\u2500".repeat(40));
|
|
1827
|
+
logBuffer.push("Commands:");
|
|
1828
|
+
logBuffer.push(" q - Stop server and return to menu");
|
|
1829
|
+
logBuffer.push(" p - Reconfigure exposed projects");
|
|
1830
|
+
logBuffer.push(" i - Install to additional IDEs");
|
|
1831
|
+
logBuffer.push(" r - Reload configuration");
|
|
1832
|
+
logBuffer.push(" c - Clear log display");
|
|
1833
|
+
logBuffer.push(" ? - Show this help");
|
|
1834
|
+
logBuffer.push("\u2500".repeat(40));
|
|
1835
|
+
render(logBuffer);
|
|
1836
|
+
return;
|
|
1595
1837
|
}
|
|
1596
1838
|
};
|
|
1597
1839
|
process.stdin.on("data", onKey);
|
|
@@ -1600,35 +1842,27 @@ async function handleStartServer() {
|
|
|
1600
1842
|
if (fs16.existsSync(logPath)) {
|
|
1601
1843
|
const stats = fs16.statSync(logPath);
|
|
1602
1844
|
if (stats.size > lastSize) {
|
|
1603
|
-
const
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1845
|
+
const buffer = Buffer.alloc(stats.size - lastSize);
|
|
1846
|
+
const fd = fs16.openSync(logPath, "r");
|
|
1847
|
+
fs16.readSync(fd, buffer, 0, buffer.length, lastSize);
|
|
1848
|
+
fs16.closeSync(fd);
|
|
1849
|
+
const newContent = buffer.toString("utf-8");
|
|
1850
|
+
const newLines = newContent.split("\n").filter((l) => l.trim());
|
|
1851
|
+
logBuffer.push(...newLines);
|
|
1852
|
+
if (logBuffer.length > 100) {
|
|
1853
|
+
logBuffer = logBuffer.slice(-100);
|
|
1854
|
+
}
|
|
1611
1855
|
lastSize = stats.size;
|
|
1856
|
+
render(logBuffer);
|
|
1612
1857
|
}
|
|
1613
1858
|
}
|
|
1614
1859
|
}, 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
1860
|
});
|
|
1627
1861
|
} catch (error) {
|
|
1628
1862
|
if (process.stdin.setRawMode) {
|
|
1629
1863
|
process.stdin.setRawMode(false);
|
|
1630
1864
|
}
|
|
1631
|
-
console.error(
|
|
1865
|
+
console.error(pc7.red("\nFailed to start server:"));
|
|
1632
1866
|
console.error(error);
|
|
1633
1867
|
}
|
|
1634
1868
|
}
|
|
@@ -1636,11 +1870,11 @@ async function handleConfigureGlobalPath() {
|
|
|
1636
1870
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
1637
1871
|
const fs16 = await import("fs");
|
|
1638
1872
|
const path16 = await import("path");
|
|
1639
|
-
|
|
1640
|
-
`MCP Hub requires a ${
|
|
1873
|
+
note6(
|
|
1874
|
+
`MCP Hub requires a ${pc7.bold("global storage path")} to store its configuration
|
|
1641
1875
|
and coordinate across projects.
|
|
1642
1876
|
|
|
1643
|
-
Your current setup uses ${
|
|
1877
|
+
Your current setup uses ${pc7.cyan("workspace")} mode, which stores data
|
|
1644
1878
|
locally in each project. MCP needs a central location.`,
|
|
1645
1879
|
"Global Path Required"
|
|
1646
1880
|
);
|
|
@@ -1654,8 +1888,8 @@ locally in each project. MCP needs a central location.`,
|
|
|
1654
1888
|
}
|
|
1655
1889
|
const config = loadMCPConfig();
|
|
1656
1890
|
saveMCPConfig(config);
|
|
1657
|
-
|
|
1658
|
-
`${
|
|
1891
|
+
note6(
|
|
1892
|
+
`${pc7.green("\u2713")} Global path configured: ${pc7.cyan(resolvedPath)}
|
|
1659
1893
|
|
|
1660
1894
|
MCP config will be stored at:
|
|
1661
1895
|
${path16.join(resolvedPath, "mcp.yaml")}`,
|
|
@@ -1663,54 +1897,63 @@ ${path16.join(resolvedPath, "mcp.yaml")}`,
|
|
|
1663
1897
|
);
|
|
1664
1898
|
return true;
|
|
1665
1899
|
} catch (error) {
|
|
1666
|
-
|
|
1667
|
-
`${
|
|
1900
|
+
note6(
|
|
1901
|
+
`${pc7.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
|
|
1668
1902
|
"Error"
|
|
1669
1903
|
);
|
|
1670
1904
|
return false;
|
|
1671
1905
|
}
|
|
1672
1906
|
}
|
|
1673
1907
|
async function handleShowStatus() {
|
|
1674
|
-
const s =
|
|
1908
|
+
const s = spinner5();
|
|
1675
1909
|
s.start("Loading projects...");
|
|
1676
1910
|
const config = loadMCPConfig();
|
|
1677
1911
|
const projects = scanForProjects();
|
|
1912
|
+
const workspacePath = detectWorkspaceRoot();
|
|
1913
|
+
const installStatus = checkInstallStatus(workspacePath);
|
|
1678
1914
|
s.stop("Projects loaded");
|
|
1679
1915
|
if (projects.length === 0) {
|
|
1680
|
-
|
|
1916
|
+
note6('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
1681
1917
|
return;
|
|
1682
1918
|
}
|
|
1683
1919
|
const lines = [
|
|
1684
|
-
`${
|
|
1920
|
+
`${pc7.bold("Installation Status")}`,
|
|
1921
|
+
"",
|
|
1922
|
+
` Antigravity: ${installStatus.antigravity ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
1923
|
+
` VSCode (Global): ${installStatus.vscodeGlobal ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
1924
|
+
` VSCode (Workspace): ${installStatus.vscodeWorkspace ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
1925
|
+
` Claude Desktop: ${installStatus.claude ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
1926
|
+
"",
|
|
1927
|
+
`${pc7.bold("Project Status")}`,
|
|
1685
1928
|
""
|
|
1686
1929
|
];
|
|
1687
1930
|
for (const project of projects) {
|
|
1688
1931
|
const projectConfig = config.projects.find((p) => p.name === project.name);
|
|
1689
1932
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
1690
|
-
const status = isExposed ?
|
|
1691
|
-
const source =
|
|
1933
|
+
const status = isExposed ? pc7.green("\u2713 exposed") : pc7.dim("\u25CB hidden");
|
|
1934
|
+
const source = pc7.dim(`(${project.source})`);
|
|
1692
1935
|
lines.push(` ${status} ${project.name} ${source}`);
|
|
1693
1936
|
}
|
|
1694
1937
|
lines.push("");
|
|
1695
|
-
lines.push(
|
|
1938
|
+
lines.push(pc7.dim(`Config: ${getMCPConfigPath()}`));
|
|
1696
1939
|
const serverStatus = getMCPServerStatus();
|
|
1697
1940
|
if (serverStatus.running) {
|
|
1698
|
-
lines.push(
|
|
1941
|
+
lines.push(pc7.green(`Server: running on port ${serverStatus.port}`));
|
|
1699
1942
|
} else {
|
|
1700
|
-
lines.push(
|
|
1943
|
+
lines.push(pc7.dim("Server: not running"));
|
|
1701
1944
|
}
|
|
1702
|
-
|
|
1945
|
+
note6(lines.join("\n"), "MCP Hub Status");
|
|
1703
1946
|
}
|
|
1704
1947
|
async function handleConfigure() {
|
|
1705
1948
|
const { logger: logger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
1706
|
-
const s =
|
|
1949
|
+
const s = spinner5();
|
|
1707
1950
|
s.start("Scanning for projects...");
|
|
1708
1951
|
const config = loadMCPConfig();
|
|
1709
1952
|
const projects = scanForProjects();
|
|
1710
1953
|
logger2.info("Configure: Loaded config", { projects: config.projects, defaultMode: config.defaults.includeNew });
|
|
1711
1954
|
s.stop("Projects found");
|
|
1712
1955
|
if (projects.length === 0) {
|
|
1713
|
-
|
|
1956
|
+
note6('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
1714
1957
|
return;
|
|
1715
1958
|
}
|
|
1716
1959
|
const options = projects.map((project) => {
|
|
@@ -1718,7 +1961,7 @@ async function handleConfigure() {
|
|
|
1718
1961
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
1719
1962
|
return {
|
|
1720
1963
|
value: project.name,
|
|
1721
|
-
label: `${project.name} ${
|
|
1964
|
+
label: `${project.name} ${pc7.dim(`(${project.source})`)}`,
|
|
1722
1965
|
hint: project.dataPath
|
|
1723
1966
|
};
|
|
1724
1967
|
});
|
|
@@ -1732,7 +1975,7 @@ async function handleConfigure() {
|
|
|
1732
1975
|
initialValues: currentlyExposed,
|
|
1733
1976
|
required: false
|
|
1734
1977
|
});
|
|
1735
|
-
if (
|
|
1978
|
+
if (isCancel6(selected)) {
|
|
1736
1979
|
return;
|
|
1737
1980
|
}
|
|
1738
1981
|
const selectedNames = selected;
|
|
@@ -1744,8 +1987,8 @@ async function handleConfigure() {
|
|
|
1744
1987
|
saveMCPConfig(config);
|
|
1745
1988
|
logger2.info("Configure: Config saved", config);
|
|
1746
1989
|
const exposedCount = selectedNames.length;
|
|
1747
|
-
|
|
1748
|
-
`${
|
|
1990
|
+
note6(
|
|
1991
|
+
`${pc7.green("\u2713")} Configuration saved!
|
|
1749
1992
|
|
|
1750
1993
|
Exposed projects: ${exposedCount}
|
|
1751
1994
|
Hidden projects: ${projects.length - exposedCount}`,
|
|
@@ -1755,65 +1998,57 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
1755
1998
|
async function handleStopServer() {
|
|
1756
1999
|
const status = getMCPServerStatus();
|
|
1757
2000
|
if (!status.running) {
|
|
1758
|
-
|
|
2001
|
+
note6("MCP server is not running.", "Status");
|
|
1759
2002
|
return;
|
|
1760
2003
|
}
|
|
1761
2004
|
const confirmed = await confirm4({
|
|
1762
2005
|
message: "Stop the MCP server?",
|
|
1763
2006
|
initialValue: true
|
|
1764
2007
|
});
|
|
1765
|
-
if (
|
|
2008
|
+
if (isCancel6(confirmed) || !confirmed) {
|
|
1766
2009
|
return;
|
|
1767
2010
|
}
|
|
1768
2011
|
stopMCPServer();
|
|
1769
|
-
|
|
2012
|
+
note6(pc7.green("MCP server stopped."), "Server Stopped");
|
|
1770
2013
|
}
|
|
1771
2014
|
function showHelp() {
|
|
1772
2015
|
const help = `
|
|
1773
|
-
${
|
|
2016
|
+
${pc7.bold("RRCE MCP Hub")} - Cross-project AI assistant server
|
|
1774
2017
|
|
|
1775
|
-
${
|
|
2018
|
+
${pc7.bold("ABOUT")}
|
|
1776
2019
|
MCP (Model Context Protocol) allows AI assistants like Claude to
|
|
1777
2020
|
access your project knowledge in real-time. The RRCE MCP Hub
|
|
1778
2021
|
provides a central server that exposes selected projects.
|
|
1779
2022
|
|
|
1780
|
-
${
|
|
1781
|
-
${
|
|
1782
|
-
${
|
|
1783
|
-
${
|
|
1784
|
-
${
|
|
2023
|
+
${pc7.bold("MENU OPTIONS")}
|
|
2024
|
+
${pc7.cyan("Start MCP server")} Start the server for AI access
|
|
2025
|
+
${pc7.cyan("Configure projects")} Choose which projects to expose
|
|
2026
|
+
${pc7.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
|
|
2027
|
+
${pc7.cyan("View status")} See which projects are exposed
|
|
1785
2028
|
|
|
1786
|
-
${
|
|
1787
|
-
${
|
|
1788
|
-
${
|
|
1789
|
-
${
|
|
1790
|
-
${
|
|
2029
|
+
${pc7.bold("DIRECT COMMANDS")}
|
|
2030
|
+
${pc7.dim("rrce-workflow mcp start")} Start server directly
|
|
2031
|
+
${pc7.dim("rrce-workflow mcp stop")} Stop server directly
|
|
2032
|
+
${pc7.dim("rrce-workflow mcp status")} Show status directly
|
|
2033
|
+
${pc7.dim("rrce-workflow mcp help")} Show this help
|
|
1791
2034
|
|
|
1792
|
-
${
|
|
1793
|
-
|
|
1794
|
-
${
|
|
1795
|
-
"
|
|
1796
|
-
|
|
1797
|
-
"command": "npx",
|
|
1798
|
-
"args": ["rrce-workflow", "mcp", "start"]
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
}`)}
|
|
2035
|
+
${pc7.bold("IDE INSTALLATION")}
|
|
2036
|
+
${pc7.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
|
|
2037
|
+
${pc7.cyan("VSCode Global")} ~/.config/Code/User/settings.json
|
|
2038
|
+
${pc7.cyan("VSCode Workspace")} .vscode/mcp.json
|
|
2039
|
+
${pc7.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
|
|
1802
2040
|
|
|
1803
|
-
${
|
|
1804
|
-
${
|
|
1805
|
-
${
|
|
1806
|
-
${
|
|
2041
|
+
${pc7.bold("SERVER COMMANDS")} (while running)
|
|
2042
|
+
${pc7.cyan("q")} Stop and quit ${pc7.cyan("p")} Reconfigure projects
|
|
2043
|
+
${pc7.cyan("i")} Install to IDE ${pc7.cyan("r")} Reload config
|
|
2044
|
+
${pc7.cyan("c")} Clear logs ${pc7.cyan("?")} Show help
|
|
1807
2045
|
|
|
1808
|
-
${
|
|
1809
|
-
${
|
|
1810
|
-
${
|
|
1811
|
-
${
|
|
1812
|
-
${pc8.cyan("execute")} Implement planned work
|
|
1813
|
-
${pc8.cyan("docs")} Generate documentation
|
|
1814
|
-
${pc8.cyan("sync")} Sync knowledge with codebase
|
|
2046
|
+
${pc7.bold("RESOURCES EXPOSED")}
|
|
2047
|
+
${pc7.cyan("rrce://projects")} List all exposed projects
|
|
2048
|
+
${pc7.cyan("rrce://projects/{name}/context")} Get project context
|
|
2049
|
+
${pc7.cyan("rrce://projects/{name}/tasks")} Get project tasks
|
|
1815
2050
|
`;
|
|
1816
|
-
|
|
2051
|
+
note6(help.trim(), "Help");
|
|
1817
2052
|
}
|
|
1818
2053
|
var init_mcp = __esm({
|
|
1819
2054
|
"src/mcp/index.ts"() {
|
|
@@ -1822,13 +2057,14 @@ var init_mcp = __esm({
|
|
|
1822
2057
|
init_detection();
|
|
1823
2058
|
init_server();
|
|
1824
2059
|
init_install();
|
|
2060
|
+
init_paths();
|
|
1825
2061
|
}
|
|
1826
2062
|
});
|
|
1827
2063
|
|
|
1828
2064
|
// src/commands/wizard/index.ts
|
|
1829
|
-
import { intro, select as
|
|
1830
|
-
import
|
|
1831
|
-
import * as
|
|
2065
|
+
import { intro as intro2, select as select4, spinner as spinner6, note as note7, outro as outro6, isCancel as isCancel7 } from "@clack/prompts";
|
|
2066
|
+
import pc8 from "picocolors";
|
|
2067
|
+
import * as fs15 from "fs";
|
|
1832
2068
|
|
|
1833
2069
|
// src/lib/git.ts
|
|
1834
2070
|
import { execSync } from "child_process";
|
|
@@ -2430,18 +2666,19 @@ function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot,
|
|
|
2430
2666
|
}
|
|
2431
2667
|
|
|
2432
2668
|
// src/commands/wizard/index.ts
|
|
2669
|
+
init_mcp();
|
|
2433
2670
|
async function runWizard() {
|
|
2434
|
-
|
|
2435
|
-
const s =
|
|
2671
|
+
intro2(pc8.cyan(pc8.inverse(" RRCE-Workflow Setup ")));
|
|
2672
|
+
const s = spinner6();
|
|
2436
2673
|
s.start("Detecting environment");
|
|
2437
2674
|
const workspacePath = detectWorkspaceRoot();
|
|
2438
2675
|
const workspaceName = getWorkspaceName(workspacePath);
|
|
2439
2676
|
const gitUser = getGitUser();
|
|
2440
2677
|
await new Promise((r) => setTimeout(r, 800));
|
|
2441
2678
|
s.stop("Environment detected");
|
|
2442
|
-
|
|
2443
|
-
`Git User: ${
|
|
2444
|
-
Workspace: ${
|
|
2679
|
+
note7(
|
|
2680
|
+
`Git User: ${pc8.bold(gitUser || "(not found)")}
|
|
2681
|
+
Workspace: ${pc8.bold(workspaceName)}`,
|
|
2445
2682
|
"Context"
|
|
2446
2683
|
);
|
|
2447
2684
|
const detectedProjects = scanForProjects({
|
|
@@ -2449,44 +2686,53 @@ Workspace: ${pc7.bold(workspaceName)}`,
|
|
|
2449
2686
|
workspacePath
|
|
2450
2687
|
});
|
|
2451
2688
|
const configFilePath = getConfigPath(workspacePath);
|
|
2452
|
-
const isAlreadyConfigured =
|
|
2689
|
+
const isAlreadyConfigured = fs15.existsSync(configFilePath);
|
|
2453
2690
|
let currentStorageMode = null;
|
|
2454
2691
|
if (isAlreadyConfigured) {
|
|
2455
2692
|
try {
|
|
2456
|
-
const configContent =
|
|
2693
|
+
const configContent = fs15.readFileSync(configFilePath, "utf-8");
|
|
2457
2694
|
const modeMatch = configContent.match(/mode:\s*(global|workspace)/);
|
|
2458
2695
|
currentStorageMode = modeMatch?.[1] ?? null;
|
|
2459
2696
|
} catch {
|
|
2460
2697
|
}
|
|
2461
2698
|
}
|
|
2462
2699
|
const localDataPath = getLocalWorkspacePath(workspacePath);
|
|
2463
|
-
const hasLocalData =
|
|
2700
|
+
const hasLocalData = fs15.existsSync(localDataPath);
|
|
2464
2701
|
if (isAlreadyConfigured) {
|
|
2465
2702
|
const menuOptions = [];
|
|
2703
|
+
menuOptions.push({
|
|
2704
|
+
value: "mcp",
|
|
2705
|
+
label: "\u{1F50C} Configure MCP Server",
|
|
2706
|
+
hint: "Expose projects to AI assistants (VSCode, Antigravity, Claude)"
|
|
2707
|
+
});
|
|
2466
2708
|
if (detectedProjects.length > 0) {
|
|
2467
2709
|
menuOptions.push({
|
|
2468
2710
|
value: "link",
|
|
2469
|
-
label: "Link other project knowledge",
|
|
2711
|
+
label: "\u{1F517} Link other project knowledge",
|
|
2470
2712
|
hint: `${detectedProjects.length} projects detected (global + sibling)`
|
|
2471
2713
|
});
|
|
2472
2714
|
}
|
|
2473
2715
|
if (currentStorageMode === "workspace" && hasLocalData) {
|
|
2474
2716
|
menuOptions.push({
|
|
2475
2717
|
value: "sync-global",
|
|
2476
|
-
label: "Sync to global storage",
|
|
2718
|
+
label: "\u2601\uFE0F Sync to global storage",
|
|
2477
2719
|
hint: "Share knowledge with other projects"
|
|
2478
2720
|
});
|
|
2479
2721
|
}
|
|
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
|
|
2722
|
+
menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
|
|
2723
|
+
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
2724
|
+
const action = await select4({
|
|
2483
2725
|
message: "This workspace is already configured. What would you like to do?",
|
|
2484
2726
|
options: menuOptions
|
|
2485
2727
|
});
|
|
2486
|
-
if (
|
|
2487
|
-
|
|
2728
|
+
if (isCancel7(action) || action === "exit") {
|
|
2729
|
+
outro6("Exited.");
|
|
2488
2730
|
process.exit(0);
|
|
2489
2731
|
}
|
|
2732
|
+
if (action === "mcp") {
|
|
2733
|
+
await runMCP();
|
|
2734
|
+
return;
|
|
2735
|
+
}
|
|
2490
2736
|
if (action === "link") {
|
|
2491
2737
|
await runLinkProjectsFlow(workspacePath, workspaceName);
|
|
2492
2738
|
return;
|