rrce-workflow 0.2.33 → 0.2.35
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 +165 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,6 +25,29 @@ var init_git = __esm({
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
// src/lib/paths.ts
|
|
28
|
+
var paths_exports = {};
|
|
29
|
+
__export(paths_exports, {
|
|
30
|
+
checkWriteAccess: () => checkWriteAccess,
|
|
31
|
+
copyDirToAllStoragePaths: () => copyDirToAllStoragePaths,
|
|
32
|
+
copyToAllStoragePaths: () => copyToAllStoragePaths,
|
|
33
|
+
detectWorkspaceRoot: () => detectWorkspaceRoot,
|
|
34
|
+
ensureDir: () => ensureDir,
|
|
35
|
+
getAgentPromptPath: () => getAgentPromptPath,
|
|
36
|
+
getConfigPath: () => getConfigPath,
|
|
37
|
+
getDefaultRRCEHome: () => getDefaultRRCEHome,
|
|
38
|
+
getEffectiveRRCEHome: () => getEffectiveRRCEHome,
|
|
39
|
+
getGlobalProjectKnowledgePath: () => getGlobalProjectKnowledgePath,
|
|
40
|
+
getGlobalWorkspacePath: () => getGlobalWorkspacePath,
|
|
41
|
+
getLocalWorkspacePath: () => getLocalWorkspacePath,
|
|
42
|
+
getRRCEHome: () => getRRCEHome,
|
|
43
|
+
getSuggestedGlobalPaths: () => getSuggestedGlobalPaths,
|
|
44
|
+
getWorkspaceName: () => getWorkspaceName,
|
|
45
|
+
listGlobalProjects: () => listGlobalProjects,
|
|
46
|
+
resolveAllDataPaths: () => resolveAllDataPaths,
|
|
47
|
+
resolveDataPath: () => resolveDataPath,
|
|
48
|
+
syncMetadataToAll: () => syncMetadataToAll,
|
|
49
|
+
writeToAllStoragePaths: () => writeToAllStoragePaths
|
|
50
|
+
});
|
|
28
51
|
import * as fs from "fs";
|
|
29
52
|
import * as path from "path";
|
|
30
53
|
function detectWorkspaceRoot() {
|
|
@@ -54,9 +77,49 @@ function getConfigPath(workspaceRoot) {
|
|
|
54
77
|
function getWorkspaceName(workspaceRoot) {
|
|
55
78
|
return path.basename(workspaceRoot);
|
|
56
79
|
}
|
|
80
|
+
function resolveDataPath(mode, workspaceName, workspaceRoot) {
|
|
81
|
+
switch (mode) {
|
|
82
|
+
case "global":
|
|
83
|
+
return path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
84
|
+
case "workspace":
|
|
85
|
+
return path.join(workspaceRoot, ".rrce-workflow");
|
|
86
|
+
default:
|
|
87
|
+
return path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function resolveAllDataPaths(mode, workspaceName, workspaceRoot) {
|
|
91
|
+
const globalPath = path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
92
|
+
const workspacePath = path.join(workspaceRoot, ".rrce-workflow");
|
|
93
|
+
switch (mode) {
|
|
94
|
+
case "global":
|
|
95
|
+
return [globalPath];
|
|
96
|
+
case "workspace":
|
|
97
|
+
return [workspacePath];
|
|
98
|
+
default:
|
|
99
|
+
return [globalPath];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
57
102
|
function getRRCEHome() {
|
|
58
103
|
return RRCE_HOME;
|
|
59
104
|
}
|
|
105
|
+
function listGlobalProjects(excludeWorkspace) {
|
|
106
|
+
const workspacesDir = path.join(RRCE_HOME, "workspaces");
|
|
107
|
+
if (!fs.existsSync(workspacesDir)) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const entries = fs.readdirSync(workspacesDir, { withFileTypes: true });
|
|
112
|
+
return entries.filter((entry) => entry.isDirectory() && entry.name !== excludeWorkspace).map((entry) => entry.name);
|
|
113
|
+
} catch {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function getGlobalProjectKnowledgePath(projectName) {
|
|
118
|
+
return path.join(RRCE_HOME, "workspaces", projectName, "knowledge");
|
|
119
|
+
}
|
|
120
|
+
function getGlobalWorkspacePath(workspaceName) {
|
|
121
|
+
return path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
122
|
+
}
|
|
60
123
|
function getLocalWorkspacePath(workspaceRoot) {
|
|
61
124
|
return path.join(workspaceRoot, ".rrce-workflow");
|
|
62
125
|
}
|
|
@@ -80,6 +143,13 @@ function copyToAllStoragePaths(sourceFile, relativePath, dataPaths) {
|
|
|
80
143
|
fs.writeFileSync(targetPath, content);
|
|
81
144
|
}
|
|
82
145
|
}
|
|
146
|
+
function writeToAllStoragePaths(content, relativePath, dataPaths) {
|
|
147
|
+
for (const dataPath of dataPaths) {
|
|
148
|
+
const targetPath = path.join(dataPath, relativePath);
|
|
149
|
+
ensureDir(path.dirname(targetPath));
|
|
150
|
+
fs.writeFileSync(targetPath, content);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
83
153
|
function copyDirToAllStoragePaths(sourceDir, relativeDir, dataPaths) {
|
|
84
154
|
if (!fs.existsSync(sourceDir)) {
|
|
85
155
|
return;
|
|
@@ -124,6 +194,25 @@ function checkWriteAccess(dirPath) {
|
|
|
124
194
|
function getDefaultRRCEHome() {
|
|
125
195
|
return process.env.RRCE_HOME || path.join(process.env.HOME || "~", ".rrce-workflow");
|
|
126
196
|
}
|
|
197
|
+
function getSuggestedGlobalPaths() {
|
|
198
|
+
const suggestions = [];
|
|
199
|
+
if (process.env.RRCE_HOME) {
|
|
200
|
+
suggestions.push({
|
|
201
|
+
path: process.env.RRCE_HOME,
|
|
202
|
+
label: "RRCE_HOME (environment)",
|
|
203
|
+
isWritable: checkWriteAccess(process.env.RRCE_HOME)
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const homeDefault = path.join(process.env.HOME || "~", ".rrce-workflow");
|
|
207
|
+
if (!process.env.RRCE_HOME || process.env.RRCE_HOME !== homeDefault) {
|
|
208
|
+
suggestions.push({
|
|
209
|
+
path: homeDefault,
|
|
210
|
+
label: "~/.rrce-workflow (default)",
|
|
211
|
+
isWritable: checkWriteAccess(homeDefault)
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return suggestions;
|
|
215
|
+
}
|
|
127
216
|
function getEffectiveRRCEHome(workspaceRoot) {
|
|
128
217
|
if (workspaceRoot) {
|
|
129
218
|
const configPath = getConfigPath(workspaceRoot);
|
|
@@ -1206,8 +1295,10 @@ async function startMCPServer(options = {}) {
|
|
|
1206
1295
|
serverState = { running: true, port: config.server.port, pid: process.pid };
|
|
1207
1296
|
const exposed = getExposedProjects().map((p) => p.name).join(", ");
|
|
1208
1297
|
logger.info(`RRCE MCP Hub started (pid: ${process.pid})`, { exposedProjects: exposed });
|
|
1209
|
-
|
|
1210
|
-
|
|
1298
|
+
if (!options.interactive) {
|
|
1299
|
+
console.error(`RRCE MCP Hub started (pid: ${process.pid})`);
|
|
1300
|
+
console.error(`Exposed projects: ${exposed}`);
|
|
1301
|
+
}
|
|
1211
1302
|
return { port: config.server.port, pid: process.pid };
|
|
1212
1303
|
} catch (error) {
|
|
1213
1304
|
logger.error("Failed to start MCP server", error);
|
|
@@ -1283,8 +1374,8 @@ function registerResourceHandlers(server) {
|
|
|
1283
1374
|
});
|
|
1284
1375
|
}
|
|
1285
1376
|
function registerToolHandlers(server) {
|
|
1286
|
-
server.setRequestHandler(ListToolsRequestSchema, async () =>
|
|
1287
|
-
tools
|
|
1377
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1378
|
+
const tools = [
|
|
1288
1379
|
{
|
|
1289
1380
|
name: "search_knowledge",
|
|
1290
1381
|
description: "Search across all exposed project knowledge bases",
|
|
@@ -1325,8 +1416,17 @@ function registerToolHandlers(server) {
|
|
|
1325
1416
|
required: ["agent"]
|
|
1326
1417
|
}
|
|
1327
1418
|
}
|
|
1328
|
-
]
|
|
1329
|
-
|
|
1419
|
+
];
|
|
1420
|
+
const projects = getExposedProjects();
|
|
1421
|
+
if (projects.length === 0) {
|
|
1422
|
+
tools.push({
|
|
1423
|
+
name: "help_setup",
|
|
1424
|
+
description: "Get help on how to configure projects for the RRCE MCP Server",
|
|
1425
|
+
inputSchema: { type: "object", properties: {} }
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
return { tools };
|
|
1429
|
+
});
|
|
1330
1430
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1331
1431
|
const { name, arguments: args } = request.params;
|
|
1332
1432
|
logger.info(`Calling tool: ${name}`, args);
|
|
@@ -1404,6 +1504,18 @@ Note: If the user's request refers to a project not listed here, ask them to exp
|
|
|
1404
1504
|
`;
|
|
1405
1505
|
return { content: [{ type: "text", text: contextPreamble + content }] };
|
|
1406
1506
|
}
|
|
1507
|
+
case "help_setup": {
|
|
1508
|
+
const msg = `
|
|
1509
|
+
RRCE MCP Server is running, but no projects are configured/exposed.
|
|
1510
|
+
|
|
1511
|
+
To fix this:
|
|
1512
|
+
1. Open a terminal.
|
|
1513
|
+
2. Run: npx rrce-workflow mcp configure
|
|
1514
|
+
3. Select the projects you want to expose to the AI.
|
|
1515
|
+
4. Restart the MCP server (or it may pick up changes automatically).
|
|
1516
|
+
`;
|
|
1517
|
+
return { content: [{ type: "text", text: msg }] };
|
|
1518
|
+
}
|
|
1407
1519
|
default:
|
|
1408
1520
|
throw new Error(`Unknown tool: ${name}`);
|
|
1409
1521
|
}
|
|
@@ -1458,6 +1570,13 @@ function registerPromptHandlers(server) {
|
|
|
1458
1570
|
Context - Available Projects (MCP Hub):
|
|
1459
1571
|
${projectList}
|
|
1460
1572
|
`;
|
|
1573
|
+
if (projects.length === 0) {
|
|
1574
|
+
contextPreamble += `
|
|
1575
|
+
WARNING: No projects are currently exposed to the MCP server.
|
|
1576
|
+
The user needs to run 'npx rrce-workflow mcp configure' in their terminal to select projects to expose.
|
|
1577
|
+
Please advise the user to do this if they expect to see project context.
|
|
1578
|
+
`;
|
|
1579
|
+
}
|
|
1461
1580
|
if (activeProject) {
|
|
1462
1581
|
contextPreamble += `
|
|
1463
1582
|
Current Active Workspace: ${activeProject.name} (${activeProject.path})
|
|
@@ -1495,7 +1614,6 @@ function stopMCPServer() {
|
|
|
1495
1614
|
}
|
|
1496
1615
|
serverState = { running: false };
|
|
1497
1616
|
logger.info("RRCE MCP Hub stopped");
|
|
1498
|
-
console.error("RRCE MCP Hub stopped");
|
|
1499
1617
|
}
|
|
1500
1618
|
function getMCPServerStatus() {
|
|
1501
1619
|
return { ...serverState };
|
|
@@ -2407,6 +2525,10 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2407
2525
|
confirm: () => confirm2({
|
|
2408
2526
|
message: "Create configuration?",
|
|
2409
2527
|
initialValue: true
|
|
2528
|
+
}),
|
|
2529
|
+
exposeToMCP: () => confirm2({
|
|
2530
|
+
message: "Expose this project to MCP (AI Agent) server?",
|
|
2531
|
+
initialValue: true
|
|
2410
2532
|
})
|
|
2411
2533
|
},
|
|
2412
2534
|
{
|
|
@@ -2435,7 +2557,8 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2435
2557
|
globalPath: customGlobalPath,
|
|
2436
2558
|
tools: config.tools,
|
|
2437
2559
|
linkedProjects: config.linkedProjects,
|
|
2438
|
-
addToGitignore: config.addToGitignore
|
|
2560
|
+
addToGitignore: config.addToGitignore,
|
|
2561
|
+
exposeToMCP: config.exposeToMCP
|
|
2439
2562
|
}, workspacePath, workspaceName, existingProjects);
|
|
2440
2563
|
s.stop("Configuration generated");
|
|
2441
2564
|
const dataPaths = getDataPaths(
|
|
@@ -2464,19 +2587,28 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2464
2587
|
summary.push(`Workspace file: ${pc4.cyan(`${workspaceName}.code-workspace`)}`);
|
|
2465
2588
|
}
|
|
2466
2589
|
note3(summary.join("\n"), "Setup Summary");
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
initialValue: true
|
|
2470
|
-
});
|
|
2471
|
-
if (shouldConfigureMCP && !isCancel3(shouldConfigureMCP)) {
|
|
2472
|
-
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
2473
|
-
await runMCP2();
|
|
2474
|
-
} else {
|
|
2590
|
+
if (config.exposeToMCP) {
|
|
2591
|
+
note3(`${pc4.green("\u2713")} Project exposed to MCP Hub`, "MCP Configuration");
|
|
2475
2592
|
if (linkedProjects.length > 0) {
|
|
2476
2593
|
outro2(pc4.green(`\u2713 Setup complete! Open ${pc4.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
2477
2594
|
} else {
|
|
2478
2595
|
outro2(pc4.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
2479
2596
|
}
|
|
2597
|
+
} else {
|
|
2598
|
+
const shouldConfigureMCP = await confirm2({
|
|
2599
|
+
message: "Would you like to configure the MCP server now?",
|
|
2600
|
+
initialValue: true
|
|
2601
|
+
});
|
|
2602
|
+
if (shouldConfigureMCP && !isCancel3(shouldConfigureMCP)) {
|
|
2603
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
2604
|
+
await runMCP2();
|
|
2605
|
+
} else {
|
|
2606
|
+
if (linkedProjects.length > 0) {
|
|
2607
|
+
outro2(pc4.green(`\u2713 Setup complete! Open ${pc4.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
2608
|
+
} else {
|
|
2609
|
+
outro2(pc4.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2480
2612
|
}
|
|
2481
2613
|
} catch (error) {
|
|
2482
2614
|
s.stop("Error occurred");
|
|
@@ -2546,6 +2678,23 @@ linked_projects:
|
|
|
2546
2678
|
);
|
|
2547
2679
|
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, config.globalPath);
|
|
2548
2680
|
}
|
|
2681
|
+
if (config.exposeToMCP) {
|
|
2682
|
+
try {
|
|
2683
|
+
const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
2684
|
+
const { getWorkspaceName: getWorkspaceName2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
2685
|
+
const mcpConfig = loadMCPConfig2();
|
|
2686
|
+
const currentProjectName = workspaceName;
|
|
2687
|
+
if (config.storageMode === "workspace") {
|
|
2688
|
+
setProjectConfig2(mcpConfig, currentProjectName, true);
|
|
2689
|
+
saveMCPConfig2(mcpConfig);
|
|
2690
|
+
} else {
|
|
2691
|
+
setProjectConfig2(mcpConfig, currentProjectName, true);
|
|
2692
|
+
saveMCPConfig2(mcpConfig);
|
|
2693
|
+
}
|
|
2694
|
+
} catch (e) {
|
|
2695
|
+
console.error("Failed to update MCP config:", e);
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2549
2698
|
}
|
|
2550
2699
|
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
2551
2700
|
const globalPath = path12.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
|