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.
Files changed (2) hide show
  1. package/dist/index.js +165 -16
  2. 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
- console.error(`RRCE MCP Hub started (pid: ${process.pid})`);
1210
- console.error(`Exposed projects: ${exposed}`);
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
- const shouldConfigureMCP = await confirm2({
2468
- message: "Would you like to configure the MCP server now?",
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.33",
3
+ "version": "0.2.35",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",