rrce-workflow 0.2.35 → 0.2.37
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 +731 -514
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -935,6 +935,10 @@ function parseMCPConfig(content) {
|
|
|
935
935
|
continue;
|
|
936
936
|
}
|
|
937
937
|
if (currentProject) {
|
|
938
|
+
const pathMatch = trimmed.match(/^path:\s*["']?([^"'\n]+)["']?/);
|
|
939
|
+
if (pathMatch) {
|
|
940
|
+
currentProject.path = pathMatch[1].trim();
|
|
941
|
+
}
|
|
938
942
|
const exposeMatch = trimmed.match(/^expose:\s*(true|false)/);
|
|
939
943
|
if (exposeMatch) {
|
|
940
944
|
currentProject.expose = exposeMatch[1] === "true";
|
|
@@ -981,7 +985,12 @@ projects:
|
|
|
981
985
|
} else {
|
|
982
986
|
for (const project of config.projects) {
|
|
983
987
|
content += ` - name: "${project.name}"
|
|
984
|
-
|
|
988
|
+
`;
|
|
989
|
+
if (project.path) {
|
|
990
|
+
content += ` path: "${project.path}"
|
|
991
|
+
`;
|
|
992
|
+
}
|
|
993
|
+
content += ` expose: ${project.expose}
|
|
985
994
|
permissions:
|
|
986
995
|
knowledge: ${project.permissions.knowledge}
|
|
987
996
|
tasks: ${project.permissions.tasks}
|
|
@@ -991,16 +1000,31 @@ projects:
|
|
|
991
1000
|
}
|
|
992
1001
|
return content;
|
|
993
1002
|
}
|
|
994
|
-
function setProjectConfig(config, name, expose, permissions) {
|
|
995
|
-
|
|
1003
|
+
function setProjectConfig(config, name, expose, permissions, projectPath) {
|
|
1004
|
+
let existing = config.projects.find((p) => {
|
|
1005
|
+
if (projectPath && p.path) {
|
|
1006
|
+
return p.path === projectPath;
|
|
1007
|
+
}
|
|
1008
|
+
if (!projectPath && !p.path) {
|
|
1009
|
+
return p.name === name;
|
|
1010
|
+
}
|
|
1011
|
+
if (projectPath && !p.path && p.name === name) {
|
|
1012
|
+
return true;
|
|
1013
|
+
}
|
|
1014
|
+
return false;
|
|
1015
|
+
});
|
|
996
1016
|
if (existing) {
|
|
997
1017
|
existing.expose = expose;
|
|
1018
|
+
if (projectPath && !existing.path) {
|
|
1019
|
+
existing.path = projectPath;
|
|
1020
|
+
}
|
|
998
1021
|
if (permissions) {
|
|
999
1022
|
existing.permissions = { ...existing.permissions, ...permissions };
|
|
1000
1023
|
}
|
|
1001
1024
|
} else {
|
|
1002
1025
|
config.projects.push({
|
|
1003
1026
|
name,
|
|
1027
|
+
path: projectPath,
|
|
1004
1028
|
expose,
|
|
1005
1029
|
permissions: permissions ? { ...DEFAULT_PERMISSIONS, ...permissions } : { ...DEFAULT_PERMISSIONS }
|
|
1006
1030
|
});
|
|
@@ -1011,15 +1035,25 @@ function removeProjectConfig(config, name) {
|
|
|
1011
1035
|
config.projects = config.projects.filter((p) => p.name !== name);
|
|
1012
1036
|
return config;
|
|
1013
1037
|
}
|
|
1014
|
-
function isProjectExposed(config, name) {
|
|
1015
|
-
const project = config.projects.find((p) =>
|
|
1038
|
+
function isProjectExposed(config, name, projectPath) {
|
|
1039
|
+
const project = config.projects.find((p) => {
|
|
1040
|
+
if (projectPath && p.path) return p.path === projectPath;
|
|
1041
|
+
if (!projectPath && !p.path) return p.name === name;
|
|
1042
|
+
if (projectPath && !p.path) return p.name === name;
|
|
1043
|
+
return false;
|
|
1044
|
+
});
|
|
1016
1045
|
if (project) {
|
|
1017
1046
|
return project.expose;
|
|
1018
1047
|
}
|
|
1019
1048
|
return config.defaults.includeNew;
|
|
1020
1049
|
}
|
|
1021
|
-
function getProjectPermissions(config, name) {
|
|
1022
|
-
const project = config.projects.find((p) =>
|
|
1050
|
+
function getProjectPermissions(config, name, projectPath) {
|
|
1051
|
+
const project = config.projects.find((p) => {
|
|
1052
|
+
if (projectPath && p.path) return p.path === projectPath;
|
|
1053
|
+
if (!projectPath && !p.path) return p.name === name;
|
|
1054
|
+
if (projectPath && !p.path) return p.name === name;
|
|
1055
|
+
return false;
|
|
1056
|
+
});
|
|
1023
1057
|
return project?.permissions ?? config.defaults.permissions;
|
|
1024
1058
|
}
|
|
1025
1059
|
var init_config = __esm({
|
|
@@ -1031,11 +1065,6 @@ var init_config = __esm({
|
|
|
1031
1065
|
});
|
|
1032
1066
|
|
|
1033
1067
|
// src/mcp/logger.ts
|
|
1034
|
-
var logger_exports = {};
|
|
1035
|
-
__export(logger_exports, {
|
|
1036
|
-
getLogFilePath: () => getLogFilePath,
|
|
1037
|
-
logger: () => logger
|
|
1038
|
-
});
|
|
1039
1068
|
import * as fs8 from "fs";
|
|
1040
1069
|
import * as path9 from "path";
|
|
1041
1070
|
function getLogFilePath() {
|
|
@@ -1105,27 +1134,73 @@ import * as path10 from "path";
|
|
|
1105
1134
|
function getExposedProjects() {
|
|
1106
1135
|
const config = loadMCPConfig();
|
|
1107
1136
|
const allProjects = scanForProjects();
|
|
1108
|
-
|
|
1137
|
+
const globalProjects = allProjects.filter((project) => isProjectExposed(config, project.name, project.dataPath));
|
|
1138
|
+
const activeProject = detectActiveProject(globalProjects);
|
|
1139
|
+
let linkedProjects = [];
|
|
1140
|
+
if (activeProject) {
|
|
1141
|
+
const localConfigPath = path10.join(activeProject.dataPath, "config.yaml");
|
|
1142
|
+
let cfgContent = null;
|
|
1143
|
+
if (fs9.existsSync(path10.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
|
|
1144
|
+
cfgContent = fs9.readFileSync(path10.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
|
|
1145
|
+
} else if (fs9.existsSync(path10.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
|
|
1146
|
+
cfgContent = fs9.readFileSync(path10.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
|
|
1147
|
+
}
|
|
1148
|
+
if (cfgContent) {
|
|
1149
|
+
if (cfgContent.includes("linked_projects:")) {
|
|
1150
|
+
const lines = cfgContent.split("\n");
|
|
1151
|
+
let inLinked = false;
|
|
1152
|
+
for (const line of lines) {
|
|
1153
|
+
const trimmed = line.trim();
|
|
1154
|
+
if (trimmed.startsWith("linked_projects:")) {
|
|
1155
|
+
inLinked = true;
|
|
1156
|
+
continue;
|
|
1157
|
+
}
|
|
1158
|
+
if (inLinked) {
|
|
1159
|
+
if (trimmed.startsWith("-") || trimmed.startsWith("linked_projects")) {
|
|
1160
|
+
} else if (trimmed !== "" && !trimmed.startsWith("#")) {
|
|
1161
|
+
inLinked = false;
|
|
1162
|
+
}
|
|
1163
|
+
if (inLinked && trimmed.startsWith("-")) {
|
|
1164
|
+
const val = trimmed.replace(/^-\s*/, "").trim();
|
|
1165
|
+
const [pName] = val.split(":");
|
|
1166
|
+
if (!globalProjects.some((p) => p.name === pName) && !linkedProjects.some((p) => p.name === pName)) {
|
|
1167
|
+
const found = allProjects.find((p) => p.name === pName);
|
|
1168
|
+
if (found) {
|
|
1169
|
+
linkedProjects.push(found);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
return [...globalProjects, ...linkedProjects];
|
|
1109
1179
|
}
|
|
1110
|
-
function detectActiveProject() {
|
|
1111
|
-
|
|
1180
|
+
function detectActiveProject(knownProjects) {
|
|
1181
|
+
let scanList = knownProjects;
|
|
1182
|
+
if (!scanList) {
|
|
1183
|
+
const config = loadMCPConfig();
|
|
1184
|
+
const all = scanForProjects();
|
|
1185
|
+
scanList = all.filter((project) => isProjectExposed(config, project.name, project.dataPath));
|
|
1186
|
+
}
|
|
1112
1187
|
const cwd = process.cwd();
|
|
1113
|
-
const matches =
|
|
1188
|
+
const matches = scanList.filter((p) => cwd.startsWith(p.path));
|
|
1114
1189
|
matches.sort((a, b) => b.path.length - a.path.length);
|
|
1115
1190
|
return matches[0];
|
|
1116
1191
|
}
|
|
1117
1192
|
function getProjectContext(projectName) {
|
|
1118
1193
|
const config = loadMCPConfig();
|
|
1119
|
-
|
|
1194
|
+
const projects = scanForProjects();
|
|
1195
|
+
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.dataPath));
|
|
1196
|
+
if (!project) {
|
|
1120
1197
|
return null;
|
|
1121
1198
|
}
|
|
1122
|
-
const permissions = getProjectPermissions(config, projectName);
|
|
1199
|
+
const permissions = getProjectPermissions(config, projectName, project.dataPath);
|
|
1123
1200
|
if (!permissions.knowledge) {
|
|
1124
1201
|
return null;
|
|
1125
1202
|
}
|
|
1126
|
-
|
|
1127
|
-
const project = projects.find((p) => p.name === projectName);
|
|
1128
|
-
if (!project?.knowledgePath) {
|
|
1203
|
+
if (!project.knowledgePath) {
|
|
1129
1204
|
return null;
|
|
1130
1205
|
}
|
|
1131
1206
|
const contextPath = path10.join(project.knowledgePath, "project-context.md");
|
|
@@ -1136,16 +1211,16 @@ function getProjectContext(projectName) {
|
|
|
1136
1211
|
}
|
|
1137
1212
|
function getProjectTasks(projectName) {
|
|
1138
1213
|
const config = loadMCPConfig();
|
|
1139
|
-
|
|
1214
|
+
const projects = scanForProjects();
|
|
1215
|
+
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.dataPath));
|
|
1216
|
+
if (!project) {
|
|
1140
1217
|
return [];
|
|
1141
1218
|
}
|
|
1142
|
-
const permissions = getProjectPermissions(config, projectName);
|
|
1219
|
+
const permissions = getProjectPermissions(config, projectName, project.dataPath);
|
|
1143
1220
|
if (!permissions.tasks) {
|
|
1144
1221
|
return [];
|
|
1145
1222
|
}
|
|
1146
|
-
|
|
1147
|
-
const project = projects.find((p) => p.name === projectName);
|
|
1148
|
-
if (!project?.tasksPath || !fs9.existsSync(project.tasksPath)) {
|
|
1223
|
+
if (!project.tasksPath || !fs9.existsSync(project.tasksPath)) {
|
|
1149
1224
|
return [];
|
|
1150
1225
|
}
|
|
1151
1226
|
const tasks = [];
|
|
@@ -1172,7 +1247,7 @@ function searchKnowledge(query) {
|
|
|
1172
1247
|
const results = [];
|
|
1173
1248
|
const queryLower = query.toLowerCase();
|
|
1174
1249
|
for (const project of projects) {
|
|
1175
|
-
const permissions = getProjectPermissions(config, project.name);
|
|
1250
|
+
const permissions = getProjectPermissions(config, project.name, project.dataPath);
|
|
1176
1251
|
if (!permissions.knowledge || !project.knowledgePath) continue;
|
|
1177
1252
|
try {
|
|
1178
1253
|
const files = fs9.readdirSync(project.knowledgePath);
|
|
@@ -1209,102 +1284,12 @@ var init_resources = __esm({
|
|
|
1209
1284
|
}
|
|
1210
1285
|
});
|
|
1211
1286
|
|
|
1212
|
-
// src/mcp/
|
|
1213
|
-
|
|
1214
|
-
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
1215
|
-
return prompts.map((p) => {
|
|
1216
|
-
const args = [];
|
|
1217
|
-
if (p.frontmatter["required-args"]) {
|
|
1218
|
-
args.push(...p.frontmatter["required-args"].map((a) => ({
|
|
1219
|
-
name: a.name,
|
|
1220
|
-
description: a.prompt || a.name,
|
|
1221
|
-
required: true
|
|
1222
|
-
})));
|
|
1223
|
-
}
|
|
1224
|
-
if (p.frontmatter["optional-args"]) {
|
|
1225
|
-
args.push(...p.frontmatter["optional-args"].map((a) => ({
|
|
1226
|
-
name: a.name,
|
|
1227
|
-
description: a.prompt || a.name,
|
|
1228
|
-
required: false
|
|
1229
|
-
})));
|
|
1230
|
-
}
|
|
1231
|
-
return {
|
|
1232
|
-
name: p.frontmatter.name,
|
|
1233
|
-
description: p.frontmatter.description,
|
|
1234
|
-
arguments: args,
|
|
1235
|
-
content: p.content
|
|
1236
|
-
};
|
|
1237
|
-
});
|
|
1238
|
-
}
|
|
1239
|
-
function getPromptDef(name) {
|
|
1240
|
-
return getAllPrompts().find((p) => p.name === name);
|
|
1241
|
-
}
|
|
1242
|
-
function renderPrompt(content, args) {
|
|
1243
|
-
let rendered = content;
|
|
1244
|
-
for (const [key, val] of Object.entries(args)) {
|
|
1245
|
-
rendered = rendered.replace(new RegExp(`{{${key}}}`, "g"), val);
|
|
1246
|
-
}
|
|
1247
|
-
return rendered;
|
|
1248
|
-
}
|
|
1249
|
-
var init_prompts2 = __esm({
|
|
1250
|
-
"src/mcp/prompts.ts"() {
|
|
1251
|
-
"use strict";
|
|
1252
|
-
init_prompts();
|
|
1253
|
-
}
|
|
1254
|
-
});
|
|
1255
|
-
|
|
1256
|
-
// src/mcp/server.ts
|
|
1257
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1258
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1287
|
+
// src/mcp/handlers/resources.ts
|
|
1288
|
+
import "@modelcontextprotocol/sdk/server/index.js";
|
|
1259
1289
|
import {
|
|
1260
|
-
CallToolRequestSchema,
|
|
1261
1290
|
ListResourcesRequestSchema,
|
|
1262
|
-
|
|
1263
|
-
ReadResourceRequestSchema,
|
|
1264
|
-
ListPromptsRequestSchema,
|
|
1265
|
-
GetPromptRequestSchema
|
|
1291
|
+
ReadResourceRequestSchema
|
|
1266
1292
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
1267
|
-
async function startMCPServer(options = {}) {
|
|
1268
|
-
try {
|
|
1269
|
-
logger.info("Starting MCP Server...");
|
|
1270
|
-
process.on("uncaughtException", (error) => {
|
|
1271
|
-
logger.error("Uncaught Exception", error);
|
|
1272
|
-
console.error("Uncaught Exception:", error);
|
|
1273
|
-
});
|
|
1274
|
-
process.on("unhandledRejection", (reason) => {
|
|
1275
|
-
logger.error("Unhandled Rejection", reason);
|
|
1276
|
-
console.error("Unhandled Rejection:", reason);
|
|
1277
|
-
});
|
|
1278
|
-
const config = loadMCPConfig();
|
|
1279
|
-
mcpServer = new Server(
|
|
1280
|
-
{ name: "rrce-mcp-hub", version: "1.0.0" },
|
|
1281
|
-
{ capabilities: { resources: {}, tools: {}, prompts: {} } }
|
|
1282
|
-
);
|
|
1283
|
-
mcpServer.onerror = (error) => {
|
|
1284
|
-
logger.error("MCP Server Error", error);
|
|
1285
|
-
};
|
|
1286
|
-
registerResourceHandlers(mcpServer);
|
|
1287
|
-
registerToolHandlers(mcpServer);
|
|
1288
|
-
registerPromptHandlers(mcpServer);
|
|
1289
|
-
if (!options.interactive) {
|
|
1290
|
-
const transport = new StdioServerTransport();
|
|
1291
|
-
await mcpServer.connect(transport);
|
|
1292
|
-
} else {
|
|
1293
|
-
logger.info("Running in interactive mode (Stdio transport detached)");
|
|
1294
|
-
}
|
|
1295
|
-
serverState = { running: true, port: config.server.port, pid: process.pid };
|
|
1296
|
-
const exposed = getExposedProjects().map((p) => p.name).join(", ");
|
|
1297
|
-
logger.info(`RRCE MCP Hub started (pid: ${process.pid})`, { exposedProjects: exposed });
|
|
1298
|
-
if (!options.interactive) {
|
|
1299
|
-
console.error(`RRCE MCP Hub started (pid: ${process.pid})`);
|
|
1300
|
-
console.error(`Exposed projects: ${exposed}`);
|
|
1301
|
-
}
|
|
1302
|
-
return { port: config.server.port, pid: process.pid };
|
|
1303
|
-
} catch (error) {
|
|
1304
|
-
logger.error("Failed to start MCP server", error);
|
|
1305
|
-
throw error;
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
1293
|
function registerResourceHandlers(server) {
|
|
1309
1294
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
1310
1295
|
logger.debug("Listing resources");
|
|
@@ -1318,7 +1303,7 @@ function registerResourceHandlers(server) {
|
|
|
1318
1303
|
});
|
|
1319
1304
|
for (const project of projects) {
|
|
1320
1305
|
const config = loadMCPConfig();
|
|
1321
|
-
const permissions = getProjectPermissions(config, project.name);
|
|
1306
|
+
const permissions = getProjectPermissions(config, project.name, project.dataPath);
|
|
1322
1307
|
if (permissions.knowledge) {
|
|
1323
1308
|
resources.push({
|
|
1324
1309
|
uri: `rrce://projects/${project.name}/context`,
|
|
@@ -1373,6 +1358,65 @@ function registerResourceHandlers(server) {
|
|
|
1373
1358
|
}
|
|
1374
1359
|
});
|
|
1375
1360
|
}
|
|
1361
|
+
var init_resources2 = __esm({
|
|
1362
|
+
"src/mcp/handlers/resources.ts"() {
|
|
1363
|
+
"use strict";
|
|
1364
|
+
init_logger();
|
|
1365
|
+
init_config();
|
|
1366
|
+
init_resources();
|
|
1367
|
+
}
|
|
1368
|
+
});
|
|
1369
|
+
|
|
1370
|
+
// src/mcp/prompts.ts
|
|
1371
|
+
function getAllPrompts() {
|
|
1372
|
+
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
1373
|
+
return prompts.map((p) => {
|
|
1374
|
+
const args = [];
|
|
1375
|
+
if (p.frontmatter["required-args"]) {
|
|
1376
|
+
args.push(...p.frontmatter["required-args"].map((a) => ({
|
|
1377
|
+
name: a.name,
|
|
1378
|
+
description: a.prompt || a.name,
|
|
1379
|
+
required: true
|
|
1380
|
+
})));
|
|
1381
|
+
}
|
|
1382
|
+
if (p.frontmatter["optional-args"]) {
|
|
1383
|
+
args.push(...p.frontmatter["optional-args"].map((a) => ({
|
|
1384
|
+
name: a.name,
|
|
1385
|
+
description: a.prompt || a.name,
|
|
1386
|
+
required: false
|
|
1387
|
+
})));
|
|
1388
|
+
}
|
|
1389
|
+
return {
|
|
1390
|
+
name: p.frontmatter.name,
|
|
1391
|
+
description: p.frontmatter.description,
|
|
1392
|
+
arguments: args,
|
|
1393
|
+
content: p.content
|
|
1394
|
+
};
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
function getPromptDef(name) {
|
|
1398
|
+
return getAllPrompts().find((p) => p.name === name);
|
|
1399
|
+
}
|
|
1400
|
+
function renderPrompt(content, args) {
|
|
1401
|
+
let rendered = content;
|
|
1402
|
+
for (const [key, val] of Object.entries(args)) {
|
|
1403
|
+
rendered = rendered.replace(new RegExp(`{{${key}}}`, "g"), val);
|
|
1404
|
+
}
|
|
1405
|
+
return rendered;
|
|
1406
|
+
}
|
|
1407
|
+
var init_prompts2 = __esm({
|
|
1408
|
+
"src/mcp/prompts.ts"() {
|
|
1409
|
+
"use strict";
|
|
1410
|
+
init_prompts();
|
|
1411
|
+
}
|
|
1412
|
+
});
|
|
1413
|
+
|
|
1414
|
+
// src/mcp/handlers/tools.ts
|
|
1415
|
+
import "@modelcontextprotocol/sdk/server/index.js";
|
|
1416
|
+
import {
|
|
1417
|
+
ListToolsRequestSchema,
|
|
1418
|
+
CallToolRequestSchema
|
|
1419
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
1376
1420
|
function registerToolHandlers(server) {
|
|
1377
1421
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1378
1422
|
const tools = [
|
|
@@ -1525,6 +1569,21 @@ To fix this:
|
|
|
1525
1569
|
}
|
|
1526
1570
|
});
|
|
1527
1571
|
}
|
|
1572
|
+
var init_tools = __esm({
|
|
1573
|
+
"src/mcp/handlers/tools.ts"() {
|
|
1574
|
+
"use strict";
|
|
1575
|
+
init_logger();
|
|
1576
|
+
init_resources();
|
|
1577
|
+
init_prompts2();
|
|
1578
|
+
}
|
|
1579
|
+
});
|
|
1580
|
+
|
|
1581
|
+
// src/mcp/handlers/prompts.ts
|
|
1582
|
+
import "@modelcontextprotocol/sdk/server/index.js";
|
|
1583
|
+
import {
|
|
1584
|
+
ListPromptsRequestSchema,
|
|
1585
|
+
GetPromptRequestSchema
|
|
1586
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
1528
1587
|
function registerPromptHandlers(server) {
|
|
1529
1588
|
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
1530
1589
|
logger.debug("Listing prompts");
|
|
@@ -1606,6 +1665,65 @@ Note: If the user's request refers to a project not listed here, ask them to exp
|
|
|
1606
1665
|
}
|
|
1607
1666
|
});
|
|
1608
1667
|
}
|
|
1668
|
+
var init_prompts3 = __esm({
|
|
1669
|
+
"src/mcp/handlers/prompts.ts"() {
|
|
1670
|
+
"use strict";
|
|
1671
|
+
init_logger();
|
|
1672
|
+
init_resources();
|
|
1673
|
+
init_prompts2();
|
|
1674
|
+
}
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
// src/mcp/server.ts
|
|
1678
|
+
var server_exports = {};
|
|
1679
|
+
__export(server_exports, {
|
|
1680
|
+
getMCPServerStatus: () => getMCPServerStatus,
|
|
1681
|
+
startMCPServer: () => startMCPServer,
|
|
1682
|
+
stopMCPServer: () => stopMCPServer
|
|
1683
|
+
});
|
|
1684
|
+
import { Server as Server4 } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1685
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1686
|
+
async function startMCPServer(options = {}) {
|
|
1687
|
+
try {
|
|
1688
|
+
logger.info("Starting MCP Server...");
|
|
1689
|
+
process.on("uncaughtException", (error) => {
|
|
1690
|
+
logger.error("Uncaught Exception", error);
|
|
1691
|
+
console.error("Uncaught Exception:", error);
|
|
1692
|
+
});
|
|
1693
|
+
process.on("unhandledRejection", (reason) => {
|
|
1694
|
+
logger.error("Unhandled Rejection", reason);
|
|
1695
|
+
console.error("Unhandled Rejection:", reason);
|
|
1696
|
+
});
|
|
1697
|
+
const config = loadMCPConfig();
|
|
1698
|
+
mcpServer = new Server4(
|
|
1699
|
+
{ name: "rrce-mcp-hub", version: "1.0.0" },
|
|
1700
|
+
{ capabilities: { resources: {}, tools: {}, prompts: {} } }
|
|
1701
|
+
);
|
|
1702
|
+
mcpServer.onerror = (error) => {
|
|
1703
|
+
logger.error("MCP Server Error", error);
|
|
1704
|
+
};
|
|
1705
|
+
registerResourceHandlers(mcpServer);
|
|
1706
|
+
registerToolHandlers(mcpServer);
|
|
1707
|
+
registerPromptHandlers(mcpServer);
|
|
1708
|
+
if (!options.interactive) {
|
|
1709
|
+
const transport = new StdioServerTransport();
|
|
1710
|
+
await mcpServer.connect(transport);
|
|
1711
|
+
} else {
|
|
1712
|
+
logger.info("Running in interactive mode (Stdio transport detached)");
|
|
1713
|
+
}
|
|
1714
|
+
serverState = { running: true, port: config.server.port, pid: process.pid };
|
|
1715
|
+
const exposed = getExposedProjects().map((p) => p.name).join(", ");
|
|
1716
|
+
logger.info(`RRCE MCP Hub started (pid: ${process.pid})`, { exposedProjects: exposed });
|
|
1717
|
+
if (!options.interactive) {
|
|
1718
|
+
console.error(`RRCE MCP Hub started (pid: ${process.pid})`);
|
|
1719
|
+
console.error(`Exposed projects: ${exposed}`);
|
|
1720
|
+
}
|
|
1721
|
+
return { port: config.server.port, pid: process.pid };
|
|
1722
|
+
} catch (error) {
|
|
1723
|
+
logger.error("Failed to start MCP server", error);
|
|
1724
|
+
throw error;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1609
1727
|
function stopMCPServer() {
|
|
1610
1728
|
if (mcpServer) {
|
|
1611
1729
|
logger.info("Stopping MCP Server...");
|
|
@@ -1625,8 +1743,9 @@ var init_server = __esm({
|
|
|
1625
1743
|
init_logger();
|
|
1626
1744
|
init_config();
|
|
1627
1745
|
init_resources();
|
|
1628
|
-
|
|
1629
|
-
|
|
1746
|
+
init_resources2();
|
|
1747
|
+
init_tools();
|
|
1748
|
+
init_prompts3();
|
|
1630
1749
|
serverState = { running: false };
|
|
1631
1750
|
mcpServer = null;
|
|
1632
1751
|
}
|
|
@@ -1820,17 +1939,179 @@ var init_install = __esm({
|
|
|
1820
1939
|
}
|
|
1821
1940
|
});
|
|
1822
1941
|
|
|
1823
|
-
// src/mcp/
|
|
1824
|
-
import "
|
|
1825
|
-
import
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1942
|
+
// src/mcp/commands/configure.ts
|
|
1943
|
+
import { spinner, note as note2, multiselect, isCancel as isCancel2 } from "@clack/prompts";
|
|
1944
|
+
import pc3 from "picocolors";
|
|
1945
|
+
async function handleConfigure() {
|
|
1946
|
+
const s = spinner();
|
|
1947
|
+
s.start("Scanning for projects...");
|
|
1948
|
+
const config = loadMCPConfig();
|
|
1949
|
+
const projects = scanForProjects();
|
|
1950
|
+
logger.info("Configure: Loaded config", { projects: config.projects, defaultMode: config.defaults.includeNew });
|
|
1951
|
+
s.stop("Projects found");
|
|
1952
|
+
if (projects.length === 0) {
|
|
1953
|
+
note2('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
1954
|
+
return;
|
|
1832
1955
|
}
|
|
1833
|
-
|
|
1956
|
+
const options = projects.map((project) => {
|
|
1957
|
+
const projectConfig = config.projects.find(
|
|
1958
|
+
(p) => p.path && p.path === project.dataPath || !p.path && p.name === project.name
|
|
1959
|
+
);
|
|
1960
|
+
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
1961
|
+
return {
|
|
1962
|
+
value: project.dataPath,
|
|
1963
|
+
// Use precise data path as unique identifier
|
|
1964
|
+
label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
|
|
1965
|
+
hint: project.dataPath
|
|
1966
|
+
};
|
|
1967
|
+
});
|
|
1968
|
+
const currentlyExposed = projects.filter((p) => {
|
|
1969
|
+
const cfg = config.projects.find(
|
|
1970
|
+
(c) => c.path && c.path === p.dataPath || !c.path && c.name === p.name
|
|
1971
|
+
);
|
|
1972
|
+
return cfg?.expose ?? config.defaults.includeNew;
|
|
1973
|
+
}).map((p) => p.dataPath);
|
|
1974
|
+
const selected = await multiselect({
|
|
1975
|
+
message: "Select projects to expose via MCP:",
|
|
1976
|
+
options,
|
|
1977
|
+
initialValues: currentlyExposed,
|
|
1978
|
+
required: false
|
|
1979
|
+
});
|
|
1980
|
+
if (isCancel2(selected)) {
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
const selectedPaths = selected;
|
|
1984
|
+
logger.info("Configure: User selected projects by path", selectedPaths);
|
|
1985
|
+
for (const project of projects) {
|
|
1986
|
+
const shouldExpose = selectedPaths.includes(project.dataPath);
|
|
1987
|
+
setProjectConfig(config, project.name, shouldExpose, void 0, project.dataPath);
|
|
1988
|
+
}
|
|
1989
|
+
saveMCPConfig(config);
|
|
1990
|
+
logger.info("Configure: Config saved", config);
|
|
1991
|
+
const exposedCount = selectedPaths.length;
|
|
1992
|
+
note2(
|
|
1993
|
+
`${pc3.green("\u2713")} Configuration saved!
|
|
1994
|
+
|
|
1995
|
+
Exposed projects: ${exposedCount}
|
|
1996
|
+
Hidden projects: ${projects.length - exposedCount}`,
|
|
1997
|
+
"Configuration Updated"
|
|
1998
|
+
);
|
|
1999
|
+
}
|
|
2000
|
+
async function handleConfigureGlobalPath() {
|
|
2001
|
+
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
2002
|
+
const fs17 = await import("fs");
|
|
2003
|
+
const path16 = await import("path");
|
|
2004
|
+
note2(
|
|
2005
|
+
`MCP Hub requires a ${pc3.bold("global storage path")} to store its configuration
|
|
2006
|
+
and coordinate across projects.
|
|
2007
|
+
|
|
2008
|
+
Your current setup uses ${pc3.cyan("workspace")} mode, which stores data
|
|
2009
|
+
locally in each project. MCP needs a central location.`,
|
|
2010
|
+
"Global Path Required"
|
|
2011
|
+
);
|
|
2012
|
+
const resolvedPath = await resolveGlobalPath2();
|
|
2013
|
+
if (!resolvedPath) {
|
|
2014
|
+
return false;
|
|
2015
|
+
}
|
|
2016
|
+
try {
|
|
2017
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
2018
|
+
fs17.mkdirSync(resolvedPath, { recursive: true });
|
|
2019
|
+
}
|
|
2020
|
+
const config = loadMCPConfig();
|
|
2021
|
+
saveMCPConfig(config);
|
|
2022
|
+
note2(
|
|
2023
|
+
`${pc3.green("\u2713")} Global path configured: ${pc3.cyan(resolvedPath)}
|
|
2024
|
+
|
|
2025
|
+
MCP config will be stored at:
|
|
2026
|
+
${path16.join(resolvedPath, "mcp.yaml")}`,
|
|
2027
|
+
"Configuration Saved"
|
|
2028
|
+
);
|
|
2029
|
+
return true;
|
|
2030
|
+
} catch (error) {
|
|
2031
|
+
note2(
|
|
2032
|
+
`${pc3.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
|
|
2033
|
+
"Error"
|
|
2034
|
+
);
|
|
2035
|
+
return false;
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
var init_configure = __esm({
|
|
2039
|
+
"src/mcp/commands/configure.ts"() {
|
|
2040
|
+
"use strict";
|
|
2041
|
+
init_config();
|
|
2042
|
+
init_detection();
|
|
2043
|
+
init_logger();
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
|
|
2047
|
+
// src/mcp/commands/install-wizard.ts
|
|
2048
|
+
import { multiselect as multiselect2, note as note3, isCancel as isCancel3 } from "@clack/prompts";
|
|
2049
|
+
import pc4 from "picocolors";
|
|
2050
|
+
async function runInstallWizard(workspacePath) {
|
|
2051
|
+
const status = checkInstallStatus(workspacePath);
|
|
2052
|
+
const options = [
|
|
2053
|
+
{
|
|
2054
|
+
value: "antigravity",
|
|
2055
|
+
label: "Antigravity IDE",
|
|
2056
|
+
hint: status.antigravity ? pc4.green("\u2713 Installed") : pc4.dim("Not installed")
|
|
2057
|
+
},
|
|
2058
|
+
{
|
|
2059
|
+
value: "vscode-global",
|
|
2060
|
+
label: "VSCode (Global Settings)",
|
|
2061
|
+
hint: status.vscodeGlobal ? pc4.green("\u2713 Installed") : pc4.dim("Not installed")
|
|
2062
|
+
},
|
|
2063
|
+
{
|
|
2064
|
+
value: "vscode-workspace",
|
|
2065
|
+
label: "VSCode (Workspace Config)",
|
|
2066
|
+
hint: status.vscodeWorkspace ? pc4.green("\u2713 Installed") : pc4.dim("Not installed")
|
|
2067
|
+
},
|
|
2068
|
+
{
|
|
2069
|
+
value: "claude",
|
|
2070
|
+
label: "Claude Desktop",
|
|
2071
|
+
hint: status.claude ? pc4.green("\u2713 Installed") : pc4.dim("Not installed")
|
|
2072
|
+
}
|
|
2073
|
+
];
|
|
2074
|
+
const selected = await multiselect2({
|
|
2075
|
+
message: "Select where to install RRCE MCP Server:",
|
|
2076
|
+
options,
|
|
2077
|
+
initialValues: [
|
|
2078
|
+
...status.antigravity ? ["antigravity"] : [],
|
|
2079
|
+
...status.vscodeGlobal ? ["vscode-global"] : [],
|
|
2080
|
+
...status.vscodeWorkspace ? ["vscode-workspace"] : [],
|
|
2081
|
+
...status.claude ? ["claude"] : []
|
|
2082
|
+
],
|
|
2083
|
+
required: false
|
|
2084
|
+
});
|
|
2085
|
+
if (isCancel3(selected)) return;
|
|
2086
|
+
const targets = selected;
|
|
2087
|
+
const results = [];
|
|
2088
|
+
for (const target of targets) {
|
|
2089
|
+
const success = installToConfig(target, workspacePath);
|
|
2090
|
+
const label = getTargetLabel(target);
|
|
2091
|
+
results.push(`${label}: ${success ? pc4.green("\u2713 Success") : pc4.red("\u2717 Failed")}`);
|
|
2092
|
+
}
|
|
2093
|
+
if (results.length > 0) {
|
|
2094
|
+
note3(results.join("\n"), "Installation Results");
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
var init_install_wizard = __esm({
|
|
2098
|
+
"src/mcp/commands/install-wizard.ts"() {
|
|
2099
|
+
"use strict";
|
|
2100
|
+
init_install();
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2103
|
+
|
|
2104
|
+
// src/mcp/ui/Header.tsx
|
|
2105
|
+
import "react";
|
|
2106
|
+
import { Box, Text } from "ink";
|
|
2107
|
+
import { jsx } from "react/jsx-runtime";
|
|
2108
|
+
var Header;
|
|
2109
|
+
var init_Header = __esm({
|
|
2110
|
+
"src/mcp/ui/Header.tsx"() {
|
|
2111
|
+
"use strict";
|
|
2112
|
+
Header = () => /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingBottom: 1, children: /* @__PURE__ */ jsx(Box, { borderStyle: "double", borderColor: "cyan", paddingX: 2, justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: " RRCE MCP Hub " }) }) });
|
|
2113
|
+
}
|
|
2114
|
+
});
|
|
1834
2115
|
|
|
1835
2116
|
// src/mcp/ui/StatusBoard.tsx
|
|
1836
2117
|
import "react";
|
|
@@ -2010,12 +2291,15 @@ var init_App = __esm({
|
|
|
2010
2291
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2011
2292
|
stopMCPServer();
|
|
2012
2293
|
onExit();
|
|
2294
|
+
exit();
|
|
2013
2295
|
}
|
|
2014
2296
|
if (input === "p") {
|
|
2015
2297
|
onConfigure();
|
|
2298
|
+
exit();
|
|
2016
2299
|
}
|
|
2017
2300
|
if (input === "i") {
|
|
2018
2301
|
onInstall();
|
|
2302
|
+
exit();
|
|
2019
2303
|
}
|
|
2020
2304
|
if (input === "c") {
|
|
2021
2305
|
setLogs([]);
|
|
@@ -2040,183 +2324,18 @@ var init_App = __esm({
|
|
|
2040
2324
|
}
|
|
2041
2325
|
});
|
|
2042
2326
|
|
|
2043
|
-
// src/mcp/
|
|
2044
|
-
|
|
2045
|
-
__export(mcp_exports, {
|
|
2046
|
-
runMCP: () => runMCP
|
|
2047
|
-
});
|
|
2048
|
-
import { intro, outro, select as select2, multiselect, confirm, spinner, note as note2, cancel, isCancel as isCancel2, text } from "@clack/prompts";
|
|
2049
|
-
import pc3 from "picocolors";
|
|
2050
|
-
async function runMCP(subcommand2) {
|
|
2051
|
-
if (subcommand2) {
|
|
2052
|
-
switch (subcommand2) {
|
|
2053
|
-
case "start":
|
|
2054
|
-
if (process.stdout.isTTY) {
|
|
2055
|
-
await handleStartServer();
|
|
2056
|
-
} else {
|
|
2057
|
-
await startMCPServer();
|
|
2058
|
-
await new Promise(() => {
|
|
2059
|
-
});
|
|
2060
|
-
}
|
|
2061
|
-
return;
|
|
2062
|
-
case "stop":
|
|
2063
|
-
await handleStopServer();
|
|
2064
|
-
return;
|
|
2065
|
-
case "status":
|
|
2066
|
-
await handleShowStatus();
|
|
2067
|
-
return;
|
|
2068
|
-
case "help":
|
|
2069
|
-
showHelp();
|
|
2070
|
-
return;
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
intro(pc3.bgCyan(pc3.black(" RRCE MCP Hub ")));
|
|
2074
|
-
const workspacePath = detectWorkspaceRoot();
|
|
2075
|
-
const globalPathCheck = await ensureMCPGlobalPath();
|
|
2076
|
-
if (!globalPathCheck.configured) {
|
|
2077
|
-
const configured = await handleConfigureGlobalPath();
|
|
2078
|
-
if (!configured) {
|
|
2079
|
-
outro(pc3.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
2080
|
-
return;
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
const installed = isInstalledAnywhere(workspacePath);
|
|
2084
|
-
if (!installed) {
|
|
2085
|
-
note2(
|
|
2086
|
-
`${pc3.bold("Welcome to RRCE MCP Hub!")}
|
|
2087
|
-
|
|
2088
|
-
MCP (Model Context Protocol) allows AI assistants to access your
|
|
2089
|
-
project knowledge in real-time. Let's get you set up.`,
|
|
2090
|
-
"Getting Started"
|
|
2091
|
-
);
|
|
2092
|
-
const shouldInstall = await confirm({
|
|
2093
|
-
message: "Install MCP server to your IDE(s)?",
|
|
2094
|
-
initialValue: true
|
|
2095
|
-
});
|
|
2096
|
-
if (shouldInstall && !isCancel2(shouldInstall)) {
|
|
2097
|
-
await handleInstallWizard(workspacePath);
|
|
2098
|
-
const config2 = loadMCPConfig();
|
|
2099
|
-
const exposedCount2 = config2.projects.filter((p) => p.expose).length;
|
|
2100
|
-
if (exposedCount2 === 0) {
|
|
2101
|
-
await handleConfigure();
|
|
2102
|
-
}
|
|
2103
|
-
const shouldStart = await confirm({
|
|
2104
|
-
message: "Start the MCP server now?",
|
|
2105
|
-
initialValue: true
|
|
2106
|
-
});
|
|
2107
|
-
if (shouldStart && !isCancel2(shouldStart)) {
|
|
2108
|
-
await handleStartServer();
|
|
2109
|
-
}
|
|
2110
|
-
}
|
|
2111
|
-
outro(pc3.green("MCP Hub setup complete!"));
|
|
2112
|
-
return;
|
|
2113
|
-
}
|
|
2114
|
-
const config = loadMCPConfig();
|
|
2115
|
-
const exposedCount = config.projects.filter((p) => p.expose).length;
|
|
2116
|
-
if (exposedCount === 0 && !config.defaults.includeNew) {
|
|
2117
|
-
note2("MCP is installed but no projects are exposed. Let's configure that.", "Configuration Needed");
|
|
2118
|
-
await handleConfigure();
|
|
2119
|
-
}
|
|
2120
|
-
let running = true;
|
|
2121
|
-
while (running) {
|
|
2122
|
-
const serverStatus = getMCPServerStatus();
|
|
2123
|
-
const serverLabel = serverStatus.running ? pc3.green("\u25CF Running") : pc3.dim("\u25CB Stopped");
|
|
2124
|
-
const currentStatus = checkInstallStatus(workspacePath);
|
|
2125
|
-
const installedCount = [currentStatus.antigravity, currentStatus.claude, currentStatus.vscodeGlobal, currentStatus.vscodeWorkspace].filter(Boolean).length;
|
|
2126
|
-
const action = await select2({
|
|
2127
|
-
message: "What would you like to do?",
|
|
2128
|
-
options: [
|
|
2129
|
-
{ value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: serverLabel },
|
|
2130
|
-
{ value: "configure", label: "\u2699\uFE0F Configure projects", hint: "Choose which projects to expose" },
|
|
2131
|
-
{ value: "install", label: "\u{1F4E5} Install to IDE", hint: `${installedCount} IDE(s) configured` },
|
|
2132
|
-
{ value: "status", label: "\u{1F4CB} View status", hint: "See details" },
|
|
2133
|
-
{ value: "help", label: "\u2753 Help", hint: "Learn about MCP Hub" },
|
|
2134
|
-
{ value: "exit", label: "\u21A9 Exit", hint: "Return to shell" }
|
|
2135
|
-
]
|
|
2136
|
-
});
|
|
2137
|
-
if (isCancel2(action)) {
|
|
2138
|
-
cancel("MCP Hub closed.");
|
|
2139
|
-
return;
|
|
2140
|
-
}
|
|
2141
|
-
switch (action) {
|
|
2142
|
-
case "start":
|
|
2143
|
-
await handleStartServer();
|
|
2144
|
-
break;
|
|
2145
|
-
case "configure":
|
|
2146
|
-
await handleConfigure();
|
|
2147
|
-
break;
|
|
2148
|
-
case "install":
|
|
2149
|
-
await handleInstallWizard(workspacePath);
|
|
2150
|
-
break;
|
|
2151
|
-
case "status":
|
|
2152
|
-
await handleShowStatus();
|
|
2153
|
-
break;
|
|
2154
|
-
case "help":
|
|
2155
|
-
showHelp();
|
|
2156
|
-
break;
|
|
2157
|
-
case "exit":
|
|
2158
|
-
running = false;
|
|
2159
|
-
break;
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
|
-
outro(pc3.green("MCP Hub closed."));
|
|
2163
|
-
}
|
|
2164
|
-
async function handleInstallWizard(workspacePath) {
|
|
2165
|
-
const status = checkInstallStatus(workspacePath);
|
|
2166
|
-
const options = [
|
|
2167
|
-
{
|
|
2168
|
-
value: "antigravity",
|
|
2169
|
-
label: "Antigravity IDE",
|
|
2170
|
-
hint: status.antigravity ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
2171
|
-
},
|
|
2172
|
-
{
|
|
2173
|
-
value: "vscode-global",
|
|
2174
|
-
label: "VSCode (Global Settings)",
|
|
2175
|
-
hint: status.vscodeGlobal ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
2176
|
-
},
|
|
2177
|
-
{
|
|
2178
|
-
value: "vscode-workspace",
|
|
2179
|
-
label: "VSCode (Workspace Config)",
|
|
2180
|
-
hint: status.vscodeWorkspace ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
2181
|
-
},
|
|
2182
|
-
{
|
|
2183
|
-
value: "claude",
|
|
2184
|
-
label: "Claude Desktop",
|
|
2185
|
-
hint: status.claude ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
2186
|
-
}
|
|
2187
|
-
];
|
|
2188
|
-
const selected = await multiselect({
|
|
2189
|
-
message: "Select where to install RRCE MCP Server:",
|
|
2190
|
-
options,
|
|
2191
|
-
initialValues: [
|
|
2192
|
-
...status.antigravity ? ["antigravity"] : [],
|
|
2193
|
-
...status.vscodeGlobal ? ["vscode-global"] : [],
|
|
2194
|
-
...status.vscodeWorkspace ? ["vscode-workspace"] : [],
|
|
2195
|
-
...status.claude ? ["claude"] : []
|
|
2196
|
-
],
|
|
2197
|
-
required: false
|
|
2198
|
-
});
|
|
2199
|
-
if (isCancel2(selected)) return;
|
|
2200
|
-
const targets = selected;
|
|
2201
|
-
const results = [];
|
|
2202
|
-
for (const target of targets) {
|
|
2203
|
-
const success = installToConfig(target, workspacePath);
|
|
2204
|
-
const label = getTargetLabel(target);
|
|
2205
|
-
results.push(`${label}: ${success ? pc3.green("\u2713 Success") : pc3.red("\u2717 Failed")}`);
|
|
2206
|
-
}
|
|
2207
|
-
if (results.length > 0) {
|
|
2208
|
-
note2(results.join("\n"), "Installation Results");
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2327
|
+
// src/mcp/commands/start.ts
|
|
2328
|
+
import { confirm, isCancel as isCancel4, text } from "@clack/prompts";
|
|
2211
2329
|
async function handleStartServer() {
|
|
2212
2330
|
const React7 = await import("react");
|
|
2213
2331
|
const { render } = await import("ink");
|
|
2214
2332
|
const { App: App2 } = await Promise.resolve().then(() => (init_App(), App_exports));
|
|
2215
|
-
const
|
|
2216
|
-
const config = loadMCPConfig2();
|
|
2333
|
+
const config = loadMCPConfig();
|
|
2217
2334
|
const projects = scanForProjects();
|
|
2218
2335
|
const exposedProjects = projects.filter((p) => {
|
|
2219
|
-
const cfg = config.projects.find(
|
|
2336
|
+
const cfg = config.projects.find(
|
|
2337
|
+
(c) => c.path && c.path === p.dataPath || !c.path && c.name === p.name
|
|
2338
|
+
);
|
|
2220
2339
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
2221
2340
|
});
|
|
2222
2341
|
if (exposedProjects.length === 0) {
|
|
@@ -2224,7 +2343,7 @@ async function handleStartServer() {
|
|
|
2224
2343
|
message: "No projects are currently exposed. Configure now?",
|
|
2225
2344
|
initialValue: true
|
|
2226
2345
|
});
|
|
2227
|
-
if (shouldConfig && !
|
|
2346
|
+
if (shouldConfig && !isCancel4(shouldConfig)) {
|
|
2228
2347
|
await handleConfigure();
|
|
2229
2348
|
return handleStartServer();
|
|
2230
2349
|
}
|
|
@@ -2240,11 +2359,11 @@ async function handleStartServer() {
|
|
|
2240
2359
|
if (isNaN(Number(value))) return "Port must be a number";
|
|
2241
2360
|
}
|
|
2242
2361
|
});
|
|
2243
|
-
if (
|
|
2362
|
+
if (isCancel4(portInput)) return;
|
|
2244
2363
|
const newPort = parseInt(portInput, 10);
|
|
2245
2364
|
if (newPort !== config.server.port) {
|
|
2246
2365
|
config.server.port = newPort;
|
|
2247
|
-
|
|
2366
|
+
saveMCPConfig(config);
|
|
2248
2367
|
initialPort = newPort;
|
|
2249
2368
|
}
|
|
2250
2369
|
}
|
|
@@ -2277,50 +2396,27 @@ async function handleStartServer() {
|
|
|
2277
2396
|
} else if (nextAction === "install") {
|
|
2278
2397
|
console.clear();
|
|
2279
2398
|
const workspacePath = detectWorkspaceRoot();
|
|
2280
|
-
await
|
|
2399
|
+
await runInstallWizard(workspacePath);
|
|
2281
2400
|
}
|
|
2282
2401
|
}
|
|
2283
2402
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
locally in each project. MCP needs a central location.`,
|
|
2294
|
-
"Global Path Required"
|
|
2295
|
-
);
|
|
2296
|
-
const resolvedPath = await resolveGlobalPath2();
|
|
2297
|
-
if (!resolvedPath) {
|
|
2298
|
-
return false;
|
|
2403
|
+
var init_start = __esm({
|
|
2404
|
+
"src/mcp/commands/start.ts"() {
|
|
2405
|
+
"use strict";
|
|
2406
|
+
init_config();
|
|
2407
|
+
init_detection();
|
|
2408
|
+
init_server();
|
|
2409
|
+
init_paths();
|
|
2410
|
+
init_configure();
|
|
2411
|
+
init_install_wizard();
|
|
2299
2412
|
}
|
|
2300
|
-
|
|
2301
|
-
if (!fs17.existsSync(resolvedPath)) {
|
|
2302
|
-
fs17.mkdirSync(resolvedPath, { recursive: true });
|
|
2303
|
-
}
|
|
2304
|
-
const config = loadMCPConfig();
|
|
2305
|
-
saveMCPConfig(config);
|
|
2306
|
-
note2(
|
|
2307
|
-
`${pc3.green("\u2713")} Global path configured: ${pc3.cyan(resolvedPath)}
|
|
2413
|
+
});
|
|
2308
2414
|
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
);
|
|
2313
|
-
return true;
|
|
2314
|
-
} catch (error) {
|
|
2315
|
-
note2(
|
|
2316
|
-
`${pc3.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
|
|
2317
|
-
"Error"
|
|
2318
|
-
);
|
|
2319
|
-
return false;
|
|
2320
|
-
}
|
|
2321
|
-
}
|
|
2415
|
+
// src/mcp/commands/status.ts
|
|
2416
|
+
import { spinner as spinner2, note as note4 } from "@clack/prompts";
|
|
2417
|
+
import pc5 from "picocolors";
|
|
2322
2418
|
async function handleShowStatus() {
|
|
2323
|
-
const s =
|
|
2419
|
+
const s = spinner2();
|
|
2324
2420
|
s.start("Loading projects...");
|
|
2325
2421
|
const config = loadMCPConfig();
|
|
2326
2422
|
const projects = scanForProjects();
|
|
@@ -2328,161 +2424,262 @@ async function handleShowStatus() {
|
|
|
2328
2424
|
const installStatus = checkInstallStatus(workspacePath);
|
|
2329
2425
|
s.stop("Projects loaded");
|
|
2330
2426
|
if (projects.length === 0) {
|
|
2331
|
-
|
|
2427
|
+
note4('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
2332
2428
|
return;
|
|
2333
2429
|
}
|
|
2334
2430
|
const lines = [
|
|
2335
|
-
`${
|
|
2431
|
+
`${pc5.bold("Installation Status")}`,
|
|
2336
2432
|
"",
|
|
2337
|
-
` Antigravity: ${installStatus.antigravity ?
|
|
2338
|
-
` VSCode (Global): ${installStatus.vscodeGlobal ?
|
|
2339
|
-
` VSCode (Workspace): ${installStatus.vscodeWorkspace ?
|
|
2340
|
-
` Claude Desktop: ${installStatus.claude ?
|
|
2433
|
+
` Antigravity: ${installStatus.antigravity ? pc5.green("\u2713 Installed") : pc5.dim("Not installed")}`,
|
|
2434
|
+
` VSCode (Global): ${installStatus.vscodeGlobal ? pc5.green("\u2713 Installed") : pc5.dim("Not installed")}`,
|
|
2435
|
+
` VSCode (Workspace): ${installStatus.vscodeWorkspace ? pc5.green("\u2713 Installed") : pc5.dim("Not installed")}`,
|
|
2436
|
+
` Claude Desktop: ${installStatus.claude ? pc5.green("\u2713 Installed") : pc5.dim("Not installed")}`,
|
|
2341
2437
|
"",
|
|
2342
|
-
`${
|
|
2438
|
+
`${pc5.bold("Project Status")}`,
|
|
2343
2439
|
""
|
|
2344
2440
|
];
|
|
2345
2441
|
for (const project of projects) {
|
|
2346
2442
|
const projectConfig = config.projects.find((p) => p.name === project.name);
|
|
2347
2443
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
2348
|
-
const status = isExposed ?
|
|
2349
|
-
const source =
|
|
2444
|
+
const status = isExposed ? pc5.green("\u2713 exposed") : pc5.dim("\u25CB hidden");
|
|
2445
|
+
const source = pc5.dim(`(${project.source})`);
|
|
2350
2446
|
lines.push(` ${status} ${project.name} ${source}`);
|
|
2351
2447
|
}
|
|
2352
2448
|
lines.push("");
|
|
2353
|
-
lines.push(
|
|
2449
|
+
lines.push(pc5.dim(`Config: ${getMCPConfigPath()}`));
|
|
2354
2450
|
const serverStatus = getMCPServerStatus();
|
|
2355
2451
|
if (serverStatus.running) {
|
|
2356
|
-
lines.push(
|
|
2452
|
+
lines.push(pc5.green(`Server: running on port ${serverStatus.port}`));
|
|
2357
2453
|
} else {
|
|
2358
|
-
lines.push(
|
|
2454
|
+
lines.push(pc5.dim("Server: not running"));
|
|
2359
2455
|
}
|
|
2360
|
-
|
|
2456
|
+
note4(lines.join("\n"), "MCP Hub Status");
|
|
2361
2457
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
if (projects.length === 0) {
|
|
2371
|
-
note2('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
2372
|
-
return;
|
|
2458
|
+
var init_status = __esm({
|
|
2459
|
+
"src/mcp/commands/status.ts"() {
|
|
2460
|
+
"use strict";
|
|
2461
|
+
init_config();
|
|
2462
|
+
init_detection();
|
|
2463
|
+
init_paths();
|
|
2464
|
+
init_server();
|
|
2465
|
+
init_install();
|
|
2373
2466
|
}
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
}
|
|
2393
|
-
|
|
2394
|
-
|
|
2467
|
+
});
|
|
2468
|
+
|
|
2469
|
+
// src/mcp/commands/help.ts
|
|
2470
|
+
import { note as note5 } from "@clack/prompts";
|
|
2471
|
+
import pc6 from "picocolors";
|
|
2472
|
+
function showHelp() {
|
|
2473
|
+
const help = `
|
|
2474
|
+
${pc6.bold("RRCE MCP Hub")} - Cross-project AI assistant server
|
|
2475
|
+
|
|
2476
|
+
${pc6.bold("ABOUT")}
|
|
2477
|
+
MCP (Model Context Protocol) allows AI assistants like Claude to
|
|
2478
|
+
access your project knowledge in real-time. The RRCE MCP Hub
|
|
2479
|
+
provides a central server that exposes selected projects.
|
|
2480
|
+
|
|
2481
|
+
${pc6.bold("MENU OPTIONS")}
|
|
2482
|
+
${pc6.cyan("Start MCP server")} Start the server for AI access
|
|
2483
|
+
${pc6.cyan("Configure projects")} Choose which projects to expose
|
|
2484
|
+
${pc6.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
|
|
2485
|
+
${pc6.cyan("View status")} See which projects are exposed
|
|
2486
|
+
|
|
2487
|
+
${pc6.bold("DIRECT COMMANDS")}
|
|
2488
|
+
${pc6.dim("rrce-workflow mcp start")} Start server directly
|
|
2489
|
+
${pc6.dim("rrce-workflow mcp stop")} Stop server directly
|
|
2490
|
+
${pc6.dim("rrce-workflow mcp status")} Show status directly
|
|
2491
|
+
${pc6.dim("rrce-workflow mcp help")} Show this help
|
|
2492
|
+
|
|
2493
|
+
${pc6.bold("IDE INSTALLATION")}
|
|
2494
|
+
${pc6.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
|
|
2495
|
+
${pc6.cyan("VSCode Global")} ~/.config/Code/User/settings.json
|
|
2496
|
+
${pc6.cyan("VSCode Workspace")} .vscode/mcp.json
|
|
2497
|
+
${pc6.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
|
|
2498
|
+
|
|
2499
|
+
${pc6.bold("SERVER COMMANDS")} (while running)
|
|
2500
|
+
${pc6.cyan("q")} Stop and quit ${pc6.cyan("p")} Reconfigure projects
|
|
2501
|
+
${pc6.cyan("i")} Install to IDE ${pc6.cyan("r")} Reload config
|
|
2502
|
+
${pc6.cyan("c")} Clear logs ${pc6.cyan("?")} Show help
|
|
2503
|
+
|
|
2504
|
+
${pc6.bold("RESOURCES EXPOSED")}
|
|
2505
|
+
${pc6.cyan("rrce://projects")} List all exposed projects
|
|
2506
|
+
${pc6.cyan("rrce://projects/{name}/context")} Get project context
|
|
2507
|
+
${pc6.cyan("rrce://projects/{name}/tasks")} Get project tasks
|
|
2508
|
+
`;
|
|
2509
|
+
note5(help.trim(), "Help");
|
|
2510
|
+
}
|
|
2511
|
+
var init_help = __esm({
|
|
2512
|
+
"src/mcp/commands/help.ts"() {
|
|
2513
|
+
"use strict";
|
|
2395
2514
|
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2515
|
+
});
|
|
2516
|
+
|
|
2517
|
+
// src/mcp/index.ts
|
|
2518
|
+
var mcp_exports = {};
|
|
2519
|
+
__export(mcp_exports, {
|
|
2520
|
+
handleConfigure: () => handleConfigure,
|
|
2521
|
+
handleConfigureGlobalPath: () => handleConfigureGlobalPath,
|
|
2522
|
+
handleStartServer: () => handleStartServer,
|
|
2523
|
+
runMCP: () => runMCP
|
|
2524
|
+
});
|
|
2525
|
+
import { intro, outro, select as select2, confirm as confirm2, note as note6, cancel, isCancel as isCancel5 } from "@clack/prompts";
|
|
2526
|
+
import pc7 from "picocolors";
|
|
2527
|
+
async function runMCP(subcommand2) {
|
|
2528
|
+
if (subcommand2) {
|
|
2529
|
+
switch (subcommand2) {
|
|
2530
|
+
case "start":
|
|
2531
|
+
if (process.stdout.isTTY) {
|
|
2532
|
+
await handleStartServer();
|
|
2533
|
+
} else {
|
|
2534
|
+
await startMCPServer();
|
|
2535
|
+
await new Promise(() => {
|
|
2536
|
+
});
|
|
2537
|
+
}
|
|
2538
|
+
return;
|
|
2539
|
+
case "stop":
|
|
2540
|
+
await handleStopServer();
|
|
2541
|
+
return;
|
|
2542
|
+
case "status":
|
|
2543
|
+
await handleShowStatus();
|
|
2544
|
+
return;
|
|
2545
|
+
case "help":
|
|
2546
|
+
showHelp();
|
|
2547
|
+
return;
|
|
2548
|
+
case "configure":
|
|
2549
|
+
await handleConfigure();
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2401
2552
|
}
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
const
|
|
2405
|
-
|
|
2406
|
-
|
|
2553
|
+
intro(pc7.bgCyan(pc7.black(" RRCE MCP Hub ")));
|
|
2554
|
+
const workspacePath = detectWorkspaceRoot();
|
|
2555
|
+
const globalPathCheck = await ensureMCPGlobalPath();
|
|
2556
|
+
if (!globalPathCheck.configured) {
|
|
2557
|
+
const configured = await handleConfigureGlobalPath();
|
|
2558
|
+
if (!configured) {
|
|
2559
|
+
outro(pc7.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
2560
|
+
return;
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
const installed = isInstalledAnywhere(workspacePath);
|
|
2564
|
+
if (!installed) {
|
|
2565
|
+
note6(
|
|
2566
|
+
`${pc7.bold("Welcome to RRCE MCP Hub!")}
|
|
2407
2567
|
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2568
|
+
MCP (Model Context Protocol) allows AI assistants to access your
|
|
2569
|
+
project knowledge in real-time. Let's get you set up.`,
|
|
2570
|
+
"Getting Started"
|
|
2571
|
+
);
|
|
2572
|
+
const shouldInstall = await confirm2({
|
|
2573
|
+
message: "Install MCP server to your IDE(s)?",
|
|
2574
|
+
initialValue: true
|
|
2575
|
+
});
|
|
2576
|
+
if (shouldInstall && !isCancel5(shouldInstall)) {
|
|
2577
|
+
await runInstallWizard(workspacePath);
|
|
2578
|
+
const config2 = loadMCPConfig();
|
|
2579
|
+
const exposedCount2 = config2.projects.filter((p) => p.expose).length;
|
|
2580
|
+
if (exposedCount2 === 0) {
|
|
2581
|
+
await handleConfigure();
|
|
2582
|
+
}
|
|
2583
|
+
const shouldStart = await confirm2({
|
|
2584
|
+
message: "Start the MCP server now?",
|
|
2585
|
+
initialValue: true
|
|
2586
|
+
});
|
|
2587
|
+
if (shouldStart && !isCancel5(shouldStart)) {
|
|
2588
|
+
await handleStartServer();
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
outro(pc7.green("MCP Hub setup complete!"));
|
|
2592
|
+
return;
|
|
2593
|
+
}
|
|
2594
|
+
const config = loadMCPConfig();
|
|
2595
|
+
const exposedCount = config.projects.filter((p) => p.expose).length;
|
|
2596
|
+
if (exposedCount === 0 && !config.defaults.includeNew) {
|
|
2597
|
+
note6("MCP is installed but no projects are exposed. Let's configure that.", "Configuration Needed");
|
|
2598
|
+
await handleConfigure();
|
|
2599
|
+
}
|
|
2600
|
+
let running = true;
|
|
2601
|
+
while (running) {
|
|
2602
|
+
const serverStatus = getMCPServerStatus();
|
|
2603
|
+
const serverLabel = serverStatus.running ? pc7.green("\u25CF Running") : pc7.dim("\u25CB Stopped");
|
|
2604
|
+
const currentStatus = checkInstallStatus(workspacePath);
|
|
2605
|
+
const installedCount = [currentStatus.antigravity, currentStatus.claude, currentStatus.vscodeGlobal, currentStatus.vscodeWorkspace].filter(Boolean).length;
|
|
2606
|
+
const action = await select2({
|
|
2607
|
+
message: "What would you like to do?",
|
|
2608
|
+
options: [
|
|
2609
|
+
{ value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: serverLabel },
|
|
2610
|
+
{ value: "configure", label: "\u2699\uFE0F Configure projects", hint: "Choose which projects to expose" },
|
|
2611
|
+
{ value: "install", label: "\u{1F4E5} Install to IDE", hint: `${installedCount} IDE(s) configured` },
|
|
2612
|
+
{ value: "status", label: "\u{1F4CB} View status", hint: "See details" },
|
|
2613
|
+
{ value: "help", label: "\u2753 Help", hint: "Learn about MCP Hub" },
|
|
2614
|
+
{ value: "exit", label: "\u21A9 Exit", hint: "Return to shell" }
|
|
2615
|
+
]
|
|
2616
|
+
});
|
|
2617
|
+
if (isCancel5(action)) {
|
|
2618
|
+
cancel("MCP Hub closed.");
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
switch (action) {
|
|
2622
|
+
case "start":
|
|
2623
|
+
await handleStartServer();
|
|
2624
|
+
break;
|
|
2625
|
+
case "configure":
|
|
2626
|
+
await handleConfigure();
|
|
2627
|
+
break;
|
|
2628
|
+
case "install":
|
|
2629
|
+
await runInstallWizard(workspacePath);
|
|
2630
|
+
break;
|
|
2631
|
+
case "status":
|
|
2632
|
+
await handleShowStatus();
|
|
2633
|
+
break;
|
|
2634
|
+
case "help":
|
|
2635
|
+
showHelp();
|
|
2636
|
+
break;
|
|
2637
|
+
case "exit":
|
|
2638
|
+
running = false;
|
|
2639
|
+
break;
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
outro(pc7.green("MCP Hub closed."));
|
|
2412
2643
|
}
|
|
2413
2644
|
async function handleStopServer() {
|
|
2645
|
+
const { stopMCPServer: stopMCPServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2414
2646
|
const status = getMCPServerStatus();
|
|
2415
2647
|
if (!status.running) {
|
|
2416
|
-
|
|
2648
|
+
note6("MCP server is not running.", "Status");
|
|
2417
2649
|
return;
|
|
2418
2650
|
}
|
|
2419
|
-
const confirmed = await
|
|
2651
|
+
const confirmed = await confirm2({
|
|
2420
2652
|
message: "Stop the MCP server?",
|
|
2421
2653
|
initialValue: true
|
|
2422
2654
|
});
|
|
2423
|
-
if (
|
|
2655
|
+
if (isCancel5(confirmed) || !confirmed) {
|
|
2424
2656
|
return;
|
|
2425
2657
|
}
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
}
|
|
2429
|
-
function showHelp() {
|
|
2430
|
-
const help = `
|
|
2431
|
-
${pc3.bold("RRCE MCP Hub")} - Cross-project AI assistant server
|
|
2432
|
-
|
|
2433
|
-
${pc3.bold("ABOUT")}
|
|
2434
|
-
MCP (Model Context Protocol) allows AI assistants like Claude to
|
|
2435
|
-
access your project knowledge in real-time. The RRCE MCP Hub
|
|
2436
|
-
provides a central server that exposes selected projects.
|
|
2437
|
-
|
|
2438
|
-
${pc3.bold("MENU OPTIONS")}
|
|
2439
|
-
${pc3.cyan("Start MCP server")} Start the server for AI access
|
|
2440
|
-
${pc3.cyan("Configure projects")} Choose which projects to expose
|
|
2441
|
-
${pc3.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
|
|
2442
|
-
${pc3.cyan("View status")} See which projects are exposed
|
|
2443
|
-
|
|
2444
|
-
${pc3.bold("DIRECT COMMANDS")}
|
|
2445
|
-
${pc3.dim("rrce-workflow mcp start")} Start server directly
|
|
2446
|
-
${pc3.dim("rrce-workflow mcp stop")} Stop server directly
|
|
2447
|
-
${pc3.dim("rrce-workflow mcp status")} Show status directly
|
|
2448
|
-
${pc3.dim("rrce-workflow mcp help")} Show this help
|
|
2449
|
-
|
|
2450
|
-
${pc3.bold("IDE INSTALLATION")}
|
|
2451
|
-
${pc3.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
|
|
2452
|
-
${pc3.cyan("VSCode Global")} ~/.config/Code/User/settings.json
|
|
2453
|
-
${pc3.cyan("VSCode Workspace")} .vscode/mcp.json
|
|
2454
|
-
${pc3.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
|
|
2455
|
-
|
|
2456
|
-
${pc3.bold("SERVER COMMANDS")} (while running)
|
|
2457
|
-
${pc3.cyan("q")} Stop and quit ${pc3.cyan("p")} Reconfigure projects
|
|
2458
|
-
${pc3.cyan("i")} Install to IDE ${pc3.cyan("r")} Reload config
|
|
2459
|
-
${pc3.cyan("c")} Clear logs ${pc3.cyan("?")} Show help
|
|
2460
|
-
|
|
2461
|
-
${pc3.bold("RESOURCES EXPOSED")}
|
|
2462
|
-
${pc3.cyan("rrce://projects")} List all exposed projects
|
|
2463
|
-
${pc3.cyan("rrce://projects/{name}/context")} Get project context
|
|
2464
|
-
${pc3.cyan("rrce://projects/{name}/tasks")} Get project tasks
|
|
2465
|
-
`;
|
|
2466
|
-
note2(help.trim(), "Help");
|
|
2658
|
+
stopMCPServer2();
|
|
2659
|
+
note6(pc7.green("MCP server stopped."), "Server Stopped");
|
|
2467
2660
|
}
|
|
2468
2661
|
var init_mcp = __esm({
|
|
2469
2662
|
"src/mcp/index.ts"() {
|
|
2470
2663
|
"use strict";
|
|
2471
2664
|
init_config();
|
|
2472
|
-
init_detection();
|
|
2473
2665
|
init_server();
|
|
2474
2666
|
init_install();
|
|
2475
2667
|
init_paths();
|
|
2668
|
+
init_start();
|
|
2669
|
+
init_configure();
|
|
2670
|
+
init_status();
|
|
2671
|
+
init_install_wizard();
|
|
2672
|
+
init_help();
|
|
2476
2673
|
}
|
|
2477
2674
|
});
|
|
2478
2675
|
|
|
2479
2676
|
// src/commands/wizard/setup-flow.ts
|
|
2480
|
-
import { group, select as select3, multiselect as
|
|
2481
|
-
import
|
|
2677
|
+
import { group, select as select3, multiselect as multiselect3, confirm as confirm3, spinner as spinner3, note as note7, outro as outro2, cancel as cancel2, isCancel as isCancel6 } from "@clack/prompts";
|
|
2678
|
+
import pc8 from "picocolors";
|
|
2482
2679
|
import * as fs12 from "fs";
|
|
2483
2680
|
import * as path12 from "path";
|
|
2484
2681
|
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
2485
|
-
const s =
|
|
2682
|
+
const s = spinner3();
|
|
2486
2683
|
const config = await group(
|
|
2487
2684
|
{
|
|
2488
2685
|
storageMode: () => select3({
|
|
@@ -2493,7 +2690,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2493
2690
|
],
|
|
2494
2691
|
initialValue: "global"
|
|
2495
2692
|
}),
|
|
2496
|
-
tools: () =>
|
|
2693
|
+
tools: () => multiselect3({
|
|
2497
2694
|
message: "Which AI tools do you use?",
|
|
2498
2695
|
options: [
|
|
2499
2696
|
{ value: "copilot", label: "GitHub Copilot", hint: "VSCode" },
|
|
@@ -2505,28 +2702,28 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2505
2702
|
if (existingProjects.length === 0) {
|
|
2506
2703
|
return Promise.resolve([]);
|
|
2507
2704
|
}
|
|
2508
|
-
return
|
|
2705
|
+
return multiselect3({
|
|
2509
2706
|
message: "Link knowledge from other projects?",
|
|
2510
2707
|
options: existingProjects.map((project) => ({
|
|
2511
2708
|
value: `${project.name}:${project.source}`,
|
|
2512
2709
|
// Unique key
|
|
2513
|
-
label: `${project.name} ${
|
|
2514
|
-
hint:
|
|
2710
|
+
label: `${project.name} ${pc8.dim(`(${project.source})`)}`,
|
|
2711
|
+
hint: pc8.dim(
|
|
2515
2712
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
2516
2713
|
)
|
|
2517
2714
|
})),
|
|
2518
2715
|
required: false
|
|
2519
2716
|
});
|
|
2520
2717
|
},
|
|
2521
|
-
addToGitignore: () =>
|
|
2718
|
+
addToGitignore: () => confirm3({
|
|
2522
2719
|
message: "Add generated folders to .gitignore? (as comments - uncomment if needed)",
|
|
2523
2720
|
initialValue: true
|
|
2524
2721
|
}),
|
|
2525
|
-
confirm: () =>
|
|
2722
|
+
confirm: () => confirm3({
|
|
2526
2723
|
message: "Create configuration?",
|
|
2527
2724
|
initialValue: true
|
|
2528
2725
|
}),
|
|
2529
|
-
exposeToMCP: () =>
|
|
2726
|
+
exposeToMCP: () => confirm3({
|
|
2530
2727
|
message: "Expose this project to MCP (AI Agent) server?",
|
|
2531
2728
|
initialValue: true
|
|
2532
2729
|
})
|
|
@@ -2571,7 +2768,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2571
2768
|
`Storage: ${config.storageMode}`
|
|
2572
2769
|
];
|
|
2573
2770
|
if (customGlobalPath && customGlobalPath !== getDefaultRRCEHome()) {
|
|
2574
|
-
summary.push(`Global path: ${
|
|
2771
|
+
summary.push(`Global path: ${pc8.cyan(customGlobalPath)}`);
|
|
2575
2772
|
}
|
|
2576
2773
|
if (dataPaths.length > 0) {
|
|
2577
2774
|
summary.push(`Data paths:`);
|
|
@@ -2584,29 +2781,29 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2584
2781
|
const linkedProjects = config.linkedProjects;
|
|
2585
2782
|
if (linkedProjects.length > 0) {
|
|
2586
2783
|
summary.push(`Linked projects: ${linkedProjects.join(", ")}`);
|
|
2587
|
-
summary.push(`Workspace file: ${
|
|
2784
|
+
summary.push(`Workspace file: ${pc8.cyan(`${workspaceName}.code-workspace`)}`);
|
|
2588
2785
|
}
|
|
2589
|
-
|
|
2786
|
+
note7(summary.join("\n"), "Setup Summary");
|
|
2590
2787
|
if (config.exposeToMCP) {
|
|
2591
|
-
|
|
2788
|
+
note7(`${pc8.green("\u2713")} Project exposed to MCP Hub`, "MCP Configuration");
|
|
2592
2789
|
if (linkedProjects.length > 0) {
|
|
2593
|
-
outro2(
|
|
2790
|
+
outro2(pc8.green(`\u2713 Setup complete! Open ${pc8.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
2594
2791
|
} else {
|
|
2595
|
-
outro2(
|
|
2792
|
+
outro2(pc8.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
2596
2793
|
}
|
|
2597
2794
|
} else {
|
|
2598
|
-
const shouldConfigureMCP = await
|
|
2795
|
+
const shouldConfigureMCP = await confirm3({
|
|
2599
2796
|
message: "Would you like to configure the MCP server now?",
|
|
2600
2797
|
initialValue: true
|
|
2601
2798
|
});
|
|
2602
|
-
if (shouldConfigureMCP && !
|
|
2799
|
+
if (shouldConfigureMCP && !isCancel6(shouldConfigureMCP)) {
|
|
2603
2800
|
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
2604
2801
|
await runMCP2();
|
|
2605
2802
|
} else {
|
|
2606
2803
|
if (linkedProjects.length > 0) {
|
|
2607
|
-
outro2(
|
|
2804
|
+
outro2(pc8.green(`\u2713 Setup complete! Open ${pc8.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
2608
2805
|
} else {
|
|
2609
|
-
outro2(
|
|
2806
|
+
outro2(pc8.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
2610
2807
|
}
|
|
2611
2808
|
}
|
|
2612
2809
|
}
|
|
@@ -2770,8 +2967,8 @@ var init_setup_flow = __esm({
|
|
|
2770
2967
|
});
|
|
2771
2968
|
|
|
2772
2969
|
// src/commands/wizard/link-flow.ts
|
|
2773
|
-
import { multiselect as
|
|
2774
|
-
import
|
|
2970
|
+
import { multiselect as multiselect4, spinner as spinner4, note as note8, outro as outro3, cancel as cancel3, isCancel as isCancel7, confirm as confirm4 } from "@clack/prompts";
|
|
2971
|
+
import pc9 from "picocolors";
|
|
2775
2972
|
import * as fs13 from "fs";
|
|
2776
2973
|
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
2777
2974
|
const projects = scanForProjects({
|
|
@@ -2779,23 +2976,23 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
2779
2976
|
workspacePath
|
|
2780
2977
|
});
|
|
2781
2978
|
if (projects.length === 0) {
|
|
2782
|
-
outro3(
|
|
2979
|
+
outro3(pc9.yellow("No other projects found. Try setting up another project first."));
|
|
2783
2980
|
return;
|
|
2784
2981
|
}
|
|
2785
2982
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
2786
|
-
const linkedProjects = await
|
|
2983
|
+
const linkedProjects = await multiselect4({
|
|
2787
2984
|
message: "Select projects to link:",
|
|
2788
2985
|
options: projects.map((project) => ({
|
|
2789
2986
|
value: `${project.name}:${project.source}`,
|
|
2790
2987
|
// Unique key
|
|
2791
|
-
label: `${project.name} ${
|
|
2792
|
-
hint:
|
|
2988
|
+
label: `${project.name} ${pc9.dim(`(${project.source})`)}`,
|
|
2989
|
+
hint: pc9.dim(
|
|
2793
2990
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
2794
2991
|
)
|
|
2795
2992
|
})),
|
|
2796
2993
|
required: true
|
|
2797
2994
|
});
|
|
2798
|
-
if (
|
|
2995
|
+
if (isCancel7(linkedProjects)) {
|
|
2799
2996
|
cancel3("Cancelled.");
|
|
2800
2997
|
process.exit(0);
|
|
2801
2998
|
}
|
|
@@ -2807,7 +3004,7 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
2807
3004
|
const selectedProjects = projects.filter(
|
|
2808
3005
|
(p) => selectedKeys.includes(`${p.name}:${p.source}`)
|
|
2809
3006
|
);
|
|
2810
|
-
const s =
|
|
3007
|
+
const s = spinner4();
|
|
2811
3008
|
s.start("Linking projects");
|
|
2812
3009
|
const configFilePath = getConfigPath(workspacePath);
|
|
2813
3010
|
let configContent = fs13.readFileSync(configFilePath, "utf-8");
|
|
@@ -2843,12 +3040,29 @@ linked_projects:
|
|
|
2843
3040
|
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
2844
3041
|
const summary = [
|
|
2845
3042
|
`Linked projects:`,
|
|
2846
|
-
...selectedProjects.map((p) => ` \u2713 ${p.name} ${
|
|
3043
|
+
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc9.dim(`(${p.source})`)}`),
|
|
2847
3044
|
``,
|
|
2848
|
-
`Workspace file: ${
|
|
3045
|
+
`Workspace file: ${pc9.cyan(workspaceFile)}`
|
|
2849
3046
|
];
|
|
2850
|
-
|
|
2851
|
-
outro3(
|
|
3047
|
+
note8(summary.join("\n"), "Link Summary");
|
|
3048
|
+
outro3(pc9.green(`\u2713 Projects linked! Open ${pc9.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
3049
|
+
const shouldExpose = await confirm4({
|
|
3050
|
+
message: "Also expose these linked projects to the MCP server (for Agent access)?",
|
|
3051
|
+
initialValue: true
|
|
3052
|
+
});
|
|
3053
|
+
if (shouldExpose && !isCancel7(shouldExpose)) {
|
|
3054
|
+
try {
|
|
3055
|
+
const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3056
|
+
const mcpConfig = loadMCPConfig2();
|
|
3057
|
+
for (const project of selectedProjects) {
|
|
3058
|
+
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
3059
|
+
}
|
|
3060
|
+
saveMCPConfig2(mcpConfig);
|
|
3061
|
+
note8("Projects have been added to the global MCP configuration.", "MCP Updated");
|
|
3062
|
+
} catch (err) {
|
|
3063
|
+
note8(`Failed to update MCP config: ${err}`, "MCP Update Failed");
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
2852
3066
|
}
|
|
2853
3067
|
var init_link_flow = __esm({
|
|
2854
3068
|
"src/commands/wizard/link-flow.ts"() {
|
|
@@ -2860,8 +3074,8 @@ var init_link_flow = __esm({
|
|
|
2860
3074
|
});
|
|
2861
3075
|
|
|
2862
3076
|
// src/commands/wizard/sync-flow.ts
|
|
2863
|
-
import { confirm as
|
|
2864
|
-
import
|
|
3077
|
+
import { confirm as confirm5, spinner as spinner5, note as note9, outro as outro4, cancel as cancel4, isCancel as isCancel8 } from "@clack/prompts";
|
|
3078
|
+
import pc10 from "picocolors";
|
|
2865
3079
|
import * as fs14 from "fs";
|
|
2866
3080
|
import * as path13 from "path";
|
|
2867
3081
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
@@ -2873,25 +3087,25 @@ async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
|
2873
3087
|
(dir) => fs14.existsSync(path13.join(localPath, dir))
|
|
2874
3088
|
);
|
|
2875
3089
|
if (existingDirs.length === 0) {
|
|
2876
|
-
outro4(
|
|
3090
|
+
outro4(pc10.yellow("No data found in workspace storage to sync."));
|
|
2877
3091
|
return;
|
|
2878
3092
|
}
|
|
2879
|
-
|
|
3093
|
+
note9(
|
|
2880
3094
|
`The following will be copied to global storage:
|
|
2881
3095
|
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
2882
3096
|
|
|
2883
|
-
Destination: ${
|
|
3097
|
+
Destination: ${pc10.cyan(globalPath)}`,
|
|
2884
3098
|
"Sync Preview"
|
|
2885
3099
|
);
|
|
2886
|
-
const shouldSync = await
|
|
3100
|
+
const shouldSync = await confirm5({
|
|
2887
3101
|
message: "Proceed with sync to global storage?",
|
|
2888
3102
|
initialValue: true
|
|
2889
3103
|
});
|
|
2890
|
-
if (
|
|
3104
|
+
if (isCancel8(shouldSync) || !shouldSync) {
|
|
2891
3105
|
outro4("Sync cancelled.");
|
|
2892
3106
|
return;
|
|
2893
3107
|
}
|
|
2894
|
-
const s =
|
|
3108
|
+
const s = spinner5();
|
|
2895
3109
|
s.start("Syncing to global storage");
|
|
2896
3110
|
try {
|
|
2897
3111
|
ensureDir(globalPath);
|
|
@@ -2906,12 +3120,12 @@ Destination: ${pc6.cyan(globalPath)}`,
|
|
|
2906
3120
|
`Synced directories:`,
|
|
2907
3121
|
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
2908
3122
|
``,
|
|
2909
|
-
`Global path: ${
|
|
3123
|
+
`Global path: ${pc10.cyan(globalPath)}`,
|
|
2910
3124
|
``,
|
|
2911
3125
|
`Other projects can now link this knowledge!`
|
|
2912
3126
|
];
|
|
2913
|
-
|
|
2914
|
-
outro4(
|
|
3127
|
+
note9(summary.join("\n"), "Sync Summary");
|
|
3128
|
+
outro4(pc10.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
2915
3129
|
} catch (error) {
|
|
2916
3130
|
s.stop("Error occurred");
|
|
2917
3131
|
cancel4(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -2927,12 +3141,12 @@ var init_sync_flow = __esm({
|
|
|
2927
3141
|
});
|
|
2928
3142
|
|
|
2929
3143
|
// src/commands/wizard/update-flow.ts
|
|
2930
|
-
import { confirm as
|
|
2931
|
-
import
|
|
3144
|
+
import { confirm as confirm6, spinner as spinner6, note as note10, outro as outro5, cancel as cancel5, isCancel as isCancel9 } from "@clack/prompts";
|
|
3145
|
+
import pc11 from "picocolors";
|
|
2932
3146
|
import * as fs15 from "fs";
|
|
2933
3147
|
import * as path14 from "path";
|
|
2934
3148
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
2935
|
-
const s =
|
|
3149
|
+
const s = spinner6();
|
|
2936
3150
|
s.start("Checking for updates");
|
|
2937
3151
|
try {
|
|
2938
3152
|
const agentCoreDir = getAgentCoreDir();
|
|
@@ -2941,7 +3155,7 @@ async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
|
2941
3155
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
2942
3156
|
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
2943
3157
|
s.stop("Updates found");
|
|
2944
|
-
|
|
3158
|
+
note10(
|
|
2945
3159
|
`The following will be updated from the package:
|
|
2946
3160
|
\u2022 prompts/ (${prompts.length} agent prompts)
|
|
2947
3161
|
\u2022 templates/ (output templates)
|
|
@@ -2950,11 +3164,11 @@ Target locations:
|
|
|
2950
3164
|
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
2951
3165
|
"Update Preview"
|
|
2952
3166
|
);
|
|
2953
|
-
const shouldUpdate = await
|
|
3167
|
+
const shouldUpdate = await confirm6({
|
|
2954
3168
|
message: "Proceed with update?",
|
|
2955
3169
|
initialValue: true
|
|
2956
3170
|
});
|
|
2957
|
-
if (
|
|
3171
|
+
if (isCancel9(shouldUpdate) || !shouldUpdate) {
|
|
2958
3172
|
outro5("Update cancelled.");
|
|
2959
3173
|
return;
|
|
2960
3174
|
}
|
|
@@ -2982,8 +3196,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
2982
3196
|
``,
|
|
2983
3197
|
`Your configuration and knowledge files were preserved.`
|
|
2984
3198
|
];
|
|
2985
|
-
|
|
2986
|
-
outro5(
|
|
3199
|
+
note10(summary.join("\n"), "Update Summary");
|
|
3200
|
+
outro5(pc11.green("\u2713 Successfully updated from package!"));
|
|
2987
3201
|
} catch (error) {
|
|
2988
3202
|
s.stop("Error occurred");
|
|
2989
3203
|
cancel5(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -3016,21 +3230,21 @@ var wizard_exports = {};
|
|
|
3016
3230
|
__export(wizard_exports, {
|
|
3017
3231
|
runWizard: () => runWizard
|
|
3018
3232
|
});
|
|
3019
|
-
import { intro as intro2, select as select4, spinner as
|
|
3020
|
-
import
|
|
3233
|
+
import { intro as intro2, select as select4, spinner as spinner7, note as note11, outro as outro6, isCancel as isCancel10 } from "@clack/prompts";
|
|
3234
|
+
import pc12 from "picocolors";
|
|
3021
3235
|
import * as fs16 from "fs";
|
|
3022
3236
|
async function runWizard() {
|
|
3023
|
-
intro2(
|
|
3024
|
-
const s =
|
|
3237
|
+
intro2(pc12.cyan(pc12.inverse(" RRCE-Workflow Setup ")));
|
|
3238
|
+
const s = spinner7();
|
|
3025
3239
|
s.start("Detecting environment");
|
|
3026
3240
|
const workspacePath = detectWorkspaceRoot();
|
|
3027
3241
|
const workspaceName = getWorkspaceName(workspacePath);
|
|
3028
3242
|
const gitUser = getGitUser();
|
|
3029
3243
|
await new Promise((r) => setTimeout(r, 800));
|
|
3030
3244
|
s.stop("Environment detected");
|
|
3031
|
-
|
|
3032
|
-
`Git User: ${
|
|
3033
|
-
Workspace: ${
|
|
3245
|
+
note11(
|
|
3246
|
+
`Git User: ${pc12.bold(gitUser || "(not found)")}
|
|
3247
|
+
Workspace: ${pc12.bold(workspaceName)}`,
|
|
3034
3248
|
"Context"
|
|
3035
3249
|
);
|
|
3036
3250
|
const detectedProjects = scanForProjects({
|
|
@@ -3072,12 +3286,13 @@ Workspace: ${pc8.bold(workspaceName)}`,
|
|
|
3072
3286
|
});
|
|
3073
3287
|
}
|
|
3074
3288
|
menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
|
|
3289
|
+
menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
|
|
3075
3290
|
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
3076
3291
|
const action = await select4({
|
|
3077
3292
|
message: "This workspace is already configured. What would you like to do?",
|
|
3078
3293
|
options: menuOptions
|
|
3079
3294
|
});
|
|
3080
|
-
if (
|
|
3295
|
+
if (isCancel10(action) || action === "exit") {
|
|
3081
3296
|
outro6("Exited.");
|
|
3082
3297
|
process.exit(0);
|
|
3083
3298
|
}
|
|
@@ -3097,6 +3312,8 @@ Workspace: ${pc8.bold(workspaceName)}`,
|
|
|
3097
3312
|
await runUpdateFlow(workspacePath, workspaceName, currentStorageMode);
|
|
3098
3313
|
return;
|
|
3099
3314
|
}
|
|
3315
|
+
if (action === "reconfigure") {
|
|
3316
|
+
}
|
|
3100
3317
|
}
|
|
3101
3318
|
await runSetupFlow(workspacePath, workspaceName, detectedProjects);
|
|
3102
3319
|
}
|
|
@@ -3119,12 +3336,12 @@ init_wizard();
|
|
|
3119
3336
|
|
|
3120
3337
|
// src/commands/selector.ts
|
|
3121
3338
|
init_prompts();
|
|
3122
|
-
import { intro as intro3, select as select5, note as
|
|
3123
|
-
import
|
|
3339
|
+
import { intro as intro3, select as select5, note as note12, cancel as cancel7, isCancel as isCancel11, outro as outro7 } from "@clack/prompts";
|
|
3340
|
+
import pc13 from "picocolors";
|
|
3124
3341
|
import * as path15 from "path";
|
|
3125
3342
|
async function runSelector() {
|
|
3126
3343
|
const workspaceName = path15.basename(process.cwd());
|
|
3127
|
-
intro3(
|
|
3344
|
+
intro3(pc13.cyan(pc13.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
3128
3345
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
3129
3346
|
if (prompts.length === 0) {
|
|
3130
3347
|
cancel7("No agents found. Run `rrce-workflow` to set up.");
|
|
@@ -3150,7 +3367,7 @@ async function runSelector() {
|
|
|
3150
3367
|
}))
|
|
3151
3368
|
]
|
|
3152
3369
|
});
|
|
3153
|
-
if (
|
|
3370
|
+
if (isCancel11(selection)) {
|
|
3154
3371
|
cancel7("Selection cancelled.");
|
|
3155
3372
|
process.exit(0);
|
|
3156
3373
|
}
|
|
@@ -3165,9 +3382,9 @@ async function runSelector() {
|
|
|
3165
3382
|
return;
|
|
3166
3383
|
}
|
|
3167
3384
|
const prompt = selection;
|
|
3168
|
-
|
|
3385
|
+
note12(
|
|
3169
3386
|
`Use this agent in your IDE by invoking:
|
|
3170
|
-
${
|
|
3387
|
+
${pc13.bold(pc13.cyan(`@${prompt.frontmatter.name}`))}`,
|
|
3171
3388
|
"Agent Selected"
|
|
3172
3389
|
);
|
|
3173
3390
|
outro7("Done");
|