rrce-workflow 0.2.72 → 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.
- package/dist/index.js +158 -114
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1390,7 +1390,7 @@ var init_types = __esm({
|
|
|
1390
1390
|
},
|
|
1391
1391
|
projects: [],
|
|
1392
1392
|
defaults: {
|
|
1393
|
-
includeNew:
|
|
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
|
-
|
|
1413
|
-
|
|
1423
|
+
const configPath = p.path ? normalizeProjectPath(p.path) : void 0;
|
|
1424
|
+
if (targetPath && configPath) {
|
|
1425
|
+
return configPath === targetPath;
|
|
1414
1426
|
}
|
|
1415
|
-
if (!
|
|
1427
|
+
if (!targetPath && !configPath) {
|
|
1416
1428
|
return p.name === identifier.name;
|
|
1417
1429
|
}
|
|
1418
|
-
if (
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
1615
|
+
const globalPath = path11.join(globalWorkspacesDir, project.name);
|
|
1588
1616
|
exists = fs9.existsSync(globalPath);
|
|
1589
1617
|
}
|
|
1590
1618
|
if (exists) {
|
|
@@ -1609,29 +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
|
|
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(
|
|
1619
|
-
ensureDir(
|
|
1620
|
-
ensureDir(
|
|
1621
|
-
ensureDir(
|
|
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(
|
|
1628
|
-
copyDirToAllStoragePaths(
|
|
1629
|
-
copyDirToAllStoragePaths(
|
|
1655
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "templates"), "templates", dataPaths);
|
|
1656
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "prompts"), "prompts", dataPaths);
|
|
1657
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "docs"), "docs", dataPaths);
|
|
1630
1658
|
const rrceHome = config.globalPath || getDefaultRRCEHome2();
|
|
1631
|
-
ensureDir(
|
|
1632
|
-
ensureDir(
|
|
1633
|
-
copyDirRecursive(
|
|
1634
|
-
copyDirRecursive(
|
|
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"));
|
|
1635
1663
|
const needsIDEPrompts = config.storageMode === "workspace" && (config.tools.includes("copilot") || config.tools.includes("antigravity")) || config.tools.includes("opencode");
|
|
1636
1664
|
if (needsIDEPrompts) {
|
|
1637
1665
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
@@ -1648,12 +1676,12 @@ function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
|
1648
1676
|
}
|
|
1649
1677
|
}
|
|
1650
1678
|
if (config.tools.includes("opencode")) {
|
|
1651
|
-
const opencodePath =
|
|
1679
|
+
const opencodePath = path12.join(workspacePath, ".opencode", "agent");
|
|
1652
1680
|
ensureDir(opencodePath);
|
|
1653
1681
|
for (const prompt of prompts) {
|
|
1654
|
-
const baseName =
|
|
1682
|
+
const baseName = path12.basename(prompt.filePath, ".md");
|
|
1655
1683
|
const content = convertToOpenCodeAgent(prompt);
|
|
1656
|
-
fs10.writeFileSync(
|
|
1684
|
+
fs10.writeFileSync(path12.join(opencodePath, `${baseName}.md`), content);
|
|
1657
1685
|
}
|
|
1658
1686
|
}
|
|
1659
1687
|
}
|
|
@@ -1662,11 +1690,11 @@ function createWorkspaceConfig(config, workspacePath, workspaceName) {
|
|
|
1662
1690
|
let configPath;
|
|
1663
1691
|
if (config.storageMode === "global") {
|
|
1664
1692
|
const rrceHome = config.globalPath || getDefaultRRCEHome2();
|
|
1665
|
-
configPath =
|
|
1693
|
+
configPath = path12.join(rrceHome, "workspaces", workspaceName, "config.yaml");
|
|
1666
1694
|
} else {
|
|
1667
|
-
configPath =
|
|
1695
|
+
configPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
1668
1696
|
}
|
|
1669
|
-
ensureDir(
|
|
1697
|
+
ensureDir(path12.dirname(configPath));
|
|
1670
1698
|
let content = `# RRCE-Workflow Configuration
|
|
1671
1699
|
version: 1
|
|
1672
1700
|
|
|
@@ -1729,8 +1757,8 @@ You can configure MCP later: ${pc4.cyan("npx rrce-workflow mcp")}`,
|
|
|
1729
1757
|
}
|
|
1730
1758
|
}
|
|
1731
1759
|
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
1732
|
-
const globalPath =
|
|
1733
|
-
const workspacePath =
|
|
1760
|
+
const globalPath = path12.join(customGlobalPath || getDefaultRRCEHome2(), "workspaces", workspaceName);
|
|
1761
|
+
const workspacePath = path12.join(workspaceRoot, ".rrce-workflow");
|
|
1734
1762
|
switch (mode) {
|
|
1735
1763
|
case "global":
|
|
1736
1764
|
return [globalPath];
|
|
@@ -1784,9 +1812,9 @@ __export(gitignore_exports, {
|
|
|
1784
1812
|
updateGitignore: () => updateGitignore
|
|
1785
1813
|
});
|
|
1786
1814
|
import * as fs11 from "fs";
|
|
1787
|
-
import * as
|
|
1815
|
+
import * as path13 from "path";
|
|
1788
1816
|
function updateGitignore(workspacePath, storageMode, tools) {
|
|
1789
|
-
const gitignorePath =
|
|
1817
|
+
const gitignorePath = path13.join(workspacePath, ".gitignore");
|
|
1790
1818
|
const entries = [];
|
|
1791
1819
|
if (storageMode === "workspace") {
|
|
1792
1820
|
entries.push(".rrce-workflow/");
|
|
@@ -1826,11 +1854,11 @@ var init_gitignore = __esm({
|
|
|
1826
1854
|
|
|
1827
1855
|
// src/mcp/logger.ts
|
|
1828
1856
|
import * as fs12 from "fs";
|
|
1829
|
-
import * as
|
|
1857
|
+
import * as path14 from "path";
|
|
1830
1858
|
function getLogFilePath() {
|
|
1831
1859
|
const workspaceRoot = detectWorkspaceRoot();
|
|
1832
1860
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
1833
|
-
return
|
|
1861
|
+
return path14.join(rrceHome, "mcp-server.log");
|
|
1834
1862
|
}
|
|
1835
1863
|
var Logger, logger;
|
|
1836
1864
|
var init_logger = __esm({
|
|
@@ -1861,7 +1889,7 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1861
1889
|
}
|
|
1862
1890
|
logMessage += "\n";
|
|
1863
1891
|
try {
|
|
1864
|
-
const dir =
|
|
1892
|
+
const dir = path14.dirname(this.logPath);
|
|
1865
1893
|
if (!fs12.existsSync(dir)) {
|
|
1866
1894
|
fs12.mkdirSync(dir, { recursive: true });
|
|
1867
1895
|
}
|
|
@@ -1890,7 +1918,7 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1890
1918
|
|
|
1891
1919
|
// src/mcp/services/rag.ts
|
|
1892
1920
|
import * as fs13 from "fs";
|
|
1893
|
-
import * as
|
|
1921
|
+
import * as path15 from "path";
|
|
1894
1922
|
var INDEX_VERSION, DEFAULT_MODEL, RAGService;
|
|
1895
1923
|
var init_rag = __esm({
|
|
1896
1924
|
"src/mcp/services/rag.ts"() {
|
|
@@ -1972,7 +2000,7 @@ var init_rag = __esm({
|
|
|
1972
2000
|
saveIndex() {
|
|
1973
2001
|
if (!this.index) return;
|
|
1974
2002
|
try {
|
|
1975
|
-
const dir =
|
|
2003
|
+
const dir = path15.dirname(this.indexPath);
|
|
1976
2004
|
if (!fs13.existsSync(dir)) {
|
|
1977
2005
|
fs13.mkdirSync(dir, { recursive: true });
|
|
1978
2006
|
}
|
|
@@ -2138,21 +2166,19 @@ var init_rag = __esm({
|
|
|
2138
2166
|
|
|
2139
2167
|
// src/mcp/resources.ts
|
|
2140
2168
|
import * as fs14 from "fs";
|
|
2141
|
-
import * as
|
|
2169
|
+
import * as path16 from "path";
|
|
2142
2170
|
function getExposedProjects() {
|
|
2143
2171
|
const config = loadMCPConfig();
|
|
2144
2172
|
const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
|
|
2145
2173
|
const allProjects = projectService.scan({ knownPaths });
|
|
2146
|
-
const
|
|
2147
|
-
const
|
|
2148
|
-
let linkedProjects = [];
|
|
2174
|
+
const activeProject = detectActiveProject(allProjects);
|
|
2175
|
+
const potentialProjects = [...allProjects];
|
|
2149
2176
|
if (activeProject) {
|
|
2150
|
-
const localConfigPath = path15.join(activeProject.dataPath, "config.yaml");
|
|
2151
2177
|
let cfgContent = null;
|
|
2152
|
-
if (fs14.existsSync(
|
|
2153
|
-
cfgContent = fs14.readFileSync(
|
|
2154
|
-
} else if (fs14.existsSync(
|
|
2155
|
-
cfgContent = fs14.readFileSync(
|
|
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");
|
|
2156
2182
|
}
|
|
2157
2183
|
if (cfgContent) {
|
|
2158
2184
|
if (cfgContent.includes("linked_projects:")) {
|
|
@@ -2172,10 +2198,10 @@ function getExposedProjects() {
|
|
|
2172
2198
|
if (inLinked && trimmed.startsWith("-")) {
|
|
2173
2199
|
const val = trimmed.replace(/^-\s*/, "").trim();
|
|
2174
2200
|
const [pName] = val.split(":");
|
|
2175
|
-
if (!
|
|
2201
|
+
if (!potentialProjects.some((p) => p.name === pName)) {
|
|
2176
2202
|
const found = allProjects.find((p) => p.name === pName);
|
|
2177
2203
|
if (found) {
|
|
2178
|
-
|
|
2204
|
+
potentialProjects.push(found);
|
|
2179
2205
|
}
|
|
2180
2206
|
}
|
|
2181
2207
|
}
|
|
@@ -2184,11 +2210,11 @@ function getExposedProjects() {
|
|
|
2184
2210
|
}
|
|
2185
2211
|
}
|
|
2186
2212
|
}
|
|
2187
|
-
return
|
|
2213
|
+
return potentialProjects.filter((project) => isProjectExposed(config, project.name, project.path));
|
|
2188
2214
|
}
|
|
2189
2215
|
function getRAGIndexPath(project) {
|
|
2190
2216
|
const scanRoot = project.path || project.dataPath;
|
|
2191
|
-
return
|
|
2217
|
+
return path16.join(project.knowledgePath || path16.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
|
|
2192
2218
|
}
|
|
2193
2219
|
function detectActiveProject(knownProjects) {
|
|
2194
2220
|
let scanList = knownProjects;
|
|
@@ -2196,25 +2222,25 @@ function detectActiveProject(knownProjects) {
|
|
|
2196
2222
|
const config = loadMCPConfig();
|
|
2197
2223
|
const knownPaths = config.projects.map((p) => p.path).filter((p) => !!p);
|
|
2198
2224
|
const all = projectService.scan({ knownPaths });
|
|
2199
|
-
scanList = all.filter((project) => isProjectExposed(config, project.name, project.
|
|
2225
|
+
scanList = all.filter((project) => isProjectExposed(config, project.name, project.path));
|
|
2200
2226
|
}
|
|
2201
2227
|
return findClosestProject(scanList);
|
|
2202
2228
|
}
|
|
2203
2229
|
function getProjectContext(projectName) {
|
|
2204
2230
|
const config = loadMCPConfig();
|
|
2205
2231
|
const projects = projectService.scan();
|
|
2206
|
-
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.
|
|
2232
|
+
const project = projects.find((p) => p.name === projectName && isProjectExposed(config, p.name, p.path));
|
|
2207
2233
|
if (!project) {
|
|
2208
2234
|
return null;
|
|
2209
2235
|
}
|
|
2210
|
-
const permissions = getProjectPermissions(config, projectName, project.
|
|
2236
|
+
const permissions = getProjectPermissions(config, projectName, project.path);
|
|
2211
2237
|
if (!permissions.knowledge) {
|
|
2212
2238
|
return null;
|
|
2213
2239
|
}
|
|
2214
2240
|
if (!project.knowledgePath) {
|
|
2215
2241
|
return null;
|
|
2216
2242
|
}
|
|
2217
|
-
const contextPath =
|
|
2243
|
+
const contextPath = path16.join(project.knowledgePath, "project-context.md");
|
|
2218
2244
|
if (!fs14.existsSync(contextPath)) {
|
|
2219
2245
|
return null;
|
|
2220
2246
|
}
|
|
@@ -2223,11 +2249,11 @@ function getProjectContext(projectName) {
|
|
|
2223
2249
|
function getProjectTasks(projectName) {
|
|
2224
2250
|
const config = loadMCPConfig();
|
|
2225
2251
|
const projects = projectService.scan();
|
|
2226
|
-
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));
|
|
2227
2253
|
if (!project) {
|
|
2228
2254
|
return [];
|
|
2229
2255
|
}
|
|
2230
|
-
const permissions = getProjectPermissions(config, projectName, project.
|
|
2256
|
+
const permissions = getProjectPermissions(config, projectName, project.path);
|
|
2231
2257
|
if (!permissions.tasks) {
|
|
2232
2258
|
return [];
|
|
2233
2259
|
}
|
|
@@ -2239,7 +2265,7 @@ function getProjectTasks(projectName) {
|
|
|
2239
2265
|
const taskDirs = fs14.readdirSync(project.tasksPath, { withFileTypes: true });
|
|
2240
2266
|
for (const dir of taskDirs) {
|
|
2241
2267
|
if (!dir.isDirectory()) continue;
|
|
2242
|
-
const metaPath =
|
|
2268
|
+
const metaPath = path16.join(project.tasksPath, dir.name, "meta.json");
|
|
2243
2269
|
if (fs14.existsSync(metaPath)) {
|
|
2244
2270
|
try {
|
|
2245
2271
|
const meta = JSON.parse(fs14.readFileSync(metaPath, "utf-8"));
|
|
@@ -2259,21 +2285,21 @@ async function searchKnowledge(query, projectFilter) {
|
|
|
2259
2285
|
const queryLower = query.toLowerCase();
|
|
2260
2286
|
for (const project of projects) {
|
|
2261
2287
|
if (projectFilter && project.name !== projectFilter) continue;
|
|
2262
|
-
const permissions = getProjectPermissions(config, project.name, project.
|
|
2288
|
+
const permissions = getProjectPermissions(config, project.name, project.path);
|
|
2263
2289
|
if (!permissions.knowledge || !project.knowledgePath) continue;
|
|
2264
2290
|
const projConfig = config.projects.find(
|
|
2265
|
-
(p) => p.path && p.path === project.
|
|
2291
|
+
(p) => p.path && normalizeProjectPath(p.path) === normalizeProjectPath(project.path) || !p.path && p.name === project.name
|
|
2266
2292
|
);
|
|
2267
2293
|
const useRAG = projConfig?.semanticSearch?.enabled;
|
|
2268
2294
|
if (useRAG) {
|
|
2269
2295
|
try {
|
|
2270
|
-
const indexPath =
|
|
2296
|
+
const indexPath = path16.join(project.knowledgePath, "embeddings.json");
|
|
2271
2297
|
const rag = new RAGService(indexPath, projConfig?.semanticSearch?.model);
|
|
2272
2298
|
const ragResults = await rag.search(query, 5);
|
|
2273
2299
|
for (const r of ragResults) {
|
|
2274
2300
|
results.push({
|
|
2275
2301
|
project: project.name,
|
|
2276
|
-
file:
|
|
2302
|
+
file: path16.relative(project.knowledgePath, r.filePath),
|
|
2277
2303
|
matches: [r.content],
|
|
2278
2304
|
// The chunk content is the match
|
|
2279
2305
|
score: r.score
|
|
@@ -2287,7 +2313,7 @@ async function searchKnowledge(query, projectFilter) {
|
|
|
2287
2313
|
const files = fs14.readdirSync(project.knowledgePath);
|
|
2288
2314
|
for (const file of files) {
|
|
2289
2315
|
if (!file.endsWith(".md")) continue;
|
|
2290
|
-
const filePath =
|
|
2316
|
+
const filePath = path16.join(project.knowledgePath, file);
|
|
2291
2317
|
const content = fs14.readFileSync(filePath, "utf-8");
|
|
2292
2318
|
const lines = content.split("\n");
|
|
2293
2319
|
const matches = [];
|
|
@@ -2318,7 +2344,7 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
2318
2344
|
return { success: false, message: `Project '${projectName}' not found`, filesIndexed: 0, filesSkipped: 0 };
|
|
2319
2345
|
}
|
|
2320
2346
|
const projConfig = config.projects.find(
|
|
2321
|
-
(p) => p.path && p.path === project.
|
|
2347
|
+
(p) => p.path && normalizeProjectPath(p.path) === normalizeProjectPath(project.path) || !p.path && p.name === project.name
|
|
2322
2348
|
) || (project.source === "global" ? { semanticSearch: { enabled: true, model: "Xenova/all-MiniLM-L6-v2" } } : void 0);
|
|
2323
2349
|
const isEnabled = projConfig?.semanticSearch?.enabled || project.semanticSearchEnabled;
|
|
2324
2350
|
if (!isEnabled) {
|
|
@@ -2368,7 +2394,7 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
2368
2394
|
];
|
|
2369
2395
|
const SKIP_DIRS = ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "venv", ".venv", "target", "vendor"];
|
|
2370
2396
|
try {
|
|
2371
|
-
const indexPath =
|
|
2397
|
+
const indexPath = path16.join(project.knowledgePath || path16.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
|
|
2372
2398
|
const model = projConfig?.semanticSearch?.model || "Xenova/all-MiniLM-L6-v2";
|
|
2373
2399
|
const rag = new RAGService(indexPath, model);
|
|
2374
2400
|
let indexed = 0;
|
|
@@ -2376,14 +2402,14 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
2376
2402
|
const scanDir = async (dir) => {
|
|
2377
2403
|
const entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
2378
2404
|
for (const entry of entries) {
|
|
2379
|
-
const fullPath =
|
|
2405
|
+
const fullPath = path16.join(dir, entry.name);
|
|
2380
2406
|
if (entry.isDirectory()) {
|
|
2381
2407
|
if (SKIP_DIRS.includes(entry.name) || entry.name.startsWith(".")) {
|
|
2382
2408
|
continue;
|
|
2383
2409
|
}
|
|
2384
2410
|
await scanDir(fullPath);
|
|
2385
2411
|
} else if (entry.isFile()) {
|
|
2386
|
-
const ext =
|
|
2412
|
+
const ext = path16.extname(entry.name).toLowerCase();
|
|
2387
2413
|
if (!INDEXABLE_EXTENSIONS.includes(ext)) {
|
|
2388
2414
|
continue;
|
|
2389
2415
|
}
|
|
@@ -2420,7 +2446,7 @@ function getContextPreamble() {
|
|
|
2420
2446
|
const activeProject = detectActiveProject();
|
|
2421
2447
|
let contextPreamble = "";
|
|
2422
2448
|
if (activeProject) {
|
|
2423
|
-
const rrceHome = process.env.RRCE_HOME ||
|
|
2449
|
+
const rrceHome = process.env.RRCE_HOME || path16.join(__require("os").homedir(), ".rrce-workflow");
|
|
2424
2450
|
const workspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
|
|
2425
2451
|
const rrceData = activeProject.dataPath;
|
|
2426
2452
|
contextPreamble += `
|
|
@@ -2437,7 +2463,7 @@ Use these values directly in your operations. Do NOT manually resolve paths.
|
|
|
2437
2463
|
`;
|
|
2438
2464
|
}
|
|
2439
2465
|
const projectList = projects.map((p) => {
|
|
2440
|
-
const isActive = activeProject && p.
|
|
2466
|
+
const isActive = activeProject && normalizeProjectPath(p.path) === normalizeProjectPath(activeProject.path);
|
|
2441
2467
|
return `- ${p.name} (${p.source}) ${isActive ? "**[ACTIVE]**" : ""}`;
|
|
2442
2468
|
}).join("\n");
|
|
2443
2469
|
contextPreamble += `
|
|
@@ -2465,6 +2491,7 @@ var init_resources = __esm({
|
|
|
2465
2491
|
"src/mcp/resources.ts"() {
|
|
2466
2492
|
"use strict";
|
|
2467
2493
|
init_config();
|
|
2494
|
+
init_config_utils();
|
|
2468
2495
|
init_detection();
|
|
2469
2496
|
init_detection_service();
|
|
2470
2497
|
init_rag();
|
|
@@ -2555,7 +2582,7 @@ var init_resources2 = __esm({
|
|
|
2555
2582
|
});
|
|
2556
2583
|
|
|
2557
2584
|
// src/mcp/prompts.ts
|
|
2558
|
-
import * as
|
|
2585
|
+
import * as path17 from "path";
|
|
2559
2586
|
function getAllPrompts() {
|
|
2560
2587
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
2561
2588
|
return prompts.map((p) => {
|
|
@@ -2608,8 +2635,8 @@ function renderPromptWithContext(content, args) {
|
|
|
2608
2635
|
resolvedWorkspaceRoot = activeProject.sourcePath || activeProject.path || activeProject.dataPath;
|
|
2609
2636
|
resolvedWorkspaceName = activeProject.name;
|
|
2610
2637
|
if (activeProject.source === "global") {
|
|
2611
|
-
const workspacesDir =
|
|
2612
|
-
resolvedRrceHome =
|
|
2638
|
+
const workspacesDir = path17.dirname(activeProject.dataPath);
|
|
2639
|
+
resolvedRrceHome = path17.dirname(workspacesDir);
|
|
2613
2640
|
}
|
|
2614
2641
|
}
|
|
2615
2642
|
if (!renderArgs["RRCE_DATA"]) renderArgs["RRCE_DATA"] = resolvedRrceData;
|
|
@@ -3059,7 +3086,7 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
3059
3086
|
async function handleConfigureGlobalPath() {
|
|
3060
3087
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
3061
3088
|
const fs21 = await import("fs");
|
|
3062
|
-
const
|
|
3089
|
+
const path21 = await import("path");
|
|
3063
3090
|
note3(
|
|
3064
3091
|
`MCP Hub requires a ${pc5.bold("global storage path")} to store its configuration
|
|
3065
3092
|
and coordinate across projects.
|
|
@@ -3082,7 +3109,7 @@ locally in each project. MCP needs a central location.`,
|
|
|
3082
3109
|
`${pc5.green("\u2713")} Global path configured: ${pc5.cyan(resolvedPath)}
|
|
3083
3110
|
|
|
3084
3111
|
MCP config will be stored at:
|
|
3085
|
-
${
|
|
3112
|
+
${path21.join(resolvedPath, "mcp.yaml")}`,
|
|
3086
3113
|
"Configuration Saved"
|
|
3087
3114
|
);
|
|
3088
3115
|
return true;
|
|
@@ -3324,7 +3351,7 @@ var init_SimpleSelect = __esm({
|
|
|
3324
3351
|
|
|
3325
3352
|
// src/mcp/ui/ProjectsView.tsx
|
|
3326
3353
|
import { useState as useState2 } from "react";
|
|
3327
|
-
import { Box as Box4, Text as Text4 } from "ink";
|
|
3354
|
+
import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
|
|
3328
3355
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3329
3356
|
var ProjectsView;
|
|
3330
3357
|
var init_ProjectsView = __esm({
|
|
@@ -3334,6 +3361,20 @@ var init_ProjectsView = __esm({
|
|
|
3334
3361
|
init_config();
|
|
3335
3362
|
ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange }) => {
|
|
3336
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
|
+
});
|
|
3337
3378
|
const projectItems = allProjects.map((p) => {
|
|
3338
3379
|
const projectConfig = config.projects.find(
|
|
3339
3380
|
(c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
|
|
@@ -3341,9 +3382,9 @@ var init_ProjectsView = __esm({
|
|
|
3341
3382
|
const isExposed = projectConfig ? projectConfig.expose : config.defaults.includeNew;
|
|
3342
3383
|
return {
|
|
3343
3384
|
label: p.name + ` (${p.source})` + (p.path ? ` - ${p.path}` : ""),
|
|
3344
|
-
value: p.
|
|
3345
|
-
//
|
|
3346
|
-
key: p.
|
|
3385
|
+
value: p.path,
|
|
3386
|
+
// Standardized ID: Use root path
|
|
3387
|
+
key: p.path,
|
|
3347
3388
|
exposed: isExposed
|
|
3348
3389
|
};
|
|
3349
3390
|
});
|
|
@@ -3352,7 +3393,7 @@ var init_ProjectsView = __esm({
|
|
|
3352
3393
|
let newConfig = { ...config };
|
|
3353
3394
|
projectItems.forEach((item) => {
|
|
3354
3395
|
const isSelected = selectedIds.includes(item.value);
|
|
3355
|
-
const project = allProjects.find((p) => p.
|
|
3396
|
+
const project = allProjects.find((p) => p.path === item.value);
|
|
3356
3397
|
if (project) {
|
|
3357
3398
|
const existingConfig = newConfig.projects.find((p) => p.name === project.name);
|
|
3358
3399
|
const projectPath = project.source === "global" && existingConfig?.path ? existingConfig.path : project.path;
|
|
@@ -3370,7 +3411,14 @@ var init_ProjectsView = __esm({
|
|
|
3370
3411
|
if (onConfigChange) onConfigChange();
|
|
3371
3412
|
};
|
|
3372
3413
|
return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
|
|
3373
|
-
/* @__PURE__ */
|
|
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
|
+
] }),
|
|
3374
3422
|
/* @__PURE__ */ jsx4(Text4, { color: "dim", children: " Select projects to expose via the MCP server. Use Space to toggle, Enter to save." }),
|
|
3375
3423
|
/* @__PURE__ */ jsx4(Box4, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx4(
|
|
3376
3424
|
SimpleSelect,
|
|
@@ -3385,7 +3433,7 @@ var init_ProjectsView = __esm({
|
|
|
3385
3433
|
onCancel: () => {
|
|
3386
3434
|
}
|
|
3387
3435
|
},
|
|
3388
|
-
JSON.stringify(initialSelected)
|
|
3436
|
+
JSON.stringify(initialSelected) + config.defaults.includeNew
|
|
3389
3437
|
) })
|
|
3390
3438
|
] });
|
|
3391
3439
|
};
|
|
@@ -3651,14 +3699,14 @@ var init_IndexingStatus = __esm({
|
|
|
3651
3699
|
|
|
3652
3700
|
// src/mcp/ui/components/TabBar.tsx
|
|
3653
3701
|
import "react";
|
|
3654
|
-
import { Box as Box10, Text as Text10, useInput as
|
|
3702
|
+
import { Box as Box10, Text as Text10, useInput as useInput3 } from "ink";
|
|
3655
3703
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3656
3704
|
var TabBar;
|
|
3657
3705
|
var init_TabBar = __esm({
|
|
3658
3706
|
"src/mcp/ui/components/TabBar.tsx"() {
|
|
3659
3707
|
"use strict";
|
|
3660
3708
|
TabBar = ({ tabs, activeTab, onChange }) => {
|
|
3661
|
-
|
|
3709
|
+
useInput3((input, key) => {
|
|
3662
3710
|
if (key.leftArrow) {
|
|
3663
3711
|
const index = tabs.findIndex((t) => t.id === activeTab);
|
|
3664
3712
|
if (index !== -1) {
|
|
@@ -3705,7 +3753,7 @@ __export(App_exports, {
|
|
|
3705
3753
|
App: () => App
|
|
3706
3754
|
});
|
|
3707
3755
|
import { useState as useState5, useEffect as useEffect4, useMemo as useMemo2, useCallback } from "react";
|
|
3708
|
-
import { Box as Box11, useInput as
|
|
3756
|
+
import { Box as Box11, useInput as useInput4, useApp } from "ink";
|
|
3709
3757
|
import fs15 from "fs";
|
|
3710
3758
|
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3711
3759
|
var App;
|
|
@@ -3724,6 +3772,7 @@ var init_App = __esm({
|
|
|
3724
3772
|
init_detection();
|
|
3725
3773
|
init_logger();
|
|
3726
3774
|
init_server();
|
|
3775
|
+
init_resources();
|
|
3727
3776
|
init_install();
|
|
3728
3777
|
init_paths();
|
|
3729
3778
|
App = ({ onExit, initialPort }) => {
|
|
@@ -3742,12 +3791,7 @@ var init_App = __esm({
|
|
|
3742
3791
|
setProjects(scanForProjects());
|
|
3743
3792
|
}, []);
|
|
3744
3793
|
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
|
-
}),
|
|
3794
|
+
() => projects.filter((p) => isProjectExposed(config, p.name, p.path)),
|
|
3751
3795
|
[projects, config]
|
|
3752
3796
|
);
|
|
3753
3797
|
const isRAGEnabled = useMemo2(() => {
|
|
@@ -3819,7 +3863,7 @@ var init_App = __esm({
|
|
|
3819
3863
|
}, 500);
|
|
3820
3864
|
return () => clearInterval(interval);
|
|
3821
3865
|
}, []);
|
|
3822
|
-
|
|
3866
|
+
useInput4(async (input, key) => {
|
|
3823
3867
|
if (input === "q" || key.ctrl && input === "c") {
|
|
3824
3868
|
stopMCPServer();
|
|
3825
3869
|
onExit();
|
|
@@ -4562,14 +4606,14 @@ var init_link_flow = __esm({
|
|
|
4562
4606
|
import { confirm as confirm8, spinner as spinner5, note as note11, outro as outro4, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
|
|
4563
4607
|
import pc13 from "picocolors";
|
|
4564
4608
|
import * as fs17 from "fs";
|
|
4565
|
-
import * as
|
|
4609
|
+
import * as path18 from "path";
|
|
4566
4610
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
4567
4611
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
4568
4612
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
4569
|
-
const globalPath =
|
|
4613
|
+
const globalPath = path18.join(customGlobalPath, "workspaces", workspaceName);
|
|
4570
4614
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
4571
4615
|
const existingDirs = subdirs.filter(
|
|
4572
|
-
(dir) => fs17.existsSync(
|
|
4616
|
+
(dir) => fs17.existsSync(path18.join(localPath, dir))
|
|
4573
4617
|
);
|
|
4574
4618
|
if (existingDirs.length === 0) {
|
|
4575
4619
|
outro4(pc13.yellow("No data found in workspace storage to sync."));
|
|
@@ -4595,8 +4639,8 @@ Destination: ${pc13.cyan(globalPath)}`,
|
|
|
4595
4639
|
try {
|
|
4596
4640
|
ensureDir(globalPath);
|
|
4597
4641
|
for (const dir of existingDirs) {
|
|
4598
|
-
const srcDir =
|
|
4599
|
-
const destDir =
|
|
4642
|
+
const srcDir = path18.join(localPath, dir);
|
|
4643
|
+
const destDir = path18.join(globalPath, dir);
|
|
4600
4644
|
ensureDir(destDir);
|
|
4601
4645
|
copyDirRecursive(srcDir, destDir);
|
|
4602
4646
|
}
|
|
@@ -4629,7 +4673,7 @@ var init_sync_flow = __esm({
|
|
|
4629
4673
|
import { confirm as confirm9, spinner as spinner6, note as note12, outro as outro5, cancel as cancel6, isCancel as isCancel11 } from "@clack/prompts";
|
|
4630
4674
|
import pc14 from "picocolors";
|
|
4631
4675
|
import * as fs18 from "fs";
|
|
4632
|
-
import * as
|
|
4676
|
+
import * as path19 from "path";
|
|
4633
4677
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
4634
4678
|
const s = spinner6();
|
|
4635
4679
|
s.start("Checking for updates");
|
|
@@ -4659,7 +4703,7 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
4659
4703
|
}
|
|
4660
4704
|
s.start("Updating from package");
|
|
4661
4705
|
for (const dataPath of dataPaths) {
|
|
4662
|
-
copyDirToAllStoragePaths(
|
|
4706
|
+
copyDirToAllStoragePaths(path19.join(agentCoreDir, "templates"), "templates", [dataPath]);
|
|
4663
4707
|
}
|
|
4664
4708
|
const configFilePath = getConfigPath(workspacePath);
|
|
4665
4709
|
if (fs18.existsSync(configFilePath)) {
|
|
@@ -4692,8 +4736,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
4692
4736
|
}
|
|
4693
4737
|
}
|
|
4694
4738
|
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
4695
|
-
const globalPath =
|
|
4696
|
-
const workspacePath =
|
|
4739
|
+
const globalPath = path19.join(customGlobalPath, "workspaces", workspaceName);
|
|
4740
|
+
const workspacePath = path19.join(workspaceRoot, ".rrce-workflow");
|
|
4697
4741
|
switch (mode) {
|
|
4698
4742
|
case "global":
|
|
4699
4743
|
return [globalPath];
|
|
@@ -4925,9 +4969,9 @@ init_wizard();
|
|
|
4925
4969
|
init_prompts();
|
|
4926
4970
|
import { intro as intro3, select as select6, note as note15, cancel as cancel9, isCancel as isCancel14, outro as outro8 } from "@clack/prompts";
|
|
4927
4971
|
import pc17 from "picocolors";
|
|
4928
|
-
import * as
|
|
4972
|
+
import * as path20 from "path";
|
|
4929
4973
|
async function runSelector() {
|
|
4930
|
-
const workspaceName =
|
|
4974
|
+
const workspaceName = path20.basename(process.cwd());
|
|
4931
4975
|
intro3(pc17.cyan(pc17.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
4932
4976
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
4933
4977
|
if (prompts.length === 0) {
|