rrce-workflow 0.2.71 → 0.2.73

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.
@@ -20,7 +20,7 @@ You are the Project Doctor for RRCE-Workflow. Perform a health check on the code
20
20
 
21
21
  ## Path Resolution
22
22
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
23
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
23
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
24
24
 
25
25
  ## Pipeline Position
26
26
  - **Input**: Can be triggered at any time for project health analysis
@@ -142,7 +142,7 @@ Rank findings using this matrix:
142
142
  ### Step 6: Generate Output
143
143
 
144
144
  1. Create task directory: `{{RRCE_DATA}}/tasks/doctor-{{YYYYMMDD}}/`
145
- 2. Write diagnosis using template: `{{RRCE_HOME}}/templates/doctor_output.md`
145
+ 2. Write diagnosis using template: `{{RRCE_DATA}}/templates/doctor_output.md`
146
146
  3. Save to: `{{RRCE_DATA}}/tasks/doctor-{{YYYYMMDD}}/diagnosis.md`
147
147
 
148
148
  **Output includes:**
@@ -176,7 +176,7 @@ Report:
176
176
  ## Deliverable
177
177
 
178
178
  - **File**: `{{RRCE_DATA}}/tasks/doctor-{{YYYYMMDD}}/diagnosis.md`
179
- - **Template**: `{{RRCE_HOME}}/templates/doctor_output.md`
179
+ - **Template**: `{{RRCE_DATA}}/templates/doctor_output.md`
180
180
  - **Outcome**: Structured diagnosis with prioritized, actionable tasks
181
181
 
182
182
  ## Focus Area Deep Dive
@@ -22,7 +22,7 @@ You are the Documentation Lead for the project. Operate like a senior engineerin
22
22
 
23
23
  ## Path Resolution
24
24
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
25
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
25
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
26
26
 
27
27
  ## Supported DOC_TYPE Values
28
28
 
@@ -68,7 +68,7 @@ Workflow
68
68
  - If `TASK_SLUG` is provided, ensure `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/docs` exists and target `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/docs/{{TASK_SLUG}}-{{DOC_TYPE}}.md`.
69
69
  - Else if `TARGET_PATH` is provided, ensure its parent directory exists (must remain under `{{RRCE_DATA}}/`) and target `{{RRCE_DATA}}/{{TARGET_PATH}}`.
70
70
  - Otherwise, default to `{{RRCE_DATA}}/knowledge/{{DOC_TYPE}}.md` and ensure `{{RRCE_DATA}}/knowledge` exists.
71
- 3. Select a template: prefer `{{RRCE_HOME}}/templates/docs/{{DOC_TYPE}}.md`; fallback to `{{RRCE_HOME}}/templates/documentation_output.md`.
71
+ 3. Select a template: prefer `{{RRCE_DATA}}/templates/docs/{{DOC_TYPE}}.md`; fallback to `{{RRCE_DATA}}/templates/documentation_output.md`.
72
72
  4. Populate contextual metadata (`AUTHOR`, `RELEASE_REF`, task references, dates) and render the document using the chosen template.
73
73
  5. If operating on a task slug, update `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` with documentation artifact paths, new references, final decisions, checklist completions, and remaining follow-ups.
74
74
  6. When broader knowledge changed, update the relevant `{{RRCE_DATA}}/knowledge/*.md` entries with `Updated: YYYY-MM-DD` markers, lean changelog bullets, and a small checklist of follow-ups.
@@ -76,5 +76,5 @@ Workflow
76
76
 
77
77
  Deliverable
78
78
  - File: Resolved from `DOC_TYPE` plus either `TASK_SLUG`, `TARGET_PATH`, or default knowledge location.
79
- - Format: `{{RRCE_HOME}}/templates/docs/{{DOC_TYPE}}.md` when available; otherwise `{{RRCE_HOME}}/templates/documentation_output.md`.
79
+ - Format: `{{RRCE_DATA}}/templates/docs/{{DOC_TYPE}}.md` when available; otherwise `{{RRCE_DATA}}/templates/documentation_output.md`.
80
80
  - Outcome: Documentation tailored to the requested type, summarizing scope, implementation, validations, decisions, references, and leftover work while keeping project knowledge synchronized.
@@ -18,7 +18,7 @@ You are the Executor for the project. Operate like a senior individual contribut
18
18
 
19
19
  ## Path Resolution
20
20
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
21
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
21
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
22
22
 
23
23
  Pipeline Position
24
24
  - **Requires**: Planning phase must be complete before execution can begin.
@@ -85,7 +85,7 @@ Workflow
85
85
  2. Set `agents.executor.status` in `meta.json` to `in_progress` while working and `complete` after delivering.
86
86
  3. Maintain checklist entries with current progress markers and timestamps where helpful.
87
87
  4. Record checkpoints, blockers, and validation steps in `agents.executor.notes` and `references`.
88
- 5. Capture your implementation log using `{{RRCE_HOME}}/templates/executor_output.md` and save it to `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/execution/{{TASK_SLUG}}-execution.md`, noting the provided `BRANCH` or current git ref.
88
+ 5. Capture your implementation log using `{{RRCE_DATA}}/templates/executor_output.md` and save it to `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/execution/{{TASK_SLUG}}-execution.md`, noting the provided `BRANCH` or current git ref.
89
89
  6. Summarize test evidence, code pointers, and outstanding follow-ups so documentation can build on it seamlessly.
90
90
  7. **Semantic Indexing**: If significant code was added or modified, suggest running `index_knowledge` to update the semantic search index:
91
91
  - Tool: `index_knowledge`
@@ -93,5 +93,5 @@ Workflow
93
93
 
94
94
  Deliverable
95
95
  - File: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/execution/{{TASK_SLUG}}-execution.md`
96
- - Format: `{{RRCE_HOME}}/templates/executor_output.md`
96
+ - Format: `{{RRCE_DATA}}/templates/executor_output.md`
97
97
  - Outcome: Implementation log covering what was built, how it was validated, and what remains, kept lean and actionable.
@@ -17,7 +17,7 @@ You are the Project Initializer for RRCE-Workflow. Your mission: create a compre
17
17
 
18
18
  ## Path Resolution
19
19
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
20
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
20
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
21
21
 
22
22
  ## Pipeline Position
23
23
  - **Entry Point**: Run before any other agent for new projects
@@ -122,7 +122,7 @@ Scan in this priority order. Stop early if sufficient information gathered:
122
122
  ### Step 3: Generate Project Context
123
123
 
124
124
  1. Ensure `{{RRCE_DATA}}/knowledge/` directory exists (create if absent)
125
- 2. Compile findings using template: `{{RRCE_HOME}}/templates/init_output.md`
125
+ 2. Compile findings using template: `{{RRCE_DATA}}/templates/init_output.md`
126
126
  3. Save to: `{{RRCE_DATA}}/knowledge/project-context.md`
127
127
  4. Update `{{RRCE_DATA}}/workspace.json` with project metadata if it exists
128
128
 
@@ -160,7 +160,7 @@ Provide a brief summary:
160
160
  ## Deliverable
161
161
 
162
162
  - **File**: `{{RRCE_DATA}}/knowledge/project-context.md`
163
- - **Template**: `{{RRCE_HOME}}/templates/init_output.md`
163
+ - **Template**: `{{RRCE_DATA}}/templates/init_output.md`
164
164
  - **Index**: `{{RRCE_DATA}}/knowledge/embeddings.json`
165
165
  - **Outcome**: Comprehensive project context + searchable semantic index
166
166
 
@@ -15,7 +15,7 @@ You are the Planning & Task Orchestrator for the project. Operate like an engine
15
15
 
16
16
  ## Path Resolution
17
17
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
18
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
18
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
19
19
 
20
20
  Pipeline Position
21
21
  - **Requires**: Research phase must be complete before planning can begin.
@@ -58,12 +58,12 @@ Non-Negotiables
58
58
 
59
59
  Workflow
60
60
  1. Confirm `TASK_SLUG` (prompt if missing) and ensure directories exist at `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning` and `{{RRCE_DATA}}/knowledge`, creating them automatically if absent.
61
- 2. Update `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` (copy the template from `{{RRCE_HOME}}/templates/meta.template.json` if it is not already present):
61
+ 2. Update `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` (copy the template from `{{RRCE_DATA}}/templates/meta.template.json` if it is not already present):
62
62
  - Mark `agents.planning.status` as `in_progress` while drafting and `complete` upon handoff.
63
63
  - Link the plan artifact path in `agents.planning.artifact`.
64
64
  - Populate or refresh `summary`, `references`, `milestones`, `checklist`, and `open_questions`.
65
65
  3. Where new persistent knowledge is created (API notes, domain decisions, etc.), append or create records in `{{RRCE_DATA}}/knowledge/{{DOMAIN}}.md` and log the file path inside `meta.json.references`.
66
- 4. Structure the plan using `{{RRCE_HOME}}/templates/planning_output.md` and store it at `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning/{{TASK_SLUG}}-plan.md`.
66
+ 4. Structure the plan using `{{RRCE_DATA}}/templates/planning_output.md` and store it at `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning/{{TASK_SLUG}}-plan.md`.
67
67
  5. Provide clear guidance on validation, testing strategy, rollout sequencing, and success criteria for the Executor.
68
68
  6. **Semantic Indexing**: If new knowledge files were created in `{{RRCE_DATA}}/knowledge/`, suggest running `index_knowledge` to update the semantic search index:
69
69
  - Tool: `index_knowledge`
@@ -71,5 +71,5 @@ Workflow
71
71
 
72
72
  Deliverable
73
73
  - File: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning/{{TASK_SLUG}}-plan.md`
74
- - Format: `{{RRCE_HOME}}/templates/planning_output.md`
74
+ - Format: `{{RRCE_DATA}}/templates/planning_output.md`
75
75
  - Outcome: Ordered, actionable roadmap with dependencies, acceptance criteria, context links, and knowledge updates ready for implementation.
@@ -22,7 +22,7 @@ You are the Research & Discussion Lead for RRCE-Workflow. Your mission: refine i
22
22
 
23
23
  ## Path Resolution
24
24
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
25
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
25
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
26
26
 
27
27
  ## Pipeline Position
28
28
  - **Entry Point**: First agent invoked for new tasks
@@ -83,7 +83,7 @@ Based on knowledge search, create a gap analysis:
83
83
  ### Step 3: Setup Task Structure
84
84
 
85
85
  1. Ensure directory exists: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/research/`
86
- 2. Copy meta template if new task: `{{RRCE_HOME}}/templates/meta.template.json` → `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json`
86
+ 2. Copy meta template if new task: `{{RRCE_DATA}}/templates/meta.template.json` → `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json`
87
87
  3. Populate initial metadata:
88
88
  - `task_id`: Generate UUID
89
89
  - `task_slug`: From argument
@@ -127,7 +127,7 @@ Document the decision in `meta.json.decisions`.
127
127
 
128
128
  ### Step 6: Generate Research Brief
129
129
 
130
- 1. Compile findings using template: `{{RRCE_HOME}}/templates/research_output.md`
130
+ 1. Compile findings using template: `{{RRCE_DATA}}/templates/research_output.md`
131
131
  2. Save to: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/research/{{TASK_SLUG}}-research.md`
132
132
 
133
133
  **Brief includes:**
@@ -188,7 +188,7 @@ Research is complete when:
188
188
  ## Deliverable
189
189
 
190
190
  - **File**: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/research/{{TASK_SLUG}}-research.md`
191
- - **Template**: `{{RRCE_HOME}}/templates/research_output.md`
191
+ - **Template**: `{{RRCE_DATA}}/templates/research_output.md`
192
192
  - **Metadata**: `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` with status `complete`
193
193
  - **Outcome**: Planning agent can proceed without re-asking the same questions
194
194
 
@@ -16,7 +16,7 @@ You are the Knowledge Sync Lead. Act like a senior architect charged with keepin
16
16
 
17
17
  ## Path Resolution
18
18
  Use the pre-resolved paths from the "System Resolved Paths" table in the context preamble.
19
- For details, see: `{{RRCE_HOME}}/docs/path-resolution.md`
19
+ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
20
20
 
21
21
  Pipeline Position
22
22
  - **Maintenance Agent**: Sync runs periodically or after significant codebase changes to keep knowledge current.
package/dist/index.js CHANGED
@@ -1390,7 +1390,7 @@ var init_types = __esm({
1390
1390
  },
1391
1391
  projects: [],
1392
1392
  defaults: {
1393
- includeNew: true,
1393
+ includeNew: false,
1394
1394
  permissions: {
1395
1395
  knowledge: true,
1396
1396
  tasks: true,
@@ -1407,15 +1407,27 @@ var init_types = __esm({
1407
1407
  });
1408
1408
 
1409
1409
  // src/mcp/config-utils.ts
1410
+ import * as path10 from "path";
1411
+ function normalizeProjectPath(projectPath) {
1412
+ if (projectPath.endsWith(".rrce-workflow")) {
1413
+ return path10.dirname(projectPath);
1414
+ }
1415
+ if (projectPath.endsWith(".rrce-workflow/")) {
1416
+ return path10.dirname(projectPath.slice(0, -1));
1417
+ }
1418
+ return projectPath;
1419
+ }
1410
1420
  function findProjectConfig(config, identifier) {
1421
+ const targetPath = identifier.path ? normalizeProjectPath(identifier.path) : void 0;
1411
1422
  return config.projects.find((p) => {
1412
- if (identifier.path && p.path) {
1413
- return p.path === identifier.path;
1423
+ const configPath = p.path ? normalizeProjectPath(p.path) : void 0;
1424
+ if (targetPath && configPath) {
1425
+ return configPath === targetPath;
1414
1426
  }
1415
- if (!identifier.path && !p.path) {
1427
+ if (!targetPath && !configPath) {
1416
1428
  return p.name === identifier.name;
1417
1429
  }
1418
- if (identifier.path && !p.path) {
1430
+ if (targetPath && !configPath) {
1419
1431
  return p.name === identifier.name;
1420
1432
  }
1421
1433
  return false;
@@ -1441,18 +1453,46 @@ __export(config_exports, {
1441
1453
  setProjectConfig: () => setProjectConfig
1442
1454
  });
1443
1455
  import * as fs9 from "fs";
1444
- import * as path10 from "path";
1456
+ import * as path11 from "path";
1445
1457
  import YAML from "yaml";
1458
+ function migrateConfig(config) {
1459
+ let changed = false;
1460
+ config.projects = config.projects.map((p) => {
1461
+ if (p.path) {
1462
+ const normalized = normalizeProjectPath(p.path);
1463
+ if (normalized !== p.path) {
1464
+ changed = true;
1465
+ return { ...p, path: normalized };
1466
+ }
1467
+ }
1468
+ return p;
1469
+ });
1470
+ return config;
1471
+ }
1446
1472
  function getMCPConfigPath() {
1447
1473
  const workspaceRoot = detectWorkspaceRoot();
1448
1474
  const rrceHome = getEffectiveRRCEHome(workspaceRoot);
1449
- return path10.join(rrceHome, "mcp.yaml");
1475
+ return path11.join(rrceHome, "mcp.yaml");
1476
+ }
1477
+ function loadMCPConfig() {
1478
+ const configPath = getMCPConfigPath();
1479
+ if (!fs9.existsSync(configPath)) {
1480
+ return { ...DEFAULT_MCP_CONFIG };
1481
+ }
1482
+ try {
1483
+ const content = fs9.readFileSync(configPath, "utf-8");
1484
+ let config = parseMCPConfig(content);
1485
+ config = migrateConfig(config);
1486
+ return config;
1487
+ } catch {
1488
+ return { ...DEFAULT_MCP_CONFIG };
1489
+ }
1450
1490
  }
1451
1491
  function ensureMCPGlobalPath() {
1452
1492
  const workspaceRoot = detectWorkspaceRoot();
1453
1493
  const rrceHome = getEffectiveRRCEHome(workspaceRoot);
1454
1494
  if (rrceHome.startsWith(".") || rrceHome.includes(".rrce-workflow/")) {
1455
- const configPath = path10.join(workspaceRoot, ".rrce-workflow", "config.yaml");
1495
+ const configPath = path11.join(workspaceRoot, ".rrce-workflow", "config.yaml");
1456
1496
  if (fs9.existsSync(configPath)) {
1457
1497
  const content = fs9.readFileSync(configPath, "utf-8");
1458
1498
  const modeMatch = content.match(/mode:\s*(global|workspace)/);
@@ -1470,21 +1510,9 @@ function ensureMCPGlobalPath() {
1470
1510
  path: rrceHome
1471
1511
  };
1472
1512
  }
1473
- function loadMCPConfig() {
1474
- const configPath = getMCPConfigPath();
1475
- if (!fs9.existsSync(configPath)) {
1476
- return { ...DEFAULT_MCP_CONFIG };
1477
- }
1478
- try {
1479
- const content = fs9.readFileSync(configPath, "utf-8");
1480
- return parseMCPConfig(content);
1481
- } catch {
1482
- return { ...DEFAULT_MCP_CONFIG };
1483
- }
1484
- }
1485
1513
  function saveMCPConfig(config) {
1486
1514
  const configPath = getMCPConfigPath();
1487
- const dir = path10.dirname(configPath);
1515
+ const dir = path11.dirname(configPath);
1488
1516
  if (!fs9.existsSync(dir)) {
1489
1517
  fs9.mkdirSync(dir, { recursive: true });
1490
1518
  }
@@ -1576,7 +1604,7 @@ function getProjectPermissions(config, name, projectPath) {
1576
1604
  }
1577
1605
  function cleanStaleProjects(config) {
1578
1606
  const rrceHome = getEffectiveGlobalPath();
1579
- const globalWorkspacesDir = path10.join(rrceHome, "workspaces");
1607
+ const globalWorkspacesDir = path11.join(rrceHome, "workspaces");
1580
1608
  const validProjects = [];
1581
1609
  const removed = [];
1582
1610
  for (const project of config.projects) {
@@ -1584,7 +1612,7 @@ function cleanStaleProjects(config) {
1584
1612
  if (project.path) {
1585
1613
  exists = fs9.existsSync(project.path);
1586
1614
  } else {
1587
- const globalPath = path10.join(globalWorkspacesDir, project.name);
1615
+ const globalPath = path11.join(globalWorkspacesDir, project.name);
1588
1616
  exists = fs9.existsSync(globalPath);
1589
1617
  }
1590
1618
  if (exists) {
@@ -1609,23 +1637,29 @@ var init_config = __esm({
1609
1637
 
1610
1638
  // src/commands/wizard/setup-actions.ts
1611
1639
  import * as fs10 from "fs";
1612
- import * as path11 from "path";
1640
+ import * as path12 from "path";
1613
1641
  import pc4 from "picocolors";
1614
1642
  import { note as note2 } from "@clack/prompts";
1615
1643
  function createDirectoryStructure(dataPaths) {
1616
1644
  for (const dataPath of dataPaths) {
1617
1645
  ensureDir(dataPath);
1618
- ensureDir(path11.join(dataPath, "knowledge"));
1619
- ensureDir(path11.join(dataPath, "refs"));
1620
- ensureDir(path11.join(dataPath, "tasks"));
1621
- ensureDir(path11.join(dataPath, "templates"));
1646
+ ensureDir(path12.join(dataPath, "knowledge"));
1647
+ ensureDir(path12.join(dataPath, "refs"));
1648
+ ensureDir(path12.join(dataPath, "tasks"));
1649
+ ensureDir(path12.join(dataPath, "templates"));
1622
1650
  }
1623
1651
  }
1624
1652
  function installAgentPrompts(config, workspacePath, dataPaths) {
1625
1653
  const agentCoreDir = getAgentCoreDir();
1626
1654
  syncMetadataToAll(agentCoreDir, dataPaths);
1627
- copyDirToAllStoragePaths(path11.join(agentCoreDir, "templates"), "templates", dataPaths);
1628
- copyDirToAllStoragePaths(path11.join(agentCoreDir, "prompts"), "prompts", dataPaths);
1655
+ copyDirToAllStoragePaths(path12.join(agentCoreDir, "templates"), "templates", dataPaths);
1656
+ copyDirToAllStoragePaths(path12.join(agentCoreDir, "prompts"), "prompts", dataPaths);
1657
+ copyDirToAllStoragePaths(path12.join(agentCoreDir, "docs"), "docs", dataPaths);
1658
+ const rrceHome = config.globalPath || getDefaultRRCEHome2();
1659
+ ensureDir(path12.join(rrceHome, "templates"));
1660
+ ensureDir(path12.join(rrceHome, "docs"));
1661
+ copyDirRecursive(path12.join(agentCoreDir, "templates"), path12.join(rrceHome, "templates"));
1662
+ copyDirRecursive(path12.join(agentCoreDir, "docs"), path12.join(rrceHome, "docs"));
1629
1663
  const needsIDEPrompts = config.storageMode === "workspace" && (config.tools.includes("copilot") || config.tools.includes("antigravity")) || config.tools.includes("opencode");
1630
1664
  if (needsIDEPrompts) {
1631
1665
  const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
@@ -1642,12 +1676,12 @@ function installAgentPrompts(config, workspacePath, dataPaths) {
1642
1676
  }
1643
1677
  }
1644
1678
  if (config.tools.includes("opencode")) {
1645
- const opencodePath = path11.join(workspacePath, ".opencode", "agent");
1679
+ const opencodePath = path12.join(workspacePath, ".opencode", "agent");
1646
1680
  ensureDir(opencodePath);
1647
1681
  for (const prompt of prompts) {
1648
- const baseName = path11.basename(prompt.filePath, ".md");
1682
+ const baseName = path12.basename(prompt.filePath, ".md");
1649
1683
  const content = convertToOpenCodeAgent(prompt);
1650
- fs10.writeFileSync(path11.join(opencodePath, `${baseName}.md`), content);
1684
+ fs10.writeFileSync(path12.join(opencodePath, `${baseName}.md`), content);
1651
1685
  }
1652
1686
  }
1653
1687
  }
@@ -1656,11 +1690,11 @@ function createWorkspaceConfig(config, workspacePath, workspaceName) {
1656
1690
  let configPath;
1657
1691
  if (config.storageMode === "global") {
1658
1692
  const rrceHome = config.globalPath || getDefaultRRCEHome2();
1659
- configPath = path11.join(rrceHome, "workspaces", workspaceName, "config.yaml");
1693
+ configPath = path12.join(rrceHome, "workspaces", workspaceName, "config.yaml");
1660
1694
  } else {
1661
- configPath = path11.join(workspacePath, ".rrce-workflow", "config.yaml");
1695
+ configPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
1662
1696
  }
1663
- ensureDir(path11.dirname(configPath));
1697
+ ensureDir(path12.dirname(configPath));
1664
1698
  let content = `# RRCE-Workflow Configuration
1665
1699
  version: 1
1666
1700
 
@@ -1723,8 +1757,8 @@ You can configure MCP later: ${pc4.cyan("npx rrce-workflow mcp")}`,
1723
1757
  }
1724
1758
  }
1725
1759
  function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
1726
- const globalPath = path11.join(customGlobalPath || getDefaultRRCEHome2(), "workspaces", workspaceName);
1727
- const workspacePath = path11.join(workspaceRoot, ".rrce-workflow");
1760
+ const globalPath = path12.join(customGlobalPath || getDefaultRRCEHome2(), "workspaces", workspaceName);
1761
+ const workspacePath = path12.join(workspaceRoot, ".rrce-workflow");
1728
1762
  switch (mode) {
1729
1763
  case "global":
1730
1764
  return [globalPath];
@@ -1778,9 +1812,9 @@ __export(gitignore_exports, {
1778
1812
  updateGitignore: () => updateGitignore
1779
1813
  });
1780
1814
  import * as fs11 from "fs";
1781
- import * as path12 from "path";
1815
+ import * as path13 from "path";
1782
1816
  function updateGitignore(workspacePath, storageMode, tools) {
1783
- const gitignorePath = path12.join(workspacePath, ".gitignore");
1817
+ const gitignorePath = path13.join(workspacePath, ".gitignore");
1784
1818
  const entries = [];
1785
1819
  if (storageMode === "workspace") {
1786
1820
  entries.push(".rrce-workflow/");
@@ -1820,11 +1854,11 @@ var init_gitignore = __esm({
1820
1854
 
1821
1855
  // src/mcp/logger.ts
1822
1856
  import * as fs12 from "fs";
1823
- import * as path13 from "path";
1857
+ import * as path14 from "path";
1824
1858
  function getLogFilePath() {
1825
1859
  const workspaceRoot = detectWorkspaceRoot();
1826
1860
  const rrceHome = getEffectiveRRCEHome(workspaceRoot);
1827
- return path13.join(rrceHome, "mcp-server.log");
1861
+ return path14.join(rrceHome, "mcp-server.log");
1828
1862
  }
1829
1863
  var Logger, logger;
1830
1864
  var init_logger = __esm({
@@ -1855,7 +1889,7 @@ ${JSON.stringify(data, null, 2)}`;
1855
1889
  }
1856
1890
  logMessage += "\n";
1857
1891
  try {
1858
- const dir = path13.dirname(this.logPath);
1892
+ const dir = path14.dirname(this.logPath);
1859
1893
  if (!fs12.existsSync(dir)) {
1860
1894
  fs12.mkdirSync(dir, { recursive: true });
1861
1895
  }
@@ -1884,7 +1918,7 @@ ${JSON.stringify(data, null, 2)}`;
1884
1918
 
1885
1919
  // src/mcp/services/rag.ts
1886
1920
  import * as fs13 from "fs";
1887
- import * as path14 from "path";
1921
+ import * as path15 from "path";
1888
1922
  var INDEX_VERSION, DEFAULT_MODEL, RAGService;
1889
1923
  var init_rag = __esm({
1890
1924
  "src/mcp/services/rag.ts"() {
@@ -1966,7 +2000,7 @@ var init_rag = __esm({
1966
2000
  saveIndex() {
1967
2001
  if (!this.index) return;
1968
2002
  try {
1969
- const dir = path14.dirname(this.indexPath);
2003
+ const dir = path15.dirname(this.indexPath);
1970
2004
  if (!fs13.existsSync(dir)) {
1971
2005
  fs13.mkdirSync(dir, { recursive: true });
1972
2006
  }
@@ -2132,21 +2166,19 @@ var init_rag = __esm({
2132
2166
 
2133
2167
  // src/mcp/resources.ts
2134
2168
  import * as fs14 from "fs";
2135
- import * as path15 from "path";
2169
+ import * as path16 from "path";
2136
2170
  function getExposedProjects() {
2137
2171
  const config = loadMCPConfig();
2138
2172
  const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
2139
2173
  const allProjects = projectService.scan({ knownPaths });
2140
- const globalProjects = allProjects.filter((project) => isProjectExposed(config, project.name, project.dataPath));
2141
- const activeProject = detectActiveProject(globalProjects);
2142
- let linkedProjects = [];
2174
+ const activeProject = detectActiveProject(allProjects);
2175
+ const potentialProjects = [...allProjects];
2143
2176
  if (activeProject) {
2144
- const localConfigPath = path15.join(activeProject.dataPath, "config.yaml");
2145
2177
  let cfgContent = null;
2146
- if (fs14.existsSync(path15.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
2147
- cfgContent = fs14.readFileSync(path15.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
2148
- } else if (fs14.existsSync(path15.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
2149
- cfgContent = fs14.readFileSync(path15.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
2178
+ if (fs14.existsSync(path16.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
2179
+ cfgContent = fs14.readFileSync(path16.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
2180
+ } else if (fs14.existsSync(path16.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
2181
+ cfgContent = fs14.readFileSync(path16.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
2150
2182
  }
2151
2183
  if (cfgContent) {
2152
2184
  if (cfgContent.includes("linked_projects:")) {
@@ -2166,10 +2198,10 @@ function getExposedProjects() {
2166
2198
  if (inLinked && trimmed.startsWith("-")) {
2167
2199
  const val = trimmed.replace(/^-\s*/, "").trim();
2168
2200
  const [pName] = val.split(":");
2169
- if (!globalProjects.some((p) => p.name === pName) && !linkedProjects.some((p) => p.name === pName)) {
2201
+ if (!potentialProjects.some((p) => p.name === pName)) {
2170
2202
  const found = allProjects.find((p) => p.name === pName);
2171
2203
  if (found) {
2172
- linkedProjects.push(found);
2204
+ potentialProjects.push(found);
2173
2205
  }
2174
2206
  }
2175
2207
  }
@@ -2178,11 +2210,11 @@ function getExposedProjects() {
2178
2210
  }
2179
2211
  }
2180
2212
  }
2181
- return [...globalProjects, ...linkedProjects];
2213
+ return potentialProjects.filter((project) => isProjectExposed(config, project.name, project.path));
2182
2214
  }
2183
2215
  function getRAGIndexPath(project) {
2184
2216
  const scanRoot = project.path || project.dataPath;
2185
- return path15.join(project.knowledgePath || path15.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
2217
+ return path16.join(project.knowledgePath || path16.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
2186
2218
  }
2187
2219
  function detectActiveProject(knownProjects) {
2188
2220
  let scanList = knownProjects;
@@ -2190,25 +2222,25 @@ function detectActiveProject(knownProjects) {
2190
2222
  const config = loadMCPConfig();
2191
2223
  const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
2192
2224
  const all = projectService.scan({ knownPaths });
2193
- scanList = all.filter((project) => isProjectExposed(config, project.name, project.dataPath));
2225
+ scanList = all.filter((project) => isProjectExposed(config, project.name, project.path));
2194
2226
  }
2195
2227
  return findClosestProject(scanList);
2196
2228
  }
2197
2229
  function getProjectContext(projectName) {
2198
2230
  const config = loadMCPConfig();
2199
2231
  const projects = projectService.scan();
2200
- const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.dataPath));
2232
+ const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.path));
2201
2233
  if (!project) {
2202
2234
  return null;
2203
2235
  }
2204
- const permissions = getProjectPermissions(config, projectName, project.dataPath);
2236
+ const permissions = getProjectPermissions(config, projectName, project.path);
2205
2237
  if (!permissions.knowledge) {
2206
2238
  return null;
2207
2239
  }
2208
2240
  if (!project.knowledgePath) {
2209
2241
  return null;
2210
2242
  }
2211
- const contextPath = path15.join(project.knowledgePath, "project-context.md");
2243
+ const contextPath = path16.join(project.knowledgePath, "project-context.md");
2212
2244
  if (!fs14.existsSync(contextPath)) {
2213
2245
  return null;
2214
2246
  }
@@ -2217,11 +2249,11 @@ function getProjectContext(projectName) {
2217
2249
  function getProjectTasks(projectName) {
2218
2250
  const config = loadMCPConfig();
2219
2251
  const projects = projectService.scan();
2220
- const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.dataPath));
2252
+ const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.path));
2221
2253
  if (!project) {
2222
2254
  return [];
2223
2255
  }
2224
- const permissions = getProjectPermissions(config, projectName, project.dataPath);
2256
+ const permissions = getProjectPermissions(config, projectName, project.path);
2225
2257
  if (!permissions.tasks) {
2226
2258
  return [];
2227
2259
  }
@@ -2233,7 +2265,7 @@ function getProjectTasks(projectName) {
2233
2265
  const taskDirs = fs14.readdirSync(project.tasksPath, { withFileTypes: true });
2234
2266
  for (const dir of taskDirs) {
2235
2267
  if (!dir.isDirectory()) continue;
2236
- const metaPath = path15.join(project.tasksPath, dir.name, "meta.json");
2268
+ const metaPath = path16.join(project.tasksPath, dir.name, "meta.json");
2237
2269
  if (fs14.existsSync(metaPath)) {
2238
2270
  try {
2239
2271
  const meta = JSON.parse(fs14.readFileSync(metaPath, "utf-8"));
@@ -2253,21 +2285,21 @@ async function searchKnowledge(query, projectFilter) {
2253
2285
  const queryLower = query.toLowerCase();
2254
2286
  for (const project of projects) {
2255
2287
  if (projectFilter && project.name !== projectFilter) continue;
2256
- const permissions = getProjectPermissions(config, project.name, project.dataPath);
2288
+ const permissions = getProjectPermissions(config, project.name, project.path);
2257
2289
  if (!permissions.knowledge || !project.knowledgePath) continue;
2258
2290
  const projConfig = config.projects.find(
2259
- (p) => p.path && p.path === project.dataPath || !p.path && p.name === project.name
2291
+ (p) => p.path && normalizeProjectPath(p.path) === normalizeProjectPath(project.path) || !p.path && p.name === project.name
2260
2292
  );
2261
2293
  const useRAG = projConfig?.semanticSearch?.enabled;
2262
2294
  if (useRAG) {
2263
2295
  try {
2264
- const indexPath = path15.join(project.knowledgePath, "embeddings.json");
2296
+ const indexPath = path16.join(project.knowledgePath, "embeddings.json");
2265
2297
  const rag = new RAGService(indexPath, projConfig?.semanticSearch?.model);
2266
2298
  const ragResults = await rag.search(query, 5);
2267
2299
  for (const r of ragResults) {
2268
2300
  results.push({
2269
2301
  project: project.name,
2270
- file: path15.relative(project.knowledgePath, r.filePath),
2302
+ file: path16.relative(project.knowledgePath, r.filePath),
2271
2303
  matches: [r.content],
2272
2304
  // The chunk content is the match
2273
2305
  score: r.score
@@ -2281,7 +2313,7 @@ async function searchKnowledge(query, projectFilter) {
2281
2313
  const files = fs14.readdirSync(project.knowledgePath);
2282
2314
  for (const file of files) {
2283
2315
  if (!file.endsWith(".md")) continue;
2284
- const filePath = path15.join(project.knowledgePath, file);
2316
+ const filePath = path16.join(project.knowledgePath, file);
2285
2317
  const content = fs14.readFileSync(filePath, "utf-8");
2286
2318
  const lines = content.split("\n");
2287
2319
  const matches = [];
@@ -2312,7 +2344,7 @@ async function indexKnowledge(projectName, force = false) {
2312
2344
  return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0, filesSkipped: 0 };
2313
2345
  }
2314
2346
  const projConfig = config.projects.find(
2315
- (p) => p.path && p.path === project.dataPath || !p.path && p.name === project.name
2347
+ (p) => p.path && normalizeProjectPath(p.path) === normalizeProjectPath(project.path) || !p.path && p.name === project.name
2316
2348
  ) || (project.source === "global" ? { semanticSearch: { enabled: true, model: "Xenova/all-MiniLM-L6-v2" } } : void 0);
2317
2349
  const isEnabled = projConfig?.semanticSearch?.enabled || project.semanticSearchEnabled;
2318
2350
  if (!isEnabled) {
@@ -2362,7 +2394,7 @@ async function indexKnowledge(projectName, force = false) {
2362
2394
  ];
2363
2395
  const SKIP_DIRS = ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "venv", ".venv", "target", "vendor"];
2364
2396
  try {
2365
- const indexPath = path15.join(project.knowledgePath || path15.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
2397
+ const indexPath = path16.join(project.knowledgePath || path16.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
2366
2398
  const model = projConfig?.semanticSearch?.model || "Xenova/all-MiniLM-L6-v2";
2367
2399
  const rag = new RAGService(indexPath, model);
2368
2400
  let indexed = 0;
@@ -2370,14 +2402,14 @@ async function indexKnowledge(projectName, force = false) {
2370
2402
  const scanDir = async (dir) => {
2371
2403
  const entries = fs14.readdirSync(dir, { withFileTypes: true });
2372
2404
  for (const entry of entries) {
2373
- const fullPath = path15.join(dir, entry.name);
2405
+ const fullPath = path16.join(dir, entry.name);
2374
2406
  if (entry.isDirectory()) {
2375
2407
  if (SKIP_DIRS.includes(entry.name) || entry.name.startsWith(".")) {
2376
2408
  continue;
2377
2409
  }
2378
2410
  await scanDir(fullPath);
2379
2411
  } else if (entry.isFile()) {
2380
- const ext = path15.extname(entry.name).toLowerCase();
2412
+ const ext = path16.extname(entry.name).toLowerCase();
2381
2413
  if (!INDEXABLE_EXTENSIONS.includes(ext)) {
2382
2414
  continue;
2383
2415
  }
@@ -2414,7 +2446,7 @@ function getContextPreamble() {
2414
2446
  const activeProject = detectActiveProject();
2415
2447
  let contextPreamble = "";
2416
2448
  if (activeProject) {
2417
- const rrceHome = process.env.RRCE_HOME || path15.join(__require("os").homedir(), ".rrce-workflow");
2449
+ const rrceHome = process.env.RRCE_HOME || path16.join(__require("os").homedir(), ".rrce-workflow");
2418
2450
  const workspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
2419
2451
  const rrceData = activeProject.dataPath;
2420
2452
  contextPreamble += `
@@ -2431,7 +2463,7 @@ Use these values directly in your operations. Do NOT manually resolve paths.
2431
2463
  `;
2432
2464
  }
2433
2465
  const projectList = projects.map((p) => {
2434
- const isActive = activeProject && p.dataPath === activeProject.dataPath;
2466
+ const isActive = activeProject && normalizeProjectPath(p.path) === normalizeProjectPath(activeProject.path);
2435
2467
  return `- ${p.name} (${p.source}) ${isActive ? "**[ACTIVE]**" : ""}`;
2436
2468
  }).join("\n");
2437
2469
  contextPreamble += `
@@ -2459,6 +2491,7 @@ var init_resources = __esm({
2459
2491
  "src/mcp/resources.ts"() {
2460
2492
  "use strict";
2461
2493
  init_config();
2494
+ init_config_utils();
2462
2495
  init_detection();
2463
2496
  init_detection_service();
2464
2497
  init_rag();
@@ -2549,6 +2582,7 @@ var init_resources2 = __esm({
2549
2582
  });
2550
2583
 
2551
2584
  // src/mcp/prompts.ts
2585
+ import * as path17 from "path";
2552
2586
  function getAllPrompts() {
2553
2587
  const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
2554
2588
  return prompts.map((p) => {
@@ -2585,6 +2619,40 @@ function getPromptDef(name) {
2585
2619
  (p) => p.name === name || p.id === name || p.name.toLowerCase() === search || p.id.toLowerCase() === search
2586
2620
  );
2587
2621
  }
2622
+ function renderPromptWithContext(content, args) {
2623
+ const renderArgs = { ...args };
2624
+ const activeProject = detectActiveProject();
2625
+ const DEFAULT_RRCE_HOME = getEffectiveGlobalPath();
2626
+ let resolvedRrceData = ".rrce-workflow/";
2627
+ let resolvedRrceHome = DEFAULT_RRCE_HOME;
2628
+ let resolvedWorkspaceRoot = process.cwd();
2629
+ let resolvedWorkspaceName = "current-project";
2630
+ if (activeProject) {
2631
+ resolvedRrceData = activeProject.dataPath;
2632
+ if (!resolvedRrceData.endsWith("/") && !resolvedRrceData.endsWith("\\")) {
2633
+ resolvedRrceData += "/";
2634
+ }
2635
+ resolvedWorkspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
2636
+ resolvedWorkspaceName = activeProject.name;
2637
+ if (activeProject.source === "global") {
2638
+ const workspacesDir = path17.dirname(activeProject.dataPath);
2639
+ resolvedRrceHome = path17.dirname(workspacesDir);
2640
+ }
2641
+ }
2642
+ if (!renderArgs["RRCE_DATA"]) renderArgs["RRCE_DATA"] = resolvedRrceData;
2643
+ if (!renderArgs["RRCE_HOME"]) renderArgs["RRCE_HOME"] = resolvedRrceHome;
2644
+ if (!renderArgs["WORKSPACE_ROOT"]) renderArgs["WORKSPACE_ROOT"] = resolvedWorkspaceRoot;
2645
+ if (!renderArgs["WORKSPACE_NAME"]) renderArgs["WORKSPACE_NAME"] = resolvedWorkspaceName;
2646
+ return {
2647
+ rendered: renderPrompt(content, renderArgs),
2648
+ context: {
2649
+ RRCE_DATA: resolvedRrceData,
2650
+ RRCE_HOME: resolvedRrceHome,
2651
+ WORKSPACE_ROOT: resolvedWorkspaceRoot,
2652
+ WORKSPACE_NAME: resolvedWorkspaceName
2653
+ }
2654
+ };
2655
+ }
2588
2656
  function renderPrompt(content, args) {
2589
2657
  let rendered = content;
2590
2658
  for (const [key, val] of Object.entries(args)) {
@@ -2596,6 +2664,8 @@ var init_prompts2 = __esm({
2596
2664
  "src/mcp/prompts.ts"() {
2597
2665
  "use strict";
2598
2666
  init_prompts();
2667
+ init_resources();
2668
+ init_paths();
2599
2669
  }
2600
2670
  });
2601
2671
 
@@ -2737,9 +2807,17 @@ Available projects: ${projects}`;
2737
2807
  for (const [key, val] of Object.entries(renderArgs)) {
2738
2808
  stringArgs[key] = String(val);
2739
2809
  }
2740
- const content = renderPrompt(promptDef.content, stringArgs);
2741
- const contextPreamble = getContextPreamble();
2742
- return { content: [{ type: "text", text: contextPreamble + content }] };
2810
+ const { rendered, context } = renderPromptWithContext(promptDef.content, stringArgs);
2811
+ let contextPreamble = getContextPreamble();
2812
+ contextPreamble += `
2813
+ ### System Resolved Paths (OVERRIDE)
2814
+ The system has pre-resolved the configuration for this project. Use these values instead of manual resolution:
2815
+ - **RRCE_DATA**: \`${context.RRCE_DATA}\` (Stores knowledge, tasks, refs)
2816
+ - **WORKSPACE_ROOT**: \`${context.WORKSPACE_ROOT}\` (Source code location)
2817
+ - **RRCE_HOME**: \`${context.RRCE_HOME}\`
2818
+ - **Current Project**: ${context.WORKSPACE_NAME}
2819
+ `;
2820
+ return { content: [{ type: "text", text: contextPreamble + rendered }] };
2743
2821
  }
2744
2822
  case "help_setup": {
2745
2823
  const msg = `
@@ -2777,7 +2855,6 @@ import {
2777
2855
  ListPromptsRequestSchema,
2778
2856
  GetPromptRequestSchema
2779
2857
  } from "@modelcontextprotocol/sdk/types.js";
2780
- import * as path16 from "path";
2781
2858
  function registerPromptHandlers(server) {
2782
2859
  server.setRequestHandler(ListPromptsRequestSchema, async () => {
2783
2860
  logger.debug("Listing prompts");
@@ -2812,34 +2889,15 @@ function registerPromptHandlers(server) {
2812
2889
  for (const [key, val] of Object.entries(providedArgs)) {
2813
2890
  renderArgs[key] = String(val);
2814
2891
  }
2815
- const activeProject = detectActiveProject();
2816
- const DEFAULT_RRCE_HOME = getEffectiveGlobalPath();
2817
- let resolvedRrceData = ".rrce-workflow/";
2818
- let resolvedRrceHome = DEFAULT_RRCE_HOME;
2819
- let resolvedWorkspaceRoot = process.cwd();
2820
- let resolvedWorkspaceName = "current-project";
2821
- if (activeProject) {
2822
- resolvedRrceData = activeProject.dataPath + "/";
2823
- resolvedWorkspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
2824
- resolvedWorkspaceName = activeProject.name;
2825
- if (activeProject.source === "global") {
2826
- const workspacesDir = path16.dirname(activeProject.dataPath);
2827
- resolvedRrceHome = path16.dirname(workspacesDir);
2828
- }
2829
- }
2830
- if (!renderArgs["RRCE_DATA"]) renderArgs["RRCE_DATA"] = resolvedRrceData;
2831
- if (!renderArgs["RRCE_HOME"]) renderArgs["RRCE_HOME"] = resolvedRrceHome;
2832
- if (!renderArgs["WORKSPACE_ROOT"]) renderArgs["WORKSPACE_ROOT"] = resolvedWorkspaceRoot;
2833
- if (!renderArgs["WORKSPACE_NAME"]) renderArgs["WORKSPACE_NAME"] = resolvedWorkspaceName;
2834
- const content = renderPrompt(promptDef.content, renderArgs);
2892
+ const { rendered, context } = renderPromptWithContext(promptDef.content, renderArgs);
2835
2893
  let contextPreamble = getContextPreamble();
2836
2894
  contextPreamble += `
2837
2895
  ### System Resolved Paths (OVERRIDE)
2838
2896
  The system has pre-resolved the configuration for this project. Use these values instead of manual resolution:
2839
- - **RRCE_DATA**: \`${resolvedRrceData}\` (Stores knowledge, tasks, refs)
2840
- - **WORKSPACE_ROOT**: \`${resolvedWorkspaceRoot}\` (Source code location)
2841
- - **RRCE_HOME**: \`${resolvedRrceHome}\`
2842
- - **Current Project**: ${resolvedWorkspaceName}
2897
+ - **RRCE_DATA**: \`${context.RRCE_DATA}\` (Stores knowledge, tasks, refs)
2898
+ - **WORKSPACE_ROOT**: \`${context.WORKSPACE_ROOT}\` (Source code location)
2899
+ - **RRCE_HOME**: \`${context.RRCE_HOME}\`
2900
+ - **Current Project**: ${context.WORKSPACE_NAME}
2843
2901
  `;
2844
2902
  return {
2845
2903
  messages: [
@@ -2847,7 +2905,7 @@ The system has pre-resolved the configuration for this project. Use these values
2847
2905
  role: "user",
2848
2906
  content: {
2849
2907
  type: "text",
2850
- text: contextPreamble + content
2908
+ text: contextPreamble + rendered
2851
2909
  }
2852
2910
  }
2853
2911
  ]
@@ -3028,7 +3086,7 @@ Hidden projects: ${projects.length - exposedCount}`,
3028
3086
  async function handleConfigureGlobalPath() {
3029
3087
  const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
3030
3088
  const fs21 = await import("fs");
3031
- const path20 = await import("path");
3089
+ const path21 = await import("path");
3032
3090
  note3(
3033
3091
  `MCP Hub requires a ${pc5.bold("global storage path")} to store its configuration
3034
3092
  and coordinate across projects.
@@ -3051,7 +3109,7 @@ locally in each project. MCP needs a central location.`,
3051
3109
  `${pc5.green("\u2713")} Global path configured: ${pc5.cyan(resolvedPath)}
3052
3110
 
3053
3111
  MCP config will be stored at:
3054
- ${path20.join(resolvedPath, "mcp.yaml")}`,
3112
+ ${path21.join(resolvedPath, "mcp.yaml")}`,
3055
3113
  "Configuration Saved"
3056
3114
  );
3057
3115
  return true;
@@ -3293,7 +3351,7 @@ var init_SimpleSelect = __esm({
3293
3351
 
3294
3352
  // src/mcp/ui/ProjectsView.tsx
3295
3353
  import { useState as useState2 } from "react";
3296
- import { Box as Box4, Text as Text4 } from "ink";
3354
+ import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
3297
3355
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
3298
3356
  var ProjectsView;
3299
3357
  var init_ProjectsView = __esm({
@@ -3303,6 +3361,20 @@ var init_ProjectsView = __esm({
3303
3361
  init_config();
3304
3362
  ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange }) => {
3305
3363
  const [config, setConfig] = useState2(initialConfig);
3364
+ useInput2((input) => {
3365
+ if (input === "a") {
3366
+ const newConfig = {
3367
+ ...config,
3368
+ defaults: {
3369
+ ...config.defaults,
3370
+ includeNew: !config.defaults.includeNew
3371
+ }
3372
+ };
3373
+ saveMCPConfig(newConfig);
3374
+ setConfig(newConfig);
3375
+ if (onConfigChange) onConfigChange();
3376
+ }
3377
+ });
3306
3378
  const projectItems = allProjects.map((p) => {
3307
3379
  const projectConfig = config.projects.find(
3308
3380
  (c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
@@ -3310,9 +3382,9 @@ var init_ProjectsView = __esm({
3310
3382
  const isExposed = projectConfig ? projectConfig.expose : config.defaults.includeNew;
3311
3383
  return {
3312
3384
  label: p.name + ` (${p.source})` + (p.path ? ` - ${p.path}` : ""),
3313
- value: p.dataPath,
3314
- // Unique ID
3315
- key: p.dataPath,
3385
+ value: p.path,
3386
+ // Standardized ID: Use root path
3387
+ key: p.path,
3316
3388
  exposed: isExposed
3317
3389
  };
3318
3390
  });
@@ -3321,7 +3393,7 @@ var init_ProjectsView = __esm({
3321
3393
  let newConfig = { ...config };
3322
3394
  projectItems.forEach((item) => {
3323
3395
  const isSelected = selectedIds.includes(item.value);
3324
- const project = allProjects.find((p) => p.dataPath === item.value);
3396
+ const project = allProjects.find((p) => p.path === item.value);
3325
3397
  if (project) {
3326
3398
  const existingConfig = newConfig.projects.find((p) => p.name === project.name);
3327
3399
  const projectPath = project.source === "global" && existingConfig?.path ? existingConfig.path : project.path;
@@ -3339,7 +3411,14 @@ var init_ProjectsView = __esm({
3339
3411
  if (onConfigChange) onConfigChange();
3340
3412
  };
3341
3413
  return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
3342
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: " Exposed Projects " }),
3414
+ /* @__PURE__ */ jsxs3(Box4, { justifyContent: "space-between", children: [
3415
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: " Exposed Projects " }),
3416
+ /* @__PURE__ */ jsxs3(Box4, { children: [
3417
+ /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Auto-expose new: " }),
3418
+ /* @__PURE__ */ jsx4(Text4, { color: config.defaults.includeNew ? "green" : "red", children: config.defaults.includeNew ? "ON" : "OFF" }),
3419
+ /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: " (Press 'a' to toggle)" })
3420
+ ] })
3421
+ ] }),
3343
3422
  /* @__PURE__ */ jsx4(Text4, { color: "dim", children: " Select projects to expose via the MCP server. Use Space to toggle, Enter to save." }),
3344
3423
  /* @__PURE__ */ jsx4(Box4, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx4(
3345
3424
  SimpleSelect,
@@ -3354,7 +3433,7 @@ var init_ProjectsView = __esm({
3354
3433
  onCancel: () => {
3355
3434
  }
3356
3435
  },
3357
- JSON.stringify(initialSelected)
3436
+ JSON.stringify(initialSelected) + config.defaults.includeNew
3358
3437
  ) })
3359
3438
  ] });
3360
3439
  };
@@ -3620,14 +3699,14 @@ var init_IndexingStatus = __esm({
3620
3699
 
3621
3700
  // src/mcp/ui/components/TabBar.tsx
3622
3701
  import "react";
3623
- import { Box as Box10, Text as Text10, useInput as useInput2 } from "ink";
3702
+ import { Box as Box10, Text as Text10, useInput as useInput3 } from "ink";
3624
3703
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3625
3704
  var TabBar;
3626
3705
  var init_TabBar = __esm({
3627
3706
  "src/mcp/ui/components/TabBar.tsx"() {
3628
3707
  "use strict";
3629
3708
  TabBar = ({ tabs, activeTab, onChange }) => {
3630
- useInput2((input, key) => {
3709
+ useInput3((input, key) => {
3631
3710
  if (key.leftArrow) {
3632
3711
  const index = tabs.findIndex((t) => t.id === activeTab);
3633
3712
  if (index !== -1) {
@@ -3674,7 +3753,7 @@ __export(App_exports, {
3674
3753
  App: () => App
3675
3754
  });
3676
3755
  import { useState as useState5, useEffect as useEffect4, useMemo as useMemo2, useCallback } from "react";
3677
- import { Box as Box11, useInput as useInput3, useApp } from "ink";
3756
+ import { Box as Box11, useInput as useInput4, useApp } from "ink";
3678
3757
  import fs15 from "fs";
3679
3758
  import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
3680
3759
  var App;
@@ -3693,6 +3772,7 @@ var init_App = __esm({
3693
3772
  init_detection();
3694
3773
  init_logger();
3695
3774
  init_server();
3775
+ init_resources();
3696
3776
  init_install();
3697
3777
  init_paths();
3698
3778
  App = ({ onExit, initialPort }) => {
@@ -3711,12 +3791,7 @@ var init_App = __esm({
3711
3791
  setProjects(scanForProjects());
3712
3792
  }, []);
3713
3793
  const exposedProjects = useMemo2(
3714
- () => projects.filter((p) => {
3715
- const cfg = config.projects.find(
3716
- (c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
3717
- );
3718
- return cfg?.expose ?? config.defaults.includeNew;
3719
- }),
3794
+ () => projects.filter((p) => isProjectExposed(config, p.name, p.path)),
3720
3795
  [projects, config]
3721
3796
  );
3722
3797
  const isRAGEnabled = useMemo2(() => {
@@ -3788,7 +3863,7 @@ var init_App = __esm({
3788
3863
  }, 500);
3789
3864
  return () => clearInterval(interval);
3790
3865
  }, []);
3791
- useInput3(async (input, key) => {
3866
+ useInput4(async (input, key) => {
3792
3867
  if (input === "q" || key.ctrl && input === "c") {
3793
3868
  stopMCPServer();
3794
3869
  onExit();
@@ -4531,14 +4606,14 @@ var init_link_flow = __esm({
4531
4606
  import { confirm as confirm8, spinner as spinner5, note as note11, outro as outro4, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
4532
4607
  import pc13 from "picocolors";
4533
4608
  import * as fs17 from "fs";
4534
- import * as path17 from "path";
4609
+ import * as path18 from "path";
4535
4610
  async function runSyncToGlobalFlow(workspacePath, workspaceName) {
4536
4611
  const localPath = getLocalWorkspacePath(workspacePath);
4537
4612
  const customGlobalPath = getEffectiveRRCEHome(workspacePath);
4538
- const globalPath = path17.join(customGlobalPath, "workspaces", workspaceName);
4613
+ const globalPath = path18.join(customGlobalPath, "workspaces", workspaceName);
4539
4614
  const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
4540
4615
  const existingDirs = subdirs.filter(
4541
- (dir) => fs17.existsSync(path17.join(localPath, dir))
4616
+ (dir) => fs17.existsSync(path18.join(localPath, dir))
4542
4617
  );
4543
4618
  if (existingDirs.length === 0) {
4544
4619
  outro4(pc13.yellow("No data found in workspace storage to sync."));
@@ -4564,8 +4639,8 @@ Destination: ${pc13.cyan(globalPath)}`,
4564
4639
  try {
4565
4640
  ensureDir(globalPath);
4566
4641
  for (const dir of existingDirs) {
4567
- const srcDir = path17.join(localPath, dir);
4568
- const destDir = path17.join(globalPath, dir);
4642
+ const srcDir = path18.join(localPath, dir);
4643
+ const destDir = path18.join(globalPath, dir);
4569
4644
  ensureDir(destDir);
4570
4645
  copyDirRecursive(srcDir, destDir);
4571
4646
  }
@@ -4598,7 +4673,7 @@ var init_sync_flow = __esm({
4598
4673
  import { confirm as confirm9, spinner as spinner6, note as note12, outro as outro5, cancel as cancel6, isCancel as isCancel11 } from "@clack/prompts";
4599
4674
  import pc14 from "picocolors";
4600
4675
  import * as fs18 from "fs";
4601
- import * as path18 from "path";
4676
+ import * as path19 from "path";
4602
4677
  async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
4603
4678
  const s = spinner6();
4604
4679
  s.start("Checking for updates");
@@ -4628,7 +4703,7 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
4628
4703
  }
4629
4704
  s.start("Updating from package");
4630
4705
  for (const dataPath of dataPaths) {
4631
- copyDirToAllStoragePaths(path18.join(agentCoreDir, "templates"), "templates", [dataPath]);
4706
+ copyDirToAllStoragePaths(path19.join(agentCoreDir, "templates"), "templates", [dataPath]);
4632
4707
  }
4633
4708
  const configFilePath = getConfigPath(workspacePath);
4634
4709
  if (fs18.existsSync(configFilePath)) {
@@ -4661,8 +4736,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
4661
4736
  }
4662
4737
  }
4663
4738
  function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
4664
- const globalPath = path18.join(customGlobalPath, "workspaces", workspaceName);
4665
- const workspacePath = path18.join(workspaceRoot, ".rrce-workflow");
4739
+ const globalPath = path19.join(customGlobalPath, "workspaces", workspaceName);
4740
+ const workspacePath = path19.join(workspaceRoot, ".rrce-workflow");
4666
4741
  switch (mode) {
4667
4742
  case "global":
4668
4743
  return [globalPath];
@@ -4894,9 +4969,9 @@ init_wizard();
4894
4969
  init_prompts();
4895
4970
  import { intro as intro3, select as select6, note as note15, cancel as cancel9, isCancel as isCancel14, outro as outro8 } from "@clack/prompts";
4896
4971
  import pc17 from "picocolors";
4897
- import * as path19 from "path";
4972
+ import * as path20 from "path";
4898
4973
  async function runSelector() {
4899
- const workspaceName = path19.basename(process.cwd());
4974
+ const workspaceName = path20.basename(process.cwd());
4900
4975
  intro3(pc17.cyan(pc17.inverse(` RRCE-Workflow | ${workspaceName} `)));
4901
4976
  const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
4902
4977
  if (prompts.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.71",
3
+ "version": "0.2.73",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",