rrce-workflow 0.2.85 → 0.2.87

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 +134 -44
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -100,17 +100,45 @@ function getConfigPath(workspaceRoot) {
100
100
  if (fs2.existsSync(mcpConfigPath)) {
101
101
  const mcpContent = fs2.readFileSync(mcpConfigPath, "utf-8");
102
102
  const lines = mcpContent.split("\n");
103
+ let inProjects = false;
103
104
  let currentName = "";
105
+ let currentPath = "";
104
106
  for (let i = 0; i < lines.length; i++) {
105
- const line = lines[i]?.trim();
106
- if (!line) continue;
107
- if (line.startsWith("- name:")) {
108
- currentName = line.replace("- name:", "").trim();
109
- } else if (line.startsWith("path:")) {
110
- const p = line.replace("path:", "").trim();
111
- if (p === workspaceRoot || p === `"${workspaceRoot}"` || p === `'${workspaceRoot}'`) {
112
- return path2.join(rrceHome, "workspaces", currentName, "config.yaml");
107
+ const line = lines[i];
108
+ const trimmed = line.trim();
109
+ if (trimmed.startsWith("projects:")) {
110
+ inProjects = true;
111
+ continue;
112
+ }
113
+ if (inProjects && line.match(/^[a-zA-Z0-9_-]+:/)) {
114
+ inProjects = false;
115
+ }
116
+ if (!inProjects) continue;
117
+ if (trimmed.startsWith("-")) {
118
+ if (currentName && currentPath) {
119
+ if (currentPath === workspaceRoot || currentPath === `"${workspaceRoot}"` || currentPath === `'${workspaceRoot}'`) {
120
+ return path2.join(rrceHome, "workspaces", currentName, "config.yaml");
121
+ }
122
+ }
123
+ currentName = "";
124
+ currentPath = "";
125
+ const contentAfterDash = trimmed.substring(1).trim();
126
+ if (contentAfterDash.startsWith("name:")) {
127
+ currentName = contentAfterDash.replace("name:", "").trim();
128
+ } else if (contentAfterDash.startsWith("path:")) {
129
+ currentPath = contentAfterDash.replace("path:", "").trim();
113
130
  }
131
+ } else {
132
+ if (trimmed.startsWith("name:")) {
133
+ currentName = trimmed.replace("name:", "").trim();
134
+ } else if (trimmed.startsWith("path:")) {
135
+ currentPath = trimmed.replace("path:", "").trim();
136
+ }
137
+ }
138
+ }
139
+ if (currentName && currentPath) {
140
+ if (currentPath === workspaceRoot || currentPath === `"${workspaceRoot}"` || currentPath === `'${workspaceRoot}'`) {
141
+ return path2.join(rrceHome, "workspaces", currentName, "config.yaml");
114
142
  }
115
143
  }
116
144
  }
@@ -221,10 +249,18 @@ var init_paths = __esm({
221
249
  import * as fs3 from "fs";
222
250
  import * as path3 from "path";
223
251
  function scanForProjects(options = {}) {
224
- const { excludeWorkspace, workspacePath, knownPaths } = options;
252
+ const { excludeWorkspace, workspacePath, knownPaths, knownProjects } = options;
225
253
  const projects = [];
226
254
  const seenPaths = /* @__PURE__ */ new Set();
227
- if (knownPaths && knownPaths.length > 0) {
255
+ if (knownProjects && knownProjects.length > 0) {
256
+ const explicitProjects = scanKnownProjects(knownProjects, excludeWorkspace);
257
+ for (const project of explicitProjects) {
258
+ if (!seenPaths.has(project.dataPath)) {
259
+ seenPaths.add(project.dataPath);
260
+ projects.push(project);
261
+ }
262
+ }
263
+ } else if (knownPaths && knownPaths.length > 0) {
228
264
  const explicitProjects = scanKnownPaths(knownPaths, excludeWorkspace);
229
265
  for (const project of explicitProjects) {
230
266
  if (!seenPaths.has(project.dataPath)) {
@@ -249,6 +285,60 @@ function scanForProjects(options = {}) {
249
285
  }
250
286
  return projects;
251
287
  }
288
+ function scanKnownProjects(projects, excludeWorkspace) {
289
+ const results = [];
290
+ const rrceHome = getEffectiveGlobalPath();
291
+ for (const p of projects) {
292
+ try {
293
+ if (!p.path || !fs3.existsSync(p.path)) continue;
294
+ if (p.name === excludeWorkspace) continue;
295
+ const localConfigPath = path3.join(p.path, ".rrce-workflow", "config.yaml");
296
+ if (fs3.existsSync(localConfigPath)) {
297
+ const config = parseWorkspaceConfig(localConfigPath);
298
+ const fullPath = path3.join(p.path, ".rrce-workflow");
299
+ const knowledgePath = path3.join(fullPath, "knowledge");
300
+ const refsPath = path3.join(fullPath, "refs");
301
+ const tasksPath = path3.join(fullPath, "tasks");
302
+ results.push({
303
+ name: p.name,
304
+ // Use MCP name
305
+ path: p.path,
306
+ dataPath: fullPath,
307
+ source: "local",
308
+ storageMode: config?.storageMode || "workspace",
309
+ knowledgePath: fs3.existsSync(knowledgePath) ? knowledgePath : void 0,
310
+ refsPath: fs3.existsSync(refsPath) ? refsPath : void 0,
311
+ tasksPath: fs3.existsSync(tasksPath) ? tasksPath : void 0,
312
+ semanticSearchEnabled: config?.semanticSearchEnabled
313
+ });
314
+ continue;
315
+ }
316
+ const globalDataPath = path3.join(rrceHome, "workspaces", p.name);
317
+ if (fs3.existsSync(globalDataPath)) {
318
+ const knowledgePath = path3.join(globalDataPath, "knowledge");
319
+ const refsPath = path3.join(globalDataPath, "refs");
320
+ const tasksPath = path3.join(globalDataPath, "tasks");
321
+ const configPath = path3.join(globalDataPath, "config.yaml");
322
+ const config = parseWorkspaceConfig(configPath);
323
+ results.push({
324
+ name: p.name,
325
+ path: p.path,
326
+ // We know this is the source path
327
+ sourcePath: p.path,
328
+ dataPath: globalDataPath,
329
+ source: "global",
330
+ storageMode: "global",
331
+ knowledgePath: fs3.existsSync(knowledgePath) ? knowledgePath : void 0,
332
+ refsPath: fs3.existsSync(refsPath) ? refsPath : void 0,
333
+ tasksPath: fs3.existsSync(tasksPath) ? tasksPath : void 0,
334
+ semanticSearchEnabled: config?.semanticSearchEnabled
335
+ });
336
+ }
337
+ } catch {
338
+ }
339
+ }
340
+ return results;
341
+ }
252
342
  function scanKnownPaths(paths, excludeWorkspace) {
253
343
  const projects = [];
254
344
  for (const p of paths) {
@@ -301,7 +391,7 @@ function scanGlobalStorage(excludeWorkspace) {
301
391
  projects.push({
302
392
  name: config?.name || entry.name,
303
393
  path: projectDataPath,
304
- // Still use dataPath as defaults, BUT...
394
+ // Default to dataPath if sourcePath unknown
305
395
  sourcePath: config?.sourcePath,
306
396
  // ...expose sourcePath if available
307
397
  dataPath: projectDataPath,
@@ -365,11 +455,11 @@ function scanHomeDirectory(excludePath) {
365
455
  function parseWorkspaceConfig(configPath) {
366
456
  try {
367
457
  const content = fs3.readFileSync(configPath, "utf-8");
368
- const nameMatch = content.match(/name:\s*["']?([^"'\n]+)["']?/);
369
- const sourcePathMatch = content.match(/sourcePath:\s*["']?([^"'\n]+)["']?/);
458
+ const nameMatch = content.match(/name:\s*["']?([^"'\n\r]+)["']?/);
459
+ const sourcePathMatch = content.match(/sourcePath:\s*["']?([^"'\n\r]+)["']?/);
370
460
  const modeMatch = content.match(/mode:\s*(global|workspace)/);
371
461
  const linkedProjects = [];
372
- const linkedMatch = content.match(/linked_projects:\s*\n((?:\s+-\s+[^\n]+\n?)+)/);
462
+ const linkedMatch = content.match(/linked_projects:\s*\n((?:\s+-\s+[^\n\r]+\n?)+)/);
373
463
  if (linkedMatch && linkedMatch[1]) {
374
464
  const lines = linkedMatch[1].split("\n");
375
465
  for (const line of lines) {
@@ -2219,8 +2309,8 @@ import * as path16 from "path";
2219
2309
  import * as crypto from "crypto";
2220
2310
  function getExposedProjects() {
2221
2311
  const config = loadMCPConfig();
2222
- const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
2223
- const allProjects = projectService.scan({ knownPaths });
2312
+ const knownProjects = config.projects.filter((p) => !!p.path).map((p) => ({ name: p.name, path: p.path }));
2313
+ const allProjects = projectService.scan({ knownProjects });
2224
2314
  const activeProject = detectActiveProject(allProjects);
2225
2315
  const potentialProjects = [...allProjects];
2226
2316
  if (activeProject) {
@@ -2270,8 +2360,8 @@ function detectActiveProject(knownProjects) {
2270
2360
  let scanList = knownProjects;
2271
2361
  if (!scanList) {
2272
2362
  const config = loadMCPConfig();
2273
- const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
2274
- const all = projectService.scan({ knownPaths });
2363
+ const knownProjectsMap = config.projects.filter((p) => !!p.path).map((p) => ({ name: p.name, path: p.path }));
2364
+ const all = projectService.scan({ knownProjects: knownProjectsMap });
2275
2365
  scanList = all.filter((project) => isProjectExposed(config, project.name, project.sourcePath || project.path));
2276
2366
  }
2277
2367
  return findClosestProject(scanList);
@@ -2844,7 +2934,7 @@ function registerToolHandlers(server) {
2844
2934
  server.setRequestHandler(ListToolsRequestSchema, async () => {
2845
2935
  const tools = [
2846
2936
  {
2847
- name: "rrce_search_knowledge",
2937
+ name: "search_knowledge",
2848
2938
  description: "Search across all exposed project knowledge bases",
2849
2939
  inputSchema: {
2850
2940
  type: "object",
@@ -2856,7 +2946,7 @@ function registerToolHandlers(server) {
2856
2946
  }
2857
2947
  },
2858
2948
  {
2859
- name: "rrce_index_knowledge",
2949
+ name: "index_knowledge",
2860
2950
  description: "Update the semantic search index for a specific project",
2861
2951
  inputSchema: {
2862
2952
  type: "object",
@@ -2868,12 +2958,12 @@ function registerToolHandlers(server) {
2868
2958
  }
2869
2959
  },
2870
2960
  {
2871
- name: "rrce_list_projects",
2961
+ name: "list_projects",
2872
2962
  description: "List all projects exposed via MCP. Use these names for project-specific tools.",
2873
2963
  inputSchema: { type: "object", properties: {} }
2874
2964
  },
2875
2965
  {
2876
- name: "rrce_get_project_context",
2966
+ name: "get_project_context",
2877
2967
  description: "Get the project context/architecture for a specific project",
2878
2968
  inputSchema: {
2879
2969
  type: "object",
@@ -2882,12 +2972,12 @@ function registerToolHandlers(server) {
2882
2972
  }
2883
2973
  },
2884
2974
  {
2885
- name: "rrce_list_agents",
2975
+ name: "list_agents",
2886
2976
  description: "List available agents (e.g. init, plan) and their arguments. Use this to discover which agent to call.",
2887
2977
  inputSchema: { type: "object", properties: {} }
2888
2978
  },
2889
2979
  {
2890
- name: "rrce_get_agent_prompt",
2980
+ name: "get_agent_prompt",
2891
2981
  description: 'Get the system prompt for a specific agent. Accepts agent Name (e.g. "RRCE Init") or ID (e.g. "init").',
2892
2982
  inputSchema: {
2893
2983
  type: "object",
@@ -2899,7 +2989,7 @@ function registerToolHandlers(server) {
2899
2989
  }
2900
2990
  },
2901
2991
  {
2902
- name: "rrce_list_tasks",
2992
+ name: "list_tasks",
2903
2993
  description: "List all tasks for a project",
2904
2994
  inputSchema: {
2905
2995
  type: "object",
@@ -2908,7 +2998,7 @@ function registerToolHandlers(server) {
2908
2998
  }
2909
2999
  },
2910
3000
  {
2911
- name: "rrce_get_task",
3001
+ name: "get_task",
2912
3002
  description: "Get details of a specific task",
2913
3003
  inputSchema: {
2914
3004
  type: "object",
@@ -2920,7 +3010,7 @@ function registerToolHandlers(server) {
2920
3010
  }
2921
3011
  },
2922
3012
  {
2923
- name: "rrce_create_task",
3013
+ name: "create_task",
2924
3014
  description: "Create a new task in the project",
2925
3015
  inputSchema: {
2926
3016
  type: "object",
@@ -2934,7 +3024,7 @@ function registerToolHandlers(server) {
2934
3024
  }
2935
3025
  },
2936
3026
  {
2937
- name: "rrce_update_task",
3027
+ name: "update_task",
2938
3028
  description: "Update an existing task",
2939
3029
  inputSchema: {
2940
3030
  type: "object",
@@ -2947,7 +3037,7 @@ function registerToolHandlers(server) {
2947
3037
  }
2948
3038
  },
2949
3039
  {
2950
- name: "rrce_delete_task",
3040
+ name: "delete_task",
2951
3041
  description: "Delete a task from the project",
2952
3042
  inputSchema: {
2953
3043
  type: "object",
@@ -2962,7 +3052,7 @@ function registerToolHandlers(server) {
2962
3052
  const projects = getExposedProjects();
2963
3053
  if (projects.length === 0) {
2964
3054
  tools.push({
2965
- name: "rrce_help_setup",
3055
+ name: "help_setup",
2966
3056
  description: "Get help on how to configure projects for the RRCE MCP Server",
2967
3057
  inputSchema: { type: "object", properties: {} }
2968
3058
  });
@@ -2974,27 +3064,27 @@ function registerToolHandlers(server) {
2974
3064
  logger.info(`Calling tool: ${name}`, args);
2975
3065
  try {
2976
3066
  switch (name) {
2977
- case "rrce_search_knowledge": {
3067
+ case "search_knowledge": {
2978
3068
  const params = args;
2979
3069
  const results = await searchKnowledge(params.query, params.project);
2980
3070
  return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
2981
3071
  }
2982
- case "rrce_index_knowledge": {
3072
+ case "index_knowledge": {
2983
3073
  const params = args;
2984
3074
  const result = await indexKnowledge(params.project, params.force);
2985
3075
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
2986
3076
  }
2987
- case "rrce_list_projects": {
3077
+ case "list_projects": {
2988
3078
  const projects = getExposedProjects();
2989
3079
  const list = projects.map((p) => ({ name: p.name, source: p.source, path: p.path }));
2990
3080
  return {
2991
3081
  content: [{
2992
3082
  type: "text",
2993
- text: JSON.stringify(list, null, 2) + "\n\nTip: Use these project names for tools like `rrce_get_project_context` or `rrce_index_knowledge`."
3083
+ text: JSON.stringify(list, null, 2) + "\n\nTip: Use these project names for tools like `get_project_context` or `index_knowledge`."
2994
3084
  }]
2995
3085
  };
2996
3086
  }
2997
- case "rrce_get_project_context": {
3087
+ case "get_project_context": {
2998
3088
  const context = getProjectContext(args.project);
2999
3089
  if (!context) {
3000
3090
  const projects = getExposedProjects().map((p) => p.name).join(", ");
@@ -3005,7 +3095,7 @@ Available projects: ${projects}`;
3005
3095
  }
3006
3096
  return { content: [{ type: "text", text: context }] };
3007
3097
  }
3008
- case "rrce_list_agents": {
3098
+ case "list_agents": {
3009
3099
  const prompts = getAllPrompts();
3010
3100
  return {
3011
3101
  content: [{
@@ -3015,11 +3105,11 @@ Available projects: ${projects}`;
3015
3105
  id: p.id,
3016
3106
  description: p.description,
3017
3107
  arguments: p.arguments
3018
- })), null, 2) + "\n\nTip: Retrieve the prompt for an agent using `rrce_get_agent_prompt` with its name or ID."
3108
+ })), null, 2) + "\n\nTip: Retrieve the prompt for an agent using `get_agent_prompt` with its name or ID."
3019
3109
  }]
3020
3110
  };
3021
3111
  }
3022
- case "rrce_get_agent_prompt": {
3112
+ case "get_agent_prompt": {
3023
3113
  const params = args;
3024
3114
  const agentName = params.agent;
3025
3115
  const promptDef = getPromptDef(agentName);
@@ -3044,12 +3134,12 @@ The system has pre-resolved the configuration for this project. Use these values
3044
3134
  `;
3045
3135
  return { content: [{ type: "text", text: contextPreamble + rendered }] };
3046
3136
  }
3047
- case "rrce_list_tasks": {
3137
+ case "list_tasks": {
3048
3138
  const params = args;
3049
3139
  const tasks = getProjectTasks(params.project);
3050
3140
  return { content: [{ type: "text", text: JSON.stringify(tasks, null, 2) }] };
3051
3141
  }
3052
- case "rrce_get_task": {
3142
+ case "get_task": {
3053
3143
  const params = args;
3054
3144
  const task = getTask(params.project, params.task_slug);
3055
3145
  if (!task) {
@@ -3057,7 +3147,7 @@ The system has pre-resolved the configuration for this project. Use these values
3057
3147
  }
3058
3148
  return { content: [{ type: "text", text: JSON.stringify(task, null, 2) }] };
3059
3149
  }
3060
- case "rrce_create_task": {
3150
+ case "create_task": {
3061
3151
  const params = args;
3062
3152
  const taskData = {
3063
3153
  title: params.title || params.task_slug,
@@ -3067,18 +3157,18 @@ The system has pre-resolved the configuration for this project. Use these values
3067
3157
  return { content: [{ type: "text", text: `\u2713 Task '${params.task_slug}' created. meta.json saved.
3068
3158
  ${JSON.stringify(task, null, 2)}` }] };
3069
3159
  }
3070
- case "rrce_update_task": {
3160
+ case "update_task": {
3071
3161
  const params = args;
3072
3162
  const task = await updateTask(params.project, params.task_slug, params.updates);
3073
3163
  return { content: [{ type: "text", text: `\u2713 Task '${params.task_slug}' updated. meta.json saved.
3074
3164
  ${JSON.stringify(task, null, 2)}` }] };
3075
3165
  }
3076
- case "rrce_delete_task": {
3166
+ case "delete_task": {
3077
3167
  const params = args;
3078
3168
  const success = deleteTask(params.project, params.task_slug);
3079
3169
  return { content: [{ type: "text", text: success ? `\u2713 Task '${params.task_slug}' deleted.` : `\u2717 Failed to delete '${params.task_slug}'.` }] };
3080
3170
  }
3081
- case "rrce_help_setup": {
3171
+ case "help_setup": {
3082
3172
  const msg = `
3083
3173
  RRCE MCP Server is running, but no projects are configured/exposed.
3084
3174
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.85",
3
+ "version": "0.2.87",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",