rrce-workflow 0.2.72 → 0.2.74
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/agent-core/prompts/documentation.md +11 -1
- package/agent-core/prompts/executor.md +11 -1
- package/agent-core/prompts/planning_orchestrator.md +11 -1
- package/agent-core/prompts/research_discussion.md +11 -1
- package/agent-core/prompts/sync.md +11 -1
- package/dist/index.js +186 -122
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: RRCE Documentation
|
|
3
3
|
description: Produce project documentation aligned with the latest delivery.
|
|
4
4
|
argument-hint: "DOC_TYPE=<type> [TASK_SLUG=<slug> | TARGET_PATH=<relative>] [RELEASE_REF=<tag/sha>]"
|
|
5
|
-
tools: ['search_knowledge', 'get_project_context', 'list_projects']
|
|
5
|
+
tools: ['search_knowledge', 'get_project_context', 'list_projects', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
|
|
6
6
|
required-args:
|
|
7
7
|
- name: DOC_TYPE
|
|
8
8
|
prompt: "Enter the documentation type (e.g., api, architecture, runbook, changelog)"
|
|
@@ -40,6 +40,16 @@ Pipeline Position
|
|
|
40
40
|
- **Best After**: Executor phase complete (if documenting a specific task).
|
|
41
41
|
- **Standalone**: Can also run independently to document general knowledge, architecture, or runbooks.
|
|
42
42
|
|
|
43
|
+
## Technical Protocol (STRICT)
|
|
44
|
+
1. **Path Resolution**: Always use the "System Resolved Paths" from the context preamble.
|
|
45
|
+
- Use `{{RRCE_DATA}}` for all RRCE-specific storage.
|
|
46
|
+
- Use `{{WORKSPACE_ROOT}}` for project source code.
|
|
47
|
+
2. **File Writing**: When using the `write` tool:
|
|
48
|
+
- The `content` parameter **MUST be a string**.
|
|
49
|
+
- If writing JSON (like `meta.json`), you **MUST stringify it** first.
|
|
50
|
+
- Example: `write(filePath, JSON.stringify(data, null, 2))`
|
|
51
|
+
3. **Directory Safety**: Use `bash` with `mkdir -p` to ensure parent directories exist before writing files if they might be missing.
|
|
52
|
+
|
|
43
53
|
Prerequisites (RECOMMENDED)
|
|
44
54
|
If a `TASK_SLUG` is provided:
|
|
45
55
|
1. **Execution Complete** (recommended): Check `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` for `agents.executor.status === 'complete'`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: RRCE Executor
|
|
3
3
|
description: Execute the planned tasks to deliver working code and tests.
|
|
4
4
|
argument-hint: "TASK_SLUG=<slug> [BRANCH=<git ref>]"
|
|
5
|
-
tools: ['search_knowledge', 'get_project_context', 'index_knowledge', 'terminalLastCommand']
|
|
5
|
+
tools: ['search_knowledge', 'get_project_context', 'index_knowledge', 'terminalLastCommand', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
|
|
6
6
|
required-args:
|
|
7
7
|
- name: TASK_SLUG
|
|
8
8
|
prompt: "Enter the task slug to execute"
|
|
@@ -24,6 +24,16 @@ Pipeline Position
|
|
|
24
24
|
- **Requires**: Planning phase must be complete before execution can begin.
|
|
25
25
|
- **Next Step**: After execution is complete, optionally hand off to `/docs` (Documentation agent).
|
|
26
26
|
|
|
27
|
+
## Technical Protocol (STRICT)
|
|
28
|
+
1. **Path Resolution**: Always use the "System Resolved Paths" from the context preamble.
|
|
29
|
+
- Use `{{RRCE_DATA}}` for all RRCE-specific storage.
|
|
30
|
+
- Use `{{WORKSPACE_ROOT}}` for project source code.
|
|
31
|
+
2. **File Writing**: When using the `write` tool:
|
|
32
|
+
- The `content` parameter **MUST be a string**.
|
|
33
|
+
- If writing JSON (like `meta.json`), you **MUST stringify it** first.
|
|
34
|
+
- Example: `write(filePath, JSON.stringify(data, null, 2))`
|
|
35
|
+
3. **Directory Safety**: Use `bash` with `mkdir -p` to ensure parent directories exist before writing files if they might be missing.
|
|
36
|
+
|
|
27
37
|
Prerequisites (STRICT)
|
|
28
38
|
Before proceeding, verify ALL of the following:
|
|
29
39
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: RRCE Planning
|
|
3
3
|
description: Transform clarified requirements into an actionable execution plan.
|
|
4
4
|
argument-hint: "TASK_SLUG=<slug>"
|
|
5
|
-
tools: ['search_knowledge', 'get_project_context', 'list_projects']
|
|
5
|
+
tools: ['search_knowledge', 'get_project_context', 'list_projects', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
|
|
6
6
|
required-args:
|
|
7
7
|
- name: TASK_SLUG
|
|
8
8
|
prompt: "Enter the task slug to create a plan for"
|
|
@@ -22,6 +22,16 @@ Pipeline Position
|
|
|
22
22
|
- **Correlation**: Planning works with Init to maintain project context. If planning reveals significant architectural changes, recommend running `/init` to update project context.
|
|
23
23
|
- **Next Step**: After planning is complete, hand off to `/execute` (Executor agent).
|
|
24
24
|
|
|
25
|
+
## Technical Protocol (STRICT)
|
|
26
|
+
1. **Path Resolution**: Always use the "System Resolved Paths" from the context preamble.
|
|
27
|
+
- Use `{{RRCE_DATA}}` for all RRCE-specific storage.
|
|
28
|
+
- Use `{{WORKSPACE_ROOT}}` for project source code.
|
|
29
|
+
2. **File Writing**: When using the `write` tool:
|
|
30
|
+
- The `content` parameter **MUST be a string**.
|
|
31
|
+
- If writing JSON (like `meta.json`), you **MUST stringify it** first.
|
|
32
|
+
- Example: `write(filePath, JSON.stringify(data, null, 2))`
|
|
33
|
+
3. **Directory Safety**: Use `bash` with `mkdir -p` to ensure parent directories exist before writing files if they might be missing.
|
|
34
|
+
|
|
25
35
|
Prerequisites (STRICT)
|
|
26
36
|
Before proceeding, verify ALL of the following:
|
|
27
37
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: RRCE Research
|
|
3
3
|
description: Research and clarify requirements by leveraging existing project knowledge before asking for clarification.
|
|
4
4
|
argument-hint: REQUEST="<user prompt>" [TASK_SLUG=<slug>] [TITLE="<task title>"] [SOURCE=<url>]
|
|
5
|
-
tools: ['search_knowledge', 'get_project_context', 'list_projects']
|
|
5
|
+
tools: ['search_knowledge', 'get_project_context', 'list_projects', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
|
|
6
6
|
required-args:
|
|
7
7
|
- name: TASK_SLUG
|
|
8
8
|
prompt: "Enter a task slug (kebab-case identifier)"
|
|
@@ -30,6 +30,16 @@ For details, see: `{{RRCE_DATA}}/docs/path-resolution.md`
|
|
|
30
30
|
- **Recommendation**: If `project-context.md` doesn't exist, suggest `/init` first for best results
|
|
31
31
|
- **Next Step**: After research is complete, hand off to `/plan TASK_SLUG={{TASK_SLUG}}`
|
|
32
32
|
|
|
33
|
+
## Technical Protocol (STRICT)
|
|
34
|
+
1. **Path Resolution**: Always use the "System Resolved Paths" from the context preamble.
|
|
35
|
+
- Use `{{RRCE_DATA}}` for all RRCE-specific storage.
|
|
36
|
+
- Use `{{WORKSPACE_ROOT}}` for project source code.
|
|
37
|
+
2. **File Writing**: When using the `write` tool:
|
|
38
|
+
- The `content` parameter **MUST be a string**.
|
|
39
|
+
- If writing JSON (like `meta.json`), you **MUST stringify it** first.
|
|
40
|
+
- Example: `write(filePath, JSON.stringify(data, null, 2))`
|
|
41
|
+
3. **Directory Safety**: Use `bash` with `mkdir -p` to ensure parent directories exist before writing files if they might be missing.
|
|
42
|
+
|
|
33
43
|
## Mission
|
|
34
44
|
- Challenge and refine the incoming request until intent, constraints, and success criteria are explicit
|
|
35
45
|
- Leverage existing project knowledge BEFORE asking the user for clarification
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: RRCE Sync
|
|
3
3
|
description: Reconcile project state with the RRCE knowledge base and update semantic index.
|
|
4
4
|
argument-hint: "[SCOPE=<path|module>]"
|
|
5
|
-
tools: ['search_knowledge', 'get_project_context', 'index_knowledge', 'list_projects']
|
|
5
|
+
tools: ['search_knowledge', 'get_project_context', 'index_knowledge', 'list_projects', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
|
|
6
6
|
required-args: []
|
|
7
7
|
optional-args:
|
|
8
8
|
- name: SCOPE
|
|
@@ -23,6 +23,16 @@ Pipeline Position
|
|
|
23
23
|
- **Requires**: Init must have been run at least once (project-context.md must exist).
|
|
24
24
|
- **Triggers Init**: If sync detects major structural changes, recommend running `/init` to update project context.
|
|
25
25
|
|
|
26
|
+
## Technical Protocol (STRICT)
|
|
27
|
+
1. **Path Resolution**: Always use the "System Resolved Paths" from the context preamble.
|
|
28
|
+
- Use `{{RRCE_DATA}}` for all RRCE-specific storage.
|
|
29
|
+
- Use `{{WORKSPACE_ROOT}}` for project source code.
|
|
30
|
+
2. **File Writing**: When using the `write` tool:
|
|
31
|
+
- The `content` parameter **MUST be a string**.
|
|
32
|
+
- If writing JSON (like `meta.json`), you **MUST stringify it** first.
|
|
33
|
+
- Example: `write(filePath, JSON.stringify(data, null, 2))`
|
|
34
|
+
3. **Directory Safety**: Use `bash` with `mkdir -p` to ensure parent directories exist before writing files if they might be missing.
|
|
35
|
+
|
|
26
36
|
Prerequisites (STRICT)
|
|
27
37
|
1. **Project Context Exists**: Check `{{RRCE_DATA}}/knowledge/project-context.md` exists.
|
|
28
38
|
- If missing, **STOP** and prompt user:
|
package/dist/index.js
CHANGED
|
@@ -393,9 +393,17 @@ function parseWorkspaceConfig(configPath) {
|
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
function findClosestProject(projects, cwd = process.cwd()) {
|
|
396
|
-
const matches = projects.
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
const matches = projects.map((p) => {
|
|
397
|
+
let matchPath = "";
|
|
398
|
+
if (cwd.startsWith(p.path)) {
|
|
399
|
+
matchPath = p.path;
|
|
400
|
+
} else if (p.sourcePath && cwd.startsWith(p.sourcePath)) {
|
|
401
|
+
matchPath = p.sourcePath;
|
|
402
|
+
}
|
|
403
|
+
return { project: p, matchPath };
|
|
404
|
+
}).filter((m) => m.matchPath !== "");
|
|
405
|
+
matches.sort((a, b) => b.matchPath.length - a.matchPath.length);
|
|
406
|
+
return matches[0]?.project;
|
|
399
407
|
}
|
|
400
408
|
var SKIP_DIRECTORIES;
|
|
401
409
|
var init_detection = __esm({
|
|
@@ -1253,7 +1261,16 @@ function copyPromptsToDir(prompts, targetDir, extension) {
|
|
|
1253
1261
|
}
|
|
1254
1262
|
function convertToOpenCodeAgent(prompt) {
|
|
1255
1263
|
const { frontmatter, content } = prompt;
|
|
1256
|
-
const tools = {
|
|
1264
|
+
const tools = {
|
|
1265
|
+
// Enable standard host tools by default
|
|
1266
|
+
"read": true,
|
|
1267
|
+
"write": true,
|
|
1268
|
+
"edit": true,
|
|
1269
|
+
"bash": true,
|
|
1270
|
+
"grep": true,
|
|
1271
|
+
"glob": true,
|
|
1272
|
+
"webfetch": true
|
|
1273
|
+
};
|
|
1257
1274
|
if (frontmatter.tools) {
|
|
1258
1275
|
for (const tool of frontmatter.tools) {
|
|
1259
1276
|
tools[`rrce_${tool}`] = true;
|
|
@@ -1262,7 +1279,7 @@ function convertToOpenCodeAgent(prompt) {
|
|
|
1262
1279
|
const opencodeFrontmatter = {
|
|
1263
1280
|
description: frontmatter.description,
|
|
1264
1281
|
mode: "primary",
|
|
1265
|
-
tools
|
|
1282
|
+
tools
|
|
1266
1283
|
};
|
|
1267
1284
|
return `---
|
|
1268
1285
|
${stringify(opencodeFrontmatter)}---
|
|
@@ -1390,7 +1407,7 @@ var init_types = __esm({
|
|
|
1390
1407
|
},
|
|
1391
1408
|
projects: [],
|
|
1392
1409
|
defaults: {
|
|
1393
|
-
includeNew:
|
|
1410
|
+
includeNew: false,
|
|
1394
1411
|
permissions: {
|
|
1395
1412
|
knowledge: true,
|
|
1396
1413
|
tasks: true,
|
|
@@ -1407,15 +1424,27 @@ var init_types = __esm({
|
|
|
1407
1424
|
});
|
|
1408
1425
|
|
|
1409
1426
|
// src/mcp/config-utils.ts
|
|
1427
|
+
import * as path10 from "path";
|
|
1428
|
+
function normalizeProjectPath(projectPath) {
|
|
1429
|
+
if (projectPath.endsWith(".rrce-workflow")) {
|
|
1430
|
+
return path10.dirname(projectPath);
|
|
1431
|
+
}
|
|
1432
|
+
if (projectPath.endsWith(".rrce-workflow/")) {
|
|
1433
|
+
return path10.dirname(projectPath.slice(0, -1));
|
|
1434
|
+
}
|
|
1435
|
+
return projectPath;
|
|
1436
|
+
}
|
|
1410
1437
|
function findProjectConfig(config, identifier) {
|
|
1438
|
+
const targetPath = identifier.path ? normalizeProjectPath(identifier.path) : void 0;
|
|
1411
1439
|
return config.projects.find((p) => {
|
|
1412
|
-
|
|
1413
|
-
|
|
1440
|
+
const configPath = p.path ? normalizeProjectPath(p.path) : void 0;
|
|
1441
|
+
if (targetPath && configPath) {
|
|
1442
|
+
return configPath === targetPath;
|
|
1414
1443
|
}
|
|
1415
|
-
if (!
|
|
1444
|
+
if (!targetPath && !configPath) {
|
|
1416
1445
|
return p.name === identifier.name;
|
|
1417
1446
|
}
|
|
1418
|
-
if (
|
|
1447
|
+
if (targetPath && !configPath) {
|
|
1419
1448
|
return p.name === identifier.name;
|
|
1420
1449
|
}
|
|
1421
1450
|
return false;
|
|
@@ -1441,18 +1470,46 @@ __export(config_exports, {
|
|
|
1441
1470
|
setProjectConfig: () => setProjectConfig
|
|
1442
1471
|
});
|
|
1443
1472
|
import * as fs9 from "fs";
|
|
1444
|
-
import * as
|
|
1473
|
+
import * as path11 from "path";
|
|
1445
1474
|
import YAML from "yaml";
|
|
1475
|
+
function migrateConfig(config) {
|
|
1476
|
+
let changed = false;
|
|
1477
|
+
config.projects = config.projects.map((p) => {
|
|
1478
|
+
if (p.path) {
|
|
1479
|
+
const normalized = normalizeProjectPath(p.path);
|
|
1480
|
+
if (normalized !== p.path) {
|
|
1481
|
+
changed = true;
|
|
1482
|
+
return { ...p, path: normalized };
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
return p;
|
|
1486
|
+
});
|
|
1487
|
+
return config;
|
|
1488
|
+
}
|
|
1446
1489
|
function getMCPConfigPath() {
|
|
1447
1490
|
const workspaceRoot = detectWorkspaceRoot();
|
|
1448
1491
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
1449
|
-
return
|
|
1492
|
+
return path11.join(rrceHome, "mcp.yaml");
|
|
1493
|
+
}
|
|
1494
|
+
function loadMCPConfig() {
|
|
1495
|
+
const configPath = getMCPConfigPath();
|
|
1496
|
+
if (!fs9.existsSync(configPath)) {
|
|
1497
|
+
return { ...DEFAULT_MCP_CONFIG };
|
|
1498
|
+
}
|
|
1499
|
+
try {
|
|
1500
|
+
const content = fs9.readFileSync(configPath, "utf-8");
|
|
1501
|
+
let config = parseMCPConfig(content);
|
|
1502
|
+
config = migrateConfig(config);
|
|
1503
|
+
return config;
|
|
1504
|
+
} catch {
|
|
1505
|
+
return { ...DEFAULT_MCP_CONFIG };
|
|
1506
|
+
}
|
|
1450
1507
|
}
|
|
1451
1508
|
function ensureMCPGlobalPath() {
|
|
1452
1509
|
const workspaceRoot = detectWorkspaceRoot();
|
|
1453
1510
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
1454
1511
|
if (rrceHome.startsWith(".") || rrceHome.includes(".rrce-workflow/")) {
|
|
1455
|
-
const configPath =
|
|
1512
|
+
const configPath = path11.join(workspaceRoot, ".rrce-workflow", "config.yaml");
|
|
1456
1513
|
if (fs9.existsSync(configPath)) {
|
|
1457
1514
|
const content = fs9.readFileSync(configPath, "utf-8");
|
|
1458
1515
|
const modeMatch = content.match(/mode:\s*(global|workspace)/);
|
|
@@ -1470,21 +1527,9 @@ function ensureMCPGlobalPath() {
|
|
|
1470
1527
|
path: rrceHome
|
|
1471
1528
|
};
|
|
1472
1529
|
}
|
|
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
1530
|
function saveMCPConfig(config) {
|
|
1486
1531
|
const configPath = getMCPConfigPath();
|
|
1487
|
-
const dir =
|
|
1532
|
+
const dir = path11.dirname(configPath);
|
|
1488
1533
|
if (!fs9.existsSync(dir)) {
|
|
1489
1534
|
fs9.mkdirSync(dir, { recursive: true });
|
|
1490
1535
|
}
|
|
@@ -1576,7 +1621,7 @@ function getProjectPermissions(config, name, projectPath) {
|
|
|
1576
1621
|
}
|
|
1577
1622
|
function cleanStaleProjects(config) {
|
|
1578
1623
|
const rrceHome = getEffectiveGlobalPath();
|
|
1579
|
-
const globalWorkspacesDir =
|
|
1624
|
+
const globalWorkspacesDir = path11.join(rrceHome, "workspaces");
|
|
1580
1625
|
const validProjects = [];
|
|
1581
1626
|
const removed = [];
|
|
1582
1627
|
for (const project of config.projects) {
|
|
@@ -1584,7 +1629,7 @@ function cleanStaleProjects(config) {
|
|
|
1584
1629
|
if (project.path) {
|
|
1585
1630
|
exists = fs9.existsSync(project.path);
|
|
1586
1631
|
} else {
|
|
1587
|
-
const globalPath =
|
|
1632
|
+
const globalPath = path11.join(globalWorkspacesDir, project.name);
|
|
1588
1633
|
exists = fs9.existsSync(globalPath);
|
|
1589
1634
|
}
|
|
1590
1635
|
if (exists) {
|
|
@@ -1609,29 +1654,29 @@ var init_config = __esm({
|
|
|
1609
1654
|
|
|
1610
1655
|
// src/commands/wizard/setup-actions.ts
|
|
1611
1656
|
import * as fs10 from "fs";
|
|
1612
|
-
import * as
|
|
1657
|
+
import * as path12 from "path";
|
|
1613
1658
|
import pc4 from "picocolors";
|
|
1614
1659
|
import { note as note2 } from "@clack/prompts";
|
|
1615
1660
|
function createDirectoryStructure(dataPaths) {
|
|
1616
1661
|
for (const dataPath of dataPaths) {
|
|
1617
1662
|
ensureDir(dataPath);
|
|
1618
|
-
ensureDir(
|
|
1619
|
-
ensureDir(
|
|
1620
|
-
ensureDir(
|
|
1621
|
-
ensureDir(
|
|
1663
|
+
ensureDir(path12.join(dataPath, "knowledge"));
|
|
1664
|
+
ensureDir(path12.join(dataPath, "refs"));
|
|
1665
|
+
ensureDir(path12.join(dataPath, "tasks"));
|
|
1666
|
+
ensureDir(path12.join(dataPath, "templates"));
|
|
1622
1667
|
}
|
|
1623
1668
|
}
|
|
1624
1669
|
function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
1625
1670
|
const agentCoreDir = getAgentCoreDir();
|
|
1626
1671
|
syncMetadataToAll(agentCoreDir, dataPaths);
|
|
1627
|
-
copyDirToAllStoragePaths(
|
|
1628
|
-
copyDirToAllStoragePaths(
|
|
1629
|
-
copyDirToAllStoragePaths(
|
|
1672
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "templates"), "templates", dataPaths);
|
|
1673
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "prompts"), "prompts", dataPaths);
|
|
1674
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "docs"), "docs", dataPaths);
|
|
1630
1675
|
const rrceHome = config.globalPath || getDefaultRRCEHome2();
|
|
1631
|
-
ensureDir(
|
|
1632
|
-
ensureDir(
|
|
1633
|
-
copyDirRecursive(
|
|
1634
|
-
copyDirRecursive(
|
|
1676
|
+
ensureDir(path12.join(rrceHome, "templates"));
|
|
1677
|
+
ensureDir(path12.join(rrceHome, "docs"));
|
|
1678
|
+
copyDirRecursive(path12.join(agentCoreDir, "templates"), path12.join(rrceHome, "templates"));
|
|
1679
|
+
copyDirRecursive(path12.join(agentCoreDir, "docs"), path12.join(rrceHome, "docs"));
|
|
1635
1680
|
const needsIDEPrompts = config.storageMode === "workspace" && (config.tools.includes("copilot") || config.tools.includes("antigravity")) || config.tools.includes("opencode");
|
|
1636
1681
|
if (needsIDEPrompts) {
|
|
1637
1682
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
@@ -1648,12 +1693,15 @@ function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
|
1648
1693
|
}
|
|
1649
1694
|
}
|
|
1650
1695
|
if (config.tools.includes("opencode")) {
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
const
|
|
1656
|
-
|
|
1696
|
+
const primaryDataPath = dataPaths[0];
|
|
1697
|
+
if (primaryDataPath) {
|
|
1698
|
+
const opencodePath = path12.join(primaryDataPath, ".opencode", "agent");
|
|
1699
|
+
ensureDir(opencodePath);
|
|
1700
|
+
for (const prompt of prompts) {
|
|
1701
|
+
const baseName = path12.basename(prompt.filePath, ".md");
|
|
1702
|
+
const content = convertToOpenCodeAgent(prompt);
|
|
1703
|
+
fs10.writeFileSync(path12.join(opencodePath, `${baseName}.md`), content);
|
|
1704
|
+
}
|
|
1657
1705
|
}
|
|
1658
1706
|
}
|
|
1659
1707
|
}
|
|
@@ -1662,11 +1710,11 @@ function createWorkspaceConfig(config, workspacePath, workspaceName) {
|
|
|
1662
1710
|
let configPath;
|
|
1663
1711
|
if (config.storageMode === "global") {
|
|
1664
1712
|
const rrceHome = config.globalPath || getDefaultRRCEHome2();
|
|
1665
|
-
configPath =
|
|
1713
|
+
configPath = path12.join(rrceHome, "workspaces", workspaceName, "config.yaml");
|
|
1666
1714
|
} else {
|
|
1667
|
-
configPath =
|
|
1715
|
+
configPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
1668
1716
|
}
|
|
1669
|
-
ensureDir(
|
|
1717
|
+
ensureDir(path12.dirname(configPath));
|
|
1670
1718
|
let content = `# RRCE-Workflow Configuration
|
|
1671
1719
|
version: 1
|
|
1672
1720
|
|
|
@@ -1729,8 +1777,8 @@ You can configure MCP later: ${pc4.cyan("npx rrce-workflow mcp")}`,
|
|
|
1729
1777
|
}
|
|
1730
1778
|
}
|
|
1731
1779
|
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
1732
|
-
const globalPath =
|
|
1733
|
-
const workspacePath =
|
|
1780
|
+
const globalPath = path12.join(customGlobalPath || getDefaultRRCEHome2(), "workspaces", workspaceName);
|
|
1781
|
+
const workspacePath = path12.join(workspaceRoot, ".rrce-workflow");
|
|
1734
1782
|
switch (mode) {
|
|
1735
1783
|
case "global":
|
|
1736
1784
|
return [globalPath];
|
|
@@ -1784,9 +1832,9 @@ __export(gitignore_exports, {
|
|
|
1784
1832
|
updateGitignore: () => updateGitignore
|
|
1785
1833
|
});
|
|
1786
1834
|
import * as fs11 from "fs";
|
|
1787
|
-
import * as
|
|
1835
|
+
import * as path13 from "path";
|
|
1788
1836
|
function updateGitignore(workspacePath, storageMode, tools) {
|
|
1789
|
-
const gitignorePath =
|
|
1837
|
+
const gitignorePath = path13.join(workspacePath, ".gitignore");
|
|
1790
1838
|
const entries = [];
|
|
1791
1839
|
if (storageMode === "workspace") {
|
|
1792
1840
|
entries.push(".rrce-workflow/");
|
|
@@ -1826,11 +1874,11 @@ var init_gitignore = __esm({
|
|
|
1826
1874
|
|
|
1827
1875
|
// src/mcp/logger.ts
|
|
1828
1876
|
import * as fs12 from "fs";
|
|
1829
|
-
import * as
|
|
1877
|
+
import * as path14 from "path";
|
|
1830
1878
|
function getLogFilePath() {
|
|
1831
1879
|
const workspaceRoot = detectWorkspaceRoot();
|
|
1832
1880
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
1833
|
-
return
|
|
1881
|
+
return path14.join(rrceHome, "mcp-server.log");
|
|
1834
1882
|
}
|
|
1835
1883
|
var Logger, logger;
|
|
1836
1884
|
var init_logger = __esm({
|
|
@@ -1861,7 +1909,7 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1861
1909
|
}
|
|
1862
1910
|
logMessage += "\n";
|
|
1863
1911
|
try {
|
|
1864
|
-
const dir =
|
|
1912
|
+
const dir = path14.dirname(this.logPath);
|
|
1865
1913
|
if (!fs12.existsSync(dir)) {
|
|
1866
1914
|
fs12.mkdirSync(dir, { recursive: true });
|
|
1867
1915
|
}
|
|
@@ -1890,7 +1938,7 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1890
1938
|
|
|
1891
1939
|
// src/mcp/services/rag.ts
|
|
1892
1940
|
import * as fs13 from "fs";
|
|
1893
|
-
import * as
|
|
1941
|
+
import * as path15 from "path";
|
|
1894
1942
|
var INDEX_VERSION, DEFAULT_MODEL, RAGService;
|
|
1895
1943
|
var init_rag = __esm({
|
|
1896
1944
|
"src/mcp/services/rag.ts"() {
|
|
@@ -1972,7 +2020,7 @@ var init_rag = __esm({
|
|
|
1972
2020
|
saveIndex() {
|
|
1973
2021
|
if (!this.index) return;
|
|
1974
2022
|
try {
|
|
1975
|
-
const dir =
|
|
2023
|
+
const dir = path15.dirname(this.indexPath);
|
|
1976
2024
|
if (!fs13.existsSync(dir)) {
|
|
1977
2025
|
fs13.mkdirSync(dir, { recursive: true });
|
|
1978
2026
|
}
|
|
@@ -2138,21 +2186,19 @@ var init_rag = __esm({
|
|
|
2138
2186
|
|
|
2139
2187
|
// src/mcp/resources.ts
|
|
2140
2188
|
import * as fs14 from "fs";
|
|
2141
|
-
import * as
|
|
2189
|
+
import * as path16 from "path";
|
|
2142
2190
|
function getExposedProjects() {
|
|
2143
2191
|
const config = loadMCPConfig();
|
|
2144
2192
|
const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
|
|
2145
2193
|
const allProjects = projectService.scan({ knownPaths });
|
|
2146
|
-
const
|
|
2147
|
-
const
|
|
2148
|
-
let linkedProjects = [];
|
|
2194
|
+
const activeProject = detectActiveProject(allProjects);
|
|
2195
|
+
const potentialProjects = [...allProjects];
|
|
2149
2196
|
if (activeProject) {
|
|
2150
|
-
const localConfigPath = path15.join(activeProject.dataPath, "config.yaml");
|
|
2151
2197
|
let cfgContent = null;
|
|
2152
|
-
if (fs14.existsSync(
|
|
2153
|
-
cfgContent = fs14.readFileSync(
|
|
2154
|
-
} else if (fs14.existsSync(
|
|
2155
|
-
cfgContent = fs14.readFileSync(
|
|
2198
|
+
if (fs14.existsSync(path16.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
|
|
2199
|
+
cfgContent = fs14.readFileSync(path16.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
|
|
2200
|
+
} else if (fs14.existsSync(path16.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
|
|
2201
|
+
cfgContent = fs14.readFileSync(path16.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
|
|
2156
2202
|
}
|
|
2157
2203
|
if (cfgContent) {
|
|
2158
2204
|
if (cfgContent.includes("linked_projects:")) {
|
|
@@ -2172,10 +2218,10 @@ function getExposedProjects() {
|
|
|
2172
2218
|
if (inLinked && trimmed.startsWith("-")) {
|
|
2173
2219
|
const val = trimmed.replace(/^-\s*/, "").trim();
|
|
2174
2220
|
const [pName] = val.split(":");
|
|
2175
|
-
if (!
|
|
2221
|
+
if (!potentialProjects.some((p) => p.name === pName)) {
|
|
2176
2222
|
const found = allProjects.find((p) => p.name === pName);
|
|
2177
2223
|
if (found) {
|
|
2178
|
-
|
|
2224
|
+
potentialProjects.push(found);
|
|
2179
2225
|
}
|
|
2180
2226
|
}
|
|
2181
2227
|
}
|
|
@@ -2184,11 +2230,11 @@ function getExposedProjects() {
|
|
|
2184
2230
|
}
|
|
2185
2231
|
}
|
|
2186
2232
|
}
|
|
2187
|
-
return
|
|
2233
|
+
return potentialProjects.filter((project) => isProjectExposed(config, project.name, project.path));
|
|
2188
2234
|
}
|
|
2189
2235
|
function getRAGIndexPath(project) {
|
|
2190
2236
|
const scanRoot = project.path || project.dataPath;
|
|
2191
|
-
return
|
|
2237
|
+
return path16.join(project.knowledgePath || path16.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
|
|
2192
2238
|
}
|
|
2193
2239
|
function detectActiveProject(knownProjects) {
|
|
2194
2240
|
let scanList = knownProjects;
|
|
@@ -2196,25 +2242,25 @@ function detectActiveProject(knownProjects) {
|
|
|
2196
2242
|
const config = loadMCPConfig();
|
|
2197
2243
|
const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
|
|
2198
2244
|
const all = projectService.scan({ knownPaths });
|
|
2199
|
-
scanList = all.filter((project) => isProjectExposed(config, project.name, project.
|
|
2245
|
+
scanList = all.filter((project) => isProjectExposed(config, project.name, project.path));
|
|
2200
2246
|
}
|
|
2201
2247
|
return findClosestProject(scanList);
|
|
2202
2248
|
}
|
|
2203
2249
|
function getProjectContext(projectName) {
|
|
2204
2250
|
const config = loadMCPConfig();
|
|
2205
2251
|
const projects = projectService.scan();
|
|
2206
|
-
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.
|
|
2252
|
+
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.path));
|
|
2207
2253
|
if (!project) {
|
|
2208
2254
|
return null;
|
|
2209
2255
|
}
|
|
2210
|
-
const permissions = getProjectPermissions(config, projectName, project.
|
|
2256
|
+
const permissions = getProjectPermissions(config, projectName, project.path);
|
|
2211
2257
|
if (!permissions.knowledge) {
|
|
2212
2258
|
return null;
|
|
2213
2259
|
}
|
|
2214
2260
|
if (!project.knowledgePath) {
|
|
2215
2261
|
return null;
|
|
2216
2262
|
}
|
|
2217
|
-
const contextPath =
|
|
2263
|
+
const contextPath = path16.join(project.knowledgePath, "project-context.md");
|
|
2218
2264
|
if (!fs14.existsSync(contextPath)) {
|
|
2219
2265
|
return null;
|
|
2220
2266
|
}
|
|
@@ -2223,11 +2269,11 @@ function getProjectContext(projectName) {
|
|
|
2223
2269
|
function getProjectTasks(projectName) {
|
|
2224
2270
|
const config = loadMCPConfig();
|
|
2225
2271
|
const projects = projectService.scan();
|
|
2226
|
-
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.
|
|
2272
|
+
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.path));
|
|
2227
2273
|
if (!project) {
|
|
2228
2274
|
return [];
|
|
2229
2275
|
}
|
|
2230
|
-
const permissions = getProjectPermissions(config, projectName, project.
|
|
2276
|
+
const permissions = getProjectPermissions(config, projectName, project.path);
|
|
2231
2277
|
if (!permissions.tasks) {
|
|
2232
2278
|
return [];
|
|
2233
2279
|
}
|
|
@@ -2239,7 +2285,7 @@ function getProjectTasks(projectName) {
|
|
|
2239
2285
|
const taskDirs = fs14.readdirSync(project.tasksPath, { withFileTypes: true });
|
|
2240
2286
|
for (const dir of taskDirs) {
|
|
2241
2287
|
if (!dir.isDirectory()) continue;
|
|
2242
|
-
const metaPath =
|
|
2288
|
+
const metaPath = path16.join(project.tasksPath, dir.name, "meta.json");
|
|
2243
2289
|
if (fs14.existsSync(metaPath)) {
|
|
2244
2290
|
try {
|
|
2245
2291
|
const meta = JSON.parse(fs14.readFileSync(metaPath, "utf-8"));
|
|
@@ -2259,21 +2305,21 @@ async function searchKnowledge(query, projectFilter) {
|
|
|
2259
2305
|
const queryLower = query.toLowerCase();
|
|
2260
2306
|
for (const project of projects) {
|
|
2261
2307
|
if (projectFilter && project.name !== projectFilter) continue;
|
|
2262
|
-
const permissions = getProjectPermissions(config, project.name, project.
|
|
2308
|
+
const permissions = getProjectPermissions(config, project.name, project.path);
|
|
2263
2309
|
if (!permissions.knowledge || !project.knowledgePath) continue;
|
|
2264
2310
|
const projConfig = config.projects.find(
|
|
2265
|
-
(p) => p.path && p.path === project.
|
|
2311
|
+
(p) => p.path && normalizeProjectPath(p.path) === normalizeProjectPath(project.path) || !p.path && p.name === project.name
|
|
2266
2312
|
);
|
|
2267
2313
|
const useRAG = projConfig?.semanticSearch?.enabled;
|
|
2268
2314
|
if (useRAG) {
|
|
2269
2315
|
try {
|
|
2270
|
-
const indexPath =
|
|
2316
|
+
const indexPath = path16.join(project.knowledgePath, "embeddings.json");
|
|
2271
2317
|
const rag = new RAGService(indexPath, projConfig?.semanticSearch?.model);
|
|
2272
2318
|
const ragResults = await rag.search(query, 5);
|
|
2273
2319
|
for (const r of ragResults) {
|
|
2274
2320
|
results.push({
|
|
2275
2321
|
project: project.name,
|
|
2276
|
-
file:
|
|
2322
|
+
file: path16.relative(project.knowledgePath, r.filePath),
|
|
2277
2323
|
matches: [r.content],
|
|
2278
2324
|
// The chunk content is the match
|
|
2279
2325
|
score: r.score
|
|
@@ -2287,7 +2333,7 @@ async function searchKnowledge(query, projectFilter) {
|
|
|
2287
2333
|
const files = fs14.readdirSync(project.knowledgePath);
|
|
2288
2334
|
for (const file of files) {
|
|
2289
2335
|
if (!file.endsWith(".md")) continue;
|
|
2290
|
-
const filePath =
|
|
2336
|
+
const filePath = path16.join(project.knowledgePath, file);
|
|
2291
2337
|
const content = fs14.readFileSync(filePath, "utf-8");
|
|
2292
2338
|
const lines = content.split("\n");
|
|
2293
2339
|
const matches = [];
|
|
@@ -2318,7 +2364,7 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
2318
2364
|
return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0, filesSkipped: 0 };
|
|
2319
2365
|
}
|
|
2320
2366
|
const projConfig = config.projects.find(
|
|
2321
|
-
(p) => p.path && p.path === project.
|
|
2367
|
+
(p) => p.path && normalizeProjectPath(p.path) === normalizeProjectPath(project.path) || !p.path && p.name === project.name
|
|
2322
2368
|
) || (project.source === "global" ? { semanticSearch: { enabled: true, model: "Xenova/all-MiniLM-L6-v2" } } : void 0);
|
|
2323
2369
|
const isEnabled = projConfig?.semanticSearch?.enabled || project.semanticSearchEnabled;
|
|
2324
2370
|
if (!isEnabled) {
|
|
@@ -2368,7 +2414,7 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
2368
2414
|
];
|
|
2369
2415
|
const SKIP_DIRS = ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "venv", ".venv", "target", "vendor"];
|
|
2370
2416
|
try {
|
|
2371
|
-
const indexPath =
|
|
2417
|
+
const indexPath = path16.join(project.knowledgePath || path16.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
|
|
2372
2418
|
const model = projConfig?.semanticSearch?.model || "Xenova/all-MiniLM-L6-v2";
|
|
2373
2419
|
const rag = new RAGService(indexPath, model);
|
|
2374
2420
|
let indexed = 0;
|
|
@@ -2376,14 +2422,14 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
2376
2422
|
const scanDir = async (dir) => {
|
|
2377
2423
|
const entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
2378
2424
|
for (const entry of entries) {
|
|
2379
|
-
const fullPath =
|
|
2425
|
+
const fullPath = path16.join(dir, entry.name);
|
|
2380
2426
|
if (entry.isDirectory()) {
|
|
2381
2427
|
if (SKIP_DIRS.includes(entry.name) || entry.name.startsWith(".")) {
|
|
2382
2428
|
continue;
|
|
2383
2429
|
}
|
|
2384
2430
|
await scanDir(fullPath);
|
|
2385
2431
|
} else if (entry.isFile()) {
|
|
2386
|
-
const ext =
|
|
2432
|
+
const ext = path16.extname(entry.name).toLowerCase();
|
|
2387
2433
|
if (!INDEXABLE_EXTENSIONS.includes(ext)) {
|
|
2388
2434
|
continue;
|
|
2389
2435
|
}
|
|
@@ -2420,7 +2466,7 @@ function getContextPreamble() {
|
|
|
2420
2466
|
const activeProject = detectActiveProject();
|
|
2421
2467
|
let contextPreamble = "";
|
|
2422
2468
|
if (activeProject) {
|
|
2423
|
-
const rrceHome = process.env.RRCE_HOME ||
|
|
2469
|
+
const rrceHome = process.env.RRCE_HOME || path16.join(__require("os").homedir(), ".rrce-workflow");
|
|
2424
2470
|
const workspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
|
|
2425
2471
|
const rrceData = activeProject.dataPath;
|
|
2426
2472
|
contextPreamble += `
|
|
@@ -2437,7 +2483,7 @@ Use these values directly in your operations. Do NOT manually resolve paths.
|
|
|
2437
2483
|
`;
|
|
2438
2484
|
}
|
|
2439
2485
|
const projectList = projects.map((p) => {
|
|
2440
|
-
const isActive = activeProject && p.
|
|
2486
|
+
const isActive = activeProject && normalizeProjectPath(p.path) === normalizeProjectPath(activeProject.path);
|
|
2441
2487
|
return `- ${p.name} (${p.source}) ${isActive ? "**[ACTIVE]**" : ""}`;
|
|
2442
2488
|
}).join("\n");
|
|
2443
2489
|
contextPreamble += `
|
|
@@ -2465,6 +2511,7 @@ var init_resources = __esm({
|
|
|
2465
2511
|
"src/mcp/resources.ts"() {
|
|
2466
2512
|
"use strict";
|
|
2467
2513
|
init_config();
|
|
2514
|
+
init_config_utils();
|
|
2468
2515
|
init_detection();
|
|
2469
2516
|
init_detection_service();
|
|
2470
2517
|
init_rag();
|
|
@@ -2555,7 +2602,7 @@ var init_resources2 = __esm({
|
|
|
2555
2602
|
});
|
|
2556
2603
|
|
|
2557
2604
|
// src/mcp/prompts.ts
|
|
2558
|
-
import * as
|
|
2605
|
+
import * as path17 from "path";
|
|
2559
2606
|
function getAllPrompts() {
|
|
2560
2607
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
2561
2608
|
return prompts.map((p) => {
|
|
@@ -2608,8 +2655,8 @@ function renderPromptWithContext(content, args) {
|
|
|
2608
2655
|
resolvedWorkspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
|
|
2609
2656
|
resolvedWorkspaceName = activeProject.name;
|
|
2610
2657
|
if (activeProject.source === "global") {
|
|
2611
|
-
const workspacesDir =
|
|
2612
|
-
resolvedRrceHome =
|
|
2658
|
+
const workspacesDir = path17.dirname(activeProject.dataPath);
|
|
2659
|
+
resolvedRrceHome = path17.dirname(workspacesDir);
|
|
2613
2660
|
}
|
|
2614
2661
|
}
|
|
2615
2662
|
if (!renderArgs["RRCE_DATA"]) renderArgs["RRCE_DATA"] = resolvedRrceData;
|
|
@@ -3059,7 +3106,7 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
3059
3106
|
async function handleConfigureGlobalPath() {
|
|
3060
3107
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
3061
3108
|
const fs21 = await import("fs");
|
|
3062
|
-
const
|
|
3109
|
+
const path21 = await import("path");
|
|
3063
3110
|
note3(
|
|
3064
3111
|
`MCP Hub requires a ${pc5.bold("global storage path")} to store its configuration
|
|
3065
3112
|
and coordinate across projects.
|
|
@@ -3082,7 +3129,7 @@ locally in each project. MCP needs a central location.`,
|
|
|
3082
3129
|
`${pc5.green("\u2713")} Global path configured: ${pc5.cyan(resolvedPath)}
|
|
3083
3130
|
|
|
3084
3131
|
MCP config will be stored at:
|
|
3085
|
-
${
|
|
3132
|
+
${path21.join(resolvedPath, "mcp.yaml")}`,
|
|
3086
3133
|
"Configuration Saved"
|
|
3087
3134
|
);
|
|
3088
3135
|
return true;
|
|
@@ -3324,7 +3371,7 @@ var init_SimpleSelect = __esm({
|
|
|
3324
3371
|
|
|
3325
3372
|
// src/mcp/ui/ProjectsView.tsx
|
|
3326
3373
|
import { useState as useState2 } from "react";
|
|
3327
|
-
import { Box as Box4, Text as Text4 } from "ink";
|
|
3374
|
+
import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
|
|
3328
3375
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3329
3376
|
var ProjectsView;
|
|
3330
3377
|
var init_ProjectsView = __esm({
|
|
@@ -3334,6 +3381,20 @@ var init_ProjectsView = __esm({
|
|
|
3334
3381
|
init_config();
|
|
3335
3382
|
ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange }) => {
|
|
3336
3383
|
const [config, setConfig] = useState2(initialConfig);
|
|
3384
|
+
useInput2((input) => {
|
|
3385
|
+
if (input === "a") {
|
|
3386
|
+
const newConfig = {
|
|
3387
|
+
...config,
|
|
3388
|
+
defaults: {
|
|
3389
|
+
...config.defaults,
|
|
3390
|
+
includeNew: !config.defaults.includeNew
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
saveMCPConfig(newConfig);
|
|
3394
|
+
setConfig(newConfig);
|
|
3395
|
+
if (onConfigChange) onConfigChange();
|
|
3396
|
+
}
|
|
3397
|
+
});
|
|
3337
3398
|
const projectItems = allProjects.map((p) => {
|
|
3338
3399
|
const projectConfig = config.projects.find(
|
|
3339
3400
|
(c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
|
|
@@ -3341,9 +3402,9 @@ var init_ProjectsView = __esm({
|
|
|
3341
3402
|
const isExposed = projectConfig ? projectConfig.expose : config.defaults.includeNew;
|
|
3342
3403
|
return {
|
|
3343
3404
|
label: p.name + ` (${p.source})` + (p.path ? ` - ${p.path}` : ""),
|
|
3344
|
-
value: p.
|
|
3345
|
-
//
|
|
3346
|
-
key: p.
|
|
3405
|
+
value: p.path,
|
|
3406
|
+
// Standardized ID: Use root path
|
|
3407
|
+
key: p.path,
|
|
3347
3408
|
exposed: isExposed
|
|
3348
3409
|
};
|
|
3349
3410
|
});
|
|
@@ -3352,7 +3413,7 @@ var init_ProjectsView = __esm({
|
|
|
3352
3413
|
let newConfig = { ...config };
|
|
3353
3414
|
projectItems.forEach((item) => {
|
|
3354
3415
|
const isSelected = selectedIds.includes(item.value);
|
|
3355
|
-
const project = allProjects.find((p) => p.
|
|
3416
|
+
const project = allProjects.find((p) => p.path === item.value);
|
|
3356
3417
|
if (project) {
|
|
3357
3418
|
const existingConfig = newConfig.projects.find((p) => p.name === project.name);
|
|
3358
3419
|
const projectPath = project.source === "global" && existingConfig?.path ? existingConfig.path : project.path;
|
|
@@ -3370,7 +3431,14 @@ var init_ProjectsView = __esm({
|
|
|
3370
3431
|
if (onConfigChange) onConfigChange();
|
|
3371
3432
|
};
|
|
3372
3433
|
return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
|
|
3373
|
-
/* @__PURE__ */
|
|
3434
|
+
/* @__PURE__ */ jsxs3(Box4, { justifyContent: "space-between", children: [
|
|
3435
|
+
/* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: " Exposed Projects " }),
|
|
3436
|
+
/* @__PURE__ */ jsxs3(Box4, { children: [
|
|
3437
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Auto-expose new: " }),
|
|
3438
|
+
/* @__PURE__ */ jsx4(Text4, { color: config.defaults.includeNew ? "green" : "red", children: config.defaults.includeNew ? "ON" : "OFF" }),
|
|
3439
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: " (Press 'a' to toggle)" })
|
|
3440
|
+
] })
|
|
3441
|
+
] }),
|
|
3374
3442
|
/* @__PURE__ */ jsx4(Text4, { color: "dim", children: " Select projects to expose via the MCP server. Use Space to toggle, Enter to save." }),
|
|
3375
3443
|
/* @__PURE__ */ jsx4(Box4, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx4(
|
|
3376
3444
|
SimpleSelect,
|
|
@@ -3385,7 +3453,7 @@ var init_ProjectsView = __esm({
|
|
|
3385
3453
|
onCancel: () => {
|
|
3386
3454
|
}
|
|
3387
3455
|
},
|
|
3388
|
-
JSON.stringify(initialSelected)
|
|
3456
|
+
JSON.stringify(initialSelected) + config.defaults.includeNew
|
|
3389
3457
|
) })
|
|
3390
3458
|
] });
|
|
3391
3459
|
};
|
|
@@ -3651,14 +3719,14 @@ var init_IndexingStatus = __esm({
|
|
|
3651
3719
|
|
|
3652
3720
|
// src/mcp/ui/components/TabBar.tsx
|
|
3653
3721
|
import "react";
|
|
3654
|
-
import { Box as Box10, Text as Text10, useInput as
|
|
3722
|
+
import { Box as Box10, Text as Text10, useInput as useInput3 } from "ink";
|
|
3655
3723
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3656
3724
|
var TabBar;
|
|
3657
3725
|
var init_TabBar = __esm({
|
|
3658
3726
|
"src/mcp/ui/components/TabBar.tsx"() {
|
|
3659
3727
|
"use strict";
|
|
3660
3728
|
TabBar = ({ tabs, activeTab, onChange }) => {
|
|
3661
|
-
|
|
3729
|
+
useInput3((input, key) => {
|
|
3662
3730
|
if (key.leftArrow) {
|
|
3663
3731
|
const index = tabs.findIndex((t) => t.id === activeTab);
|
|
3664
3732
|
if (index !== -1) {
|
|
@@ -3705,7 +3773,7 @@ __export(App_exports, {
|
|
|
3705
3773
|
App: () => App
|
|
3706
3774
|
});
|
|
3707
3775
|
import { useState as useState5, useEffect as useEffect4, useMemo as useMemo2, useCallback } from "react";
|
|
3708
|
-
import { Box as Box11, useInput as
|
|
3776
|
+
import { Box as Box11, useInput as useInput4, useApp } from "ink";
|
|
3709
3777
|
import fs15 from "fs";
|
|
3710
3778
|
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3711
3779
|
var App;
|
|
@@ -3724,6 +3792,7 @@ var init_App = __esm({
|
|
|
3724
3792
|
init_detection();
|
|
3725
3793
|
init_logger();
|
|
3726
3794
|
init_server();
|
|
3795
|
+
init_resources();
|
|
3727
3796
|
init_install();
|
|
3728
3797
|
init_paths();
|
|
3729
3798
|
App = ({ onExit, initialPort }) => {
|
|
@@ -3742,12 +3811,7 @@ var init_App = __esm({
|
|
|
3742
3811
|
setProjects(scanForProjects());
|
|
3743
3812
|
}, []);
|
|
3744
3813
|
const exposedProjects = useMemo2(
|
|
3745
|
-
() => projects.filter((p) =>
|
|
3746
|
-
const cfg = config.projects.find(
|
|
3747
|
-
(c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
|
|
3748
|
-
);
|
|
3749
|
-
return cfg?.expose ?? config.defaults.includeNew;
|
|
3750
|
-
}),
|
|
3814
|
+
() => projects.filter((p) => isProjectExposed(config, p.name, p.path)),
|
|
3751
3815
|
[projects, config]
|
|
3752
3816
|
);
|
|
3753
3817
|
const isRAGEnabled = useMemo2(() => {
|
|
@@ -3819,7 +3883,7 @@ var init_App = __esm({
|
|
|
3819
3883
|
}, 500);
|
|
3820
3884
|
return () => clearInterval(interval);
|
|
3821
3885
|
}, []);
|
|
3822
|
-
|
|
3886
|
+
useInput4(async (input, key) => {
|
|
3823
3887
|
if (input === "q" || key.ctrl && input === "c") {
|
|
3824
3888
|
stopMCPServer();
|
|
3825
3889
|
onExit();
|
|
@@ -4562,14 +4626,14 @@ var init_link_flow = __esm({
|
|
|
4562
4626
|
import { confirm as confirm8, spinner as spinner5, note as note11, outro as outro4, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
|
|
4563
4627
|
import pc13 from "picocolors";
|
|
4564
4628
|
import * as fs17 from "fs";
|
|
4565
|
-
import * as
|
|
4629
|
+
import * as path18 from "path";
|
|
4566
4630
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
4567
4631
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
4568
4632
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
4569
|
-
const globalPath =
|
|
4633
|
+
const globalPath = path18.join(customGlobalPath, "workspaces", workspaceName);
|
|
4570
4634
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
4571
4635
|
const existingDirs = subdirs.filter(
|
|
4572
|
-
(dir) => fs17.existsSync(
|
|
4636
|
+
(dir) => fs17.existsSync(path18.join(localPath, dir))
|
|
4573
4637
|
);
|
|
4574
4638
|
if (existingDirs.length === 0) {
|
|
4575
4639
|
outro4(pc13.yellow("No data found in workspace storage to sync."));
|
|
@@ -4595,8 +4659,8 @@ Destination: ${pc13.cyan(globalPath)}`,
|
|
|
4595
4659
|
try {
|
|
4596
4660
|
ensureDir(globalPath);
|
|
4597
4661
|
for (const dir of existingDirs) {
|
|
4598
|
-
const srcDir =
|
|
4599
|
-
const destDir =
|
|
4662
|
+
const srcDir = path18.join(localPath, dir);
|
|
4663
|
+
const destDir = path18.join(globalPath, dir);
|
|
4600
4664
|
ensureDir(destDir);
|
|
4601
4665
|
copyDirRecursive(srcDir, destDir);
|
|
4602
4666
|
}
|
|
@@ -4629,7 +4693,7 @@ var init_sync_flow = __esm({
|
|
|
4629
4693
|
import { confirm as confirm9, spinner as spinner6, note as note12, outro as outro5, cancel as cancel6, isCancel as isCancel11 } from "@clack/prompts";
|
|
4630
4694
|
import pc14 from "picocolors";
|
|
4631
4695
|
import * as fs18 from "fs";
|
|
4632
|
-
import * as
|
|
4696
|
+
import * as path19 from "path";
|
|
4633
4697
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
4634
4698
|
const s = spinner6();
|
|
4635
4699
|
s.start("Checking for updates");
|
|
@@ -4659,7 +4723,7 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
4659
4723
|
}
|
|
4660
4724
|
s.start("Updating from package");
|
|
4661
4725
|
for (const dataPath of dataPaths) {
|
|
4662
|
-
copyDirToAllStoragePaths(
|
|
4726
|
+
copyDirToAllStoragePaths(path19.join(agentCoreDir, "templates"), "templates", [dataPath]);
|
|
4663
4727
|
}
|
|
4664
4728
|
const configFilePath = getConfigPath(workspacePath);
|
|
4665
4729
|
if (fs18.existsSync(configFilePath)) {
|
|
@@ -4692,8 +4756,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
4692
4756
|
}
|
|
4693
4757
|
}
|
|
4694
4758
|
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
4695
|
-
const globalPath =
|
|
4696
|
-
const workspacePath =
|
|
4759
|
+
const globalPath = path19.join(customGlobalPath, "workspaces", workspaceName);
|
|
4760
|
+
const workspacePath = path19.join(workspaceRoot, ".rrce-workflow");
|
|
4697
4761
|
switch (mode) {
|
|
4698
4762
|
case "global":
|
|
4699
4763
|
return [globalPath];
|
|
@@ -4925,9 +4989,9 @@ init_wizard();
|
|
|
4925
4989
|
init_prompts();
|
|
4926
4990
|
import { intro as intro3, select as select6, note as note15, cancel as cancel9, isCancel as isCancel14, outro as outro8 } from "@clack/prompts";
|
|
4927
4991
|
import pc17 from "picocolors";
|
|
4928
|
-
import * as
|
|
4992
|
+
import * as path20 from "path";
|
|
4929
4993
|
async function runSelector() {
|
|
4930
|
-
const workspaceName =
|
|
4994
|
+
const workspaceName = path20.basename(process.cwd());
|
|
4931
4995
|
intro3(pc17.cyan(pc17.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
4932
4996
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
4933
4997
|
if (prompts.length === 0) {
|