rrce-workflow 0.2.46 → 0.2.48
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 +383 -180
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -705,6 +705,38 @@ var init_autocomplete_prompt = __esm({
|
|
|
705
705
|
}
|
|
706
706
|
});
|
|
707
707
|
|
|
708
|
+
// src/lib/preferences.ts
|
|
709
|
+
import * as fs7 from "fs";
|
|
710
|
+
import * as path7 from "path";
|
|
711
|
+
function getPreferencesPath() {
|
|
712
|
+
const home = process.env.HOME || "~";
|
|
713
|
+
return path7.join(home, ".rrce-workflow", "preferences.json");
|
|
714
|
+
}
|
|
715
|
+
function loadUserPreferences() {
|
|
716
|
+
const prefPath = getPreferencesPath();
|
|
717
|
+
if (!fs7.existsSync(prefPath)) {
|
|
718
|
+
return {};
|
|
719
|
+
}
|
|
720
|
+
try {
|
|
721
|
+
return JSON.parse(fs7.readFileSync(prefPath, "utf-8"));
|
|
722
|
+
} catch {
|
|
723
|
+
return {};
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
function saveUserPreferences(prefs) {
|
|
727
|
+
const prefPath = getPreferencesPath();
|
|
728
|
+
ensureDir(path7.dirname(prefPath));
|
|
729
|
+
const current = loadUserPreferences();
|
|
730
|
+
const refined = { ...current, ...prefs };
|
|
731
|
+
fs7.writeFileSync(prefPath, JSON.stringify(refined, null, 2));
|
|
732
|
+
}
|
|
733
|
+
var init_preferences = __esm({
|
|
734
|
+
"src/lib/preferences.ts"() {
|
|
735
|
+
"use strict";
|
|
736
|
+
init_paths();
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
|
|
708
740
|
// src/lib/tui-utils.ts
|
|
709
741
|
var tui_utils_exports = {};
|
|
710
742
|
__export(tui_utils_exports, {
|
|
@@ -712,9 +744,10 @@ __export(tui_utils_exports, {
|
|
|
712
744
|
});
|
|
713
745
|
import { select, note, isCancel } from "@clack/prompts";
|
|
714
746
|
import pc2 from "picocolors";
|
|
715
|
-
import * as
|
|
747
|
+
import * as path8 from "path";
|
|
716
748
|
async function resolveGlobalPath() {
|
|
717
|
-
const
|
|
749
|
+
const prefs = loadUserPreferences();
|
|
750
|
+
const defaultPath = prefs.defaultGlobalPath || getDefaultRRCEHome();
|
|
718
751
|
const isDefaultWritable = checkWriteAccess(defaultPath);
|
|
719
752
|
const options = [
|
|
720
753
|
{
|
|
@@ -750,7 +783,7 @@ Please choose a custom path instead.`,
|
|
|
750
783
|
}
|
|
751
784
|
return defaultPath;
|
|
752
785
|
}
|
|
753
|
-
const suggestedPath =
|
|
786
|
+
const suggestedPath = path8.join(process.env.HOME || "~", ".local", "share", "rrce-workflow");
|
|
754
787
|
const customPath = await directoryPrompt({
|
|
755
788
|
message: "Enter custom global path (Tab to autocomplete):",
|
|
756
789
|
defaultValue: suggestedPath,
|
|
@@ -769,8 +802,9 @@ Please choose a custom path instead.`,
|
|
|
769
802
|
}
|
|
770
803
|
let expandedPath = customPath;
|
|
771
804
|
if (!expandedPath.endsWith(".rrce-workflow")) {
|
|
772
|
-
expandedPath =
|
|
805
|
+
expandedPath = path8.join(expandedPath, ".rrce-workflow");
|
|
773
806
|
}
|
|
807
|
+
saveUserPreferences({ defaultGlobalPath: expandedPath });
|
|
774
808
|
return expandedPath;
|
|
775
809
|
}
|
|
776
810
|
var init_tui_utils = __esm({
|
|
@@ -778,6 +812,7 @@ var init_tui_utils = __esm({
|
|
|
778
812
|
"use strict";
|
|
779
813
|
init_paths();
|
|
780
814
|
init_autocomplete_prompt();
|
|
815
|
+
init_preferences();
|
|
781
816
|
}
|
|
782
817
|
});
|
|
783
818
|
|
|
@@ -812,6 +847,7 @@ var init_types = __esm({
|
|
|
812
847
|
// src/mcp/config.ts
|
|
813
848
|
var config_exports = {};
|
|
814
849
|
__export(config_exports, {
|
|
850
|
+
cleanStaleProjects: () => cleanStaleProjects,
|
|
815
851
|
ensureMCPGlobalPath: () => ensureMCPGlobalPath,
|
|
816
852
|
getMCPConfigPath: () => getMCPConfigPath,
|
|
817
853
|
getProjectPermissions: () => getProjectPermissions,
|
|
@@ -821,20 +857,20 @@ __export(config_exports, {
|
|
|
821
857
|
saveMCPConfig: () => saveMCPConfig,
|
|
822
858
|
setProjectConfig: () => setProjectConfig
|
|
823
859
|
});
|
|
824
|
-
import * as
|
|
825
|
-
import * as
|
|
860
|
+
import * as fs8 from "fs";
|
|
861
|
+
import * as path9 from "path";
|
|
826
862
|
function getMCPConfigPath() {
|
|
827
863
|
const workspaceRoot = detectWorkspaceRoot();
|
|
828
864
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
829
|
-
return
|
|
865
|
+
return path9.join(rrceHome, "mcp.yaml");
|
|
830
866
|
}
|
|
831
867
|
function ensureMCPGlobalPath() {
|
|
832
868
|
const workspaceRoot = detectWorkspaceRoot();
|
|
833
869
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
834
870
|
if (rrceHome.startsWith(".") || rrceHome.includes(".rrce-workflow/")) {
|
|
835
|
-
const configPath =
|
|
836
|
-
if (
|
|
837
|
-
const content =
|
|
871
|
+
const configPath = path9.join(workspaceRoot, ".rrce-workflow", "config.yaml");
|
|
872
|
+
if (fs8.existsSync(configPath)) {
|
|
873
|
+
const content = fs8.readFileSync(configPath, "utf-8");
|
|
838
874
|
const modeMatch = content.match(/mode:\s*(global|workspace)/);
|
|
839
875
|
if (modeMatch?.[1] === "workspace") {
|
|
840
876
|
return {
|
|
@@ -852,11 +888,11 @@ function ensureMCPGlobalPath() {
|
|
|
852
888
|
}
|
|
853
889
|
function loadMCPConfig() {
|
|
854
890
|
const configPath = getMCPConfigPath();
|
|
855
|
-
if (!
|
|
891
|
+
if (!fs8.existsSync(configPath)) {
|
|
856
892
|
return { ...DEFAULT_MCP_CONFIG };
|
|
857
893
|
}
|
|
858
894
|
try {
|
|
859
|
-
const content =
|
|
895
|
+
const content = fs8.readFileSync(configPath, "utf-8");
|
|
860
896
|
return parseMCPConfig(content);
|
|
861
897
|
} catch {
|
|
862
898
|
return { ...DEFAULT_MCP_CONFIG };
|
|
@@ -864,12 +900,12 @@ function loadMCPConfig() {
|
|
|
864
900
|
}
|
|
865
901
|
function saveMCPConfig(config) {
|
|
866
902
|
const configPath = getMCPConfigPath();
|
|
867
|
-
const dir =
|
|
868
|
-
if (!
|
|
869
|
-
|
|
903
|
+
const dir = path9.dirname(configPath);
|
|
904
|
+
if (!fs8.existsSync(dir)) {
|
|
905
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
870
906
|
}
|
|
871
907
|
const content = serializeMCPConfig(config);
|
|
872
|
-
|
|
908
|
+
fs8.writeFileSync(configPath, content);
|
|
873
909
|
}
|
|
874
910
|
function parseMCPConfig(content) {
|
|
875
911
|
const config = { ...DEFAULT_MCP_CONFIG, projects: [] };
|
|
@@ -1088,6 +1124,30 @@ function getProjectPermissions(config, name, projectPath) {
|
|
|
1088
1124
|
});
|
|
1089
1125
|
return project?.permissions ?? config.defaults.permissions;
|
|
1090
1126
|
}
|
|
1127
|
+
function cleanStaleProjects(config) {
|
|
1128
|
+
const rrceHome = getEffectiveRRCEHome();
|
|
1129
|
+
const globalWorkspacesDir = path9.join(rrceHome, "workspaces");
|
|
1130
|
+
const validProjects = [];
|
|
1131
|
+
const removed = [];
|
|
1132
|
+
for (const project of config.projects) {
|
|
1133
|
+
let exists = false;
|
|
1134
|
+
if (project.path) {
|
|
1135
|
+
exists = fs8.existsSync(project.path);
|
|
1136
|
+
} else {
|
|
1137
|
+
const globalPath = path9.join(globalWorkspacesDir, project.name);
|
|
1138
|
+
exists = fs8.existsSync(globalPath);
|
|
1139
|
+
}
|
|
1140
|
+
if (exists) {
|
|
1141
|
+
validProjects.push(project);
|
|
1142
|
+
} else {
|
|
1143
|
+
removed.push(project.name);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (removed.length > 0) {
|
|
1147
|
+
config.projects = validProjects;
|
|
1148
|
+
}
|
|
1149
|
+
return { config, removed };
|
|
1150
|
+
}
|
|
1091
1151
|
var init_config = __esm({
|
|
1092
1152
|
"src/mcp/config.ts"() {
|
|
1093
1153
|
"use strict";
|
|
@@ -1097,12 +1157,12 @@ var init_config = __esm({
|
|
|
1097
1157
|
});
|
|
1098
1158
|
|
|
1099
1159
|
// src/mcp/logger.ts
|
|
1100
|
-
import * as
|
|
1101
|
-
import * as
|
|
1160
|
+
import * as fs9 from "fs";
|
|
1161
|
+
import * as path10 from "path";
|
|
1102
1162
|
function getLogFilePath() {
|
|
1103
1163
|
const workspaceRoot = detectWorkspaceRoot();
|
|
1104
1164
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
1105
|
-
return
|
|
1165
|
+
return path10.join(rrceHome, "mcp-server.log");
|
|
1106
1166
|
}
|
|
1107
1167
|
var Logger, logger;
|
|
1108
1168
|
var init_logger = __esm({
|
|
@@ -1133,11 +1193,11 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1133
1193
|
}
|
|
1134
1194
|
logMessage += "\n";
|
|
1135
1195
|
try {
|
|
1136
|
-
const dir =
|
|
1137
|
-
if (!
|
|
1138
|
-
|
|
1196
|
+
const dir = path10.dirname(this.logPath);
|
|
1197
|
+
if (!fs9.existsSync(dir)) {
|
|
1198
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
1139
1199
|
}
|
|
1140
|
-
|
|
1200
|
+
fs9.appendFileSync(this.logPath, logMessage);
|
|
1141
1201
|
} catch (e) {
|
|
1142
1202
|
console.error(`[Logger Failure] Could not write to ${this.logPath}`, e);
|
|
1143
1203
|
console.error(logMessage);
|
|
@@ -1161,8 +1221,8 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1161
1221
|
});
|
|
1162
1222
|
|
|
1163
1223
|
// src/mcp/services/rag.ts
|
|
1164
|
-
import * as
|
|
1165
|
-
import * as
|
|
1224
|
+
import * as fs10 from "fs";
|
|
1225
|
+
import * as path11 from "path";
|
|
1166
1226
|
var INDEX_VERSION, DEFAULT_MODEL, RAGService;
|
|
1167
1227
|
var init_rag = __esm({
|
|
1168
1228
|
"src/mcp/services/rag.ts"() {
|
|
@@ -1203,9 +1263,9 @@ var init_rag = __esm({
|
|
|
1203
1263
|
*/
|
|
1204
1264
|
loadIndex() {
|
|
1205
1265
|
if (this.index) return;
|
|
1206
|
-
if (
|
|
1266
|
+
if (fs10.existsSync(this.indexPath)) {
|
|
1207
1267
|
try {
|
|
1208
|
-
const data =
|
|
1268
|
+
const data = fs10.readFileSync(this.indexPath, "utf-8");
|
|
1209
1269
|
this.index = JSON.parse(data);
|
|
1210
1270
|
logger.info(`RAG: Loaded index from ${this.indexPath} with ${this.index?.chunks.length} chunks.`);
|
|
1211
1271
|
} catch (error) {
|
|
@@ -1231,11 +1291,11 @@ var init_rag = __esm({
|
|
|
1231
1291
|
saveIndex() {
|
|
1232
1292
|
if (!this.index) return;
|
|
1233
1293
|
try {
|
|
1234
|
-
const dir =
|
|
1235
|
-
if (!
|
|
1236
|
-
|
|
1294
|
+
const dir = path11.dirname(this.indexPath);
|
|
1295
|
+
if (!fs10.existsSync(dir)) {
|
|
1296
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
1237
1297
|
}
|
|
1238
|
-
|
|
1298
|
+
fs10.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2));
|
|
1239
1299
|
logger.info(`RAG: Saved index to ${this.indexPath} with ${this.index.chunks.length} chunks.`);
|
|
1240
1300
|
} catch (error) {
|
|
1241
1301
|
logger.error(`RAG: Failed to save index to ${this.indexPath}`, error);
|
|
@@ -1351,8 +1411,8 @@ var init_rag = __esm({
|
|
|
1351
1411
|
});
|
|
1352
1412
|
|
|
1353
1413
|
// src/mcp/resources.ts
|
|
1354
|
-
import * as
|
|
1355
|
-
import * as
|
|
1414
|
+
import * as fs11 from "fs";
|
|
1415
|
+
import * as path12 from "path";
|
|
1356
1416
|
function getExposedProjects() {
|
|
1357
1417
|
const config = loadMCPConfig();
|
|
1358
1418
|
const allProjects = scanForProjects();
|
|
@@ -1360,12 +1420,12 @@ function getExposedProjects() {
|
|
|
1360
1420
|
const activeProject = detectActiveProject(globalProjects);
|
|
1361
1421
|
let linkedProjects = [];
|
|
1362
1422
|
if (activeProject) {
|
|
1363
|
-
const localConfigPath =
|
|
1423
|
+
const localConfigPath = path12.join(activeProject.dataPath, "config.yaml");
|
|
1364
1424
|
let cfgContent = null;
|
|
1365
|
-
if (
|
|
1366
|
-
cfgContent =
|
|
1367
|
-
} else if (
|
|
1368
|
-
cfgContent =
|
|
1425
|
+
if (fs11.existsSync(path12.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
|
|
1426
|
+
cfgContent = fs11.readFileSync(path12.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
|
|
1427
|
+
} else if (fs11.existsSync(path12.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
|
|
1428
|
+
cfgContent = fs11.readFileSync(path12.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
|
|
1369
1429
|
}
|
|
1370
1430
|
if (cfgContent) {
|
|
1371
1431
|
if (cfgContent.includes("linked_projects:")) {
|
|
@@ -1425,11 +1485,11 @@ function getProjectContext(projectName) {
|
|
|
1425
1485
|
if (!project.knowledgePath) {
|
|
1426
1486
|
return null;
|
|
1427
1487
|
}
|
|
1428
|
-
const contextPath =
|
|
1429
|
-
if (!
|
|
1488
|
+
const contextPath = path12.join(project.knowledgePath, "project-context.md");
|
|
1489
|
+
if (!fs11.existsSync(contextPath)) {
|
|
1430
1490
|
return null;
|
|
1431
1491
|
}
|
|
1432
|
-
return
|
|
1492
|
+
return fs11.readFileSync(contextPath, "utf-8");
|
|
1433
1493
|
}
|
|
1434
1494
|
function getProjectTasks(projectName) {
|
|
1435
1495
|
const config = loadMCPConfig();
|
|
@@ -1442,18 +1502,18 @@ function getProjectTasks(projectName) {
|
|
|
1442
1502
|
if (!permissions.tasks) {
|
|
1443
1503
|
return [];
|
|
1444
1504
|
}
|
|
1445
|
-
if (!project.tasksPath || !
|
|
1505
|
+
if (!project.tasksPath || !fs11.existsSync(project.tasksPath)) {
|
|
1446
1506
|
return [];
|
|
1447
1507
|
}
|
|
1448
1508
|
const tasks = [];
|
|
1449
1509
|
try {
|
|
1450
|
-
const taskDirs =
|
|
1510
|
+
const taskDirs = fs11.readdirSync(project.tasksPath, { withFileTypes: true });
|
|
1451
1511
|
for (const dir of taskDirs) {
|
|
1452
1512
|
if (!dir.isDirectory()) continue;
|
|
1453
|
-
const metaPath =
|
|
1454
|
-
if (
|
|
1513
|
+
const metaPath = path12.join(project.tasksPath, dir.name, "meta.json");
|
|
1514
|
+
if (fs11.existsSync(metaPath)) {
|
|
1455
1515
|
try {
|
|
1456
|
-
const meta = JSON.parse(
|
|
1516
|
+
const meta = JSON.parse(fs11.readFileSync(metaPath, "utf-8"));
|
|
1457
1517
|
tasks.push(meta);
|
|
1458
1518
|
} catch {
|
|
1459
1519
|
}
|
|
@@ -1477,13 +1537,13 @@ async function searchKnowledge(query) {
|
|
|
1477
1537
|
const useRAG = projConfig?.semanticSearch?.enabled;
|
|
1478
1538
|
if (useRAG) {
|
|
1479
1539
|
try {
|
|
1480
|
-
const indexPath =
|
|
1540
|
+
const indexPath = path12.join(project.knowledgePath, "embeddings.json");
|
|
1481
1541
|
const rag = new RAGService(indexPath, projConfig?.semanticSearch?.model);
|
|
1482
1542
|
const ragResults = await rag.search(query, 5);
|
|
1483
1543
|
for (const r of ragResults) {
|
|
1484
1544
|
results.push({
|
|
1485
1545
|
project: project.name,
|
|
1486
|
-
file:
|
|
1546
|
+
file: path12.relative(project.knowledgePath, r.filePath),
|
|
1487
1547
|
matches: [r.content],
|
|
1488
1548
|
// The chunk content is the match
|
|
1489
1549
|
score: r.score
|
|
@@ -1494,11 +1554,11 @@ async function searchKnowledge(query) {
|
|
|
1494
1554
|
continue;
|
|
1495
1555
|
}
|
|
1496
1556
|
try {
|
|
1497
|
-
const files =
|
|
1557
|
+
const files = fs11.readdirSync(project.knowledgePath);
|
|
1498
1558
|
for (const file of files) {
|
|
1499
1559
|
if (!file.endsWith(".md")) continue;
|
|
1500
|
-
const filePath =
|
|
1501
|
-
const content =
|
|
1560
|
+
const filePath = path12.join(project.knowledgePath, file);
|
|
1561
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
1502
1562
|
const lines = content.split("\n");
|
|
1503
1563
|
const matches = [];
|
|
1504
1564
|
for (const line of lines) {
|
|
@@ -1533,18 +1593,18 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
1533
1593
|
if (!projConfig?.semanticSearch?.enabled) {
|
|
1534
1594
|
return { success: false, message: "Semantic Search is not enabled for this project", filesIndexed: 0 };
|
|
1535
1595
|
}
|
|
1536
|
-
if (!project.knowledgePath || !
|
|
1596
|
+
if (!project.knowledgePath || !fs11.existsSync(project.knowledgePath)) {
|
|
1537
1597
|
return { success: false, message: "No knowledge directory found", filesIndexed: 0 };
|
|
1538
1598
|
}
|
|
1539
1599
|
try {
|
|
1540
|
-
const indexPath =
|
|
1600
|
+
const indexPath = path12.join(project.knowledgePath, "embeddings.json");
|
|
1541
1601
|
const rag = new RAGService(indexPath, projConfig.semanticSearch.model);
|
|
1542
|
-
const files =
|
|
1602
|
+
const files = fs11.readdirSync(project.knowledgePath).filter((f) => f.endsWith(".md"));
|
|
1543
1603
|
let count = 0;
|
|
1544
1604
|
for (const file of files) {
|
|
1545
|
-
const filePath =
|
|
1546
|
-
const content =
|
|
1547
|
-
await rag.indexFile(
|
|
1605
|
+
const filePath = path12.join(project.knowledgePath, file);
|
|
1606
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
1607
|
+
await rag.indexFile(path12.join(project.knowledgePath, file), content);
|
|
1548
1608
|
count++;
|
|
1549
1609
|
}
|
|
1550
1610
|
return { success: true, message: `Successfully indexed ${count} files`, filesIndexed: count };
|
|
@@ -2046,8 +2106,8 @@ var init_server = __esm({
|
|
|
2046
2106
|
});
|
|
2047
2107
|
|
|
2048
2108
|
// src/mcp/install.ts
|
|
2049
|
-
import * as
|
|
2050
|
-
import * as
|
|
2109
|
+
import * as fs12 from "fs";
|
|
2110
|
+
import * as path13 from "path";
|
|
2051
2111
|
import * as os from "os";
|
|
2052
2112
|
function checkInstallStatus(workspacePath) {
|
|
2053
2113
|
return {
|
|
@@ -2058,37 +2118,37 @@ function checkInstallStatus(workspacePath) {
|
|
|
2058
2118
|
};
|
|
2059
2119
|
}
|
|
2060
2120
|
function checkAntigravityConfig() {
|
|
2061
|
-
if (!
|
|
2121
|
+
if (!fs12.existsSync(ANTIGRAVITY_CONFIG)) return false;
|
|
2062
2122
|
try {
|
|
2063
|
-
const content = JSON.parse(
|
|
2123
|
+
const content = JSON.parse(fs12.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
2064
2124
|
return !!content.mcpServers?.["rrce"];
|
|
2065
2125
|
} catch {
|
|
2066
2126
|
return false;
|
|
2067
2127
|
}
|
|
2068
2128
|
}
|
|
2069
2129
|
function checkClaudeConfig() {
|
|
2070
|
-
if (!
|
|
2130
|
+
if (!fs12.existsSync(CLAUDE_CONFIG)) return false;
|
|
2071
2131
|
try {
|
|
2072
|
-
const content = JSON.parse(
|
|
2132
|
+
const content = JSON.parse(fs12.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
2073
2133
|
return !!content.mcpServers?.["rrce"];
|
|
2074
2134
|
} catch {
|
|
2075
2135
|
return false;
|
|
2076
2136
|
}
|
|
2077
2137
|
}
|
|
2078
2138
|
function checkVSCodeGlobalConfig() {
|
|
2079
|
-
if (!
|
|
2139
|
+
if (!fs12.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
|
|
2080
2140
|
try {
|
|
2081
|
-
const content = JSON.parse(
|
|
2141
|
+
const content = JSON.parse(fs12.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
2082
2142
|
return !!content["mcp.servers"]?.["rrce"];
|
|
2083
2143
|
} catch {
|
|
2084
2144
|
return false;
|
|
2085
2145
|
}
|
|
2086
2146
|
}
|
|
2087
2147
|
function checkVSCodeWorkspaceConfig(workspacePath) {
|
|
2088
|
-
const configPath =
|
|
2089
|
-
if (!
|
|
2148
|
+
const configPath = path13.join(workspacePath, ".vscode", "mcp.json");
|
|
2149
|
+
if (!fs12.existsSync(configPath)) return false;
|
|
2090
2150
|
try {
|
|
2091
|
-
const content = JSON.parse(
|
|
2151
|
+
const content = JSON.parse(fs12.readFileSync(configPath, "utf-8"));
|
|
2092
2152
|
return !!content.servers?.["rrce"];
|
|
2093
2153
|
} catch {
|
|
2094
2154
|
return false;
|
|
@@ -2113,14 +2173,14 @@ function installToConfig(target, workspacePath) {
|
|
|
2113
2173
|
}
|
|
2114
2174
|
}
|
|
2115
2175
|
function installToAntigravity() {
|
|
2116
|
-
const dir =
|
|
2117
|
-
if (!
|
|
2118
|
-
|
|
2176
|
+
const dir = path13.dirname(ANTIGRAVITY_CONFIG);
|
|
2177
|
+
if (!fs12.existsSync(dir)) {
|
|
2178
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
2119
2179
|
}
|
|
2120
2180
|
let config = { mcpServers: {} };
|
|
2121
|
-
if (
|
|
2181
|
+
if (fs12.existsSync(ANTIGRAVITY_CONFIG)) {
|
|
2122
2182
|
try {
|
|
2123
|
-
config = JSON.parse(
|
|
2183
|
+
config = JSON.parse(fs12.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
2124
2184
|
} catch {
|
|
2125
2185
|
}
|
|
2126
2186
|
}
|
|
@@ -2130,21 +2190,21 @@ function installToAntigravity() {
|
|
|
2130
2190
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2131
2191
|
};
|
|
2132
2192
|
try {
|
|
2133
|
-
|
|
2193
|
+
fs12.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
|
|
2134
2194
|
return true;
|
|
2135
2195
|
} catch {
|
|
2136
2196
|
return false;
|
|
2137
2197
|
}
|
|
2138
2198
|
}
|
|
2139
2199
|
function installToClaude() {
|
|
2140
|
-
const dir =
|
|
2141
|
-
if (!
|
|
2142
|
-
|
|
2200
|
+
const dir = path13.dirname(CLAUDE_CONFIG);
|
|
2201
|
+
if (!fs12.existsSync(dir)) {
|
|
2202
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
2143
2203
|
}
|
|
2144
2204
|
let config = { mcpServers: {} };
|
|
2145
|
-
if (
|
|
2205
|
+
if (fs12.existsSync(CLAUDE_CONFIG)) {
|
|
2146
2206
|
try {
|
|
2147
|
-
config = JSON.parse(
|
|
2207
|
+
config = JSON.parse(fs12.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
2148
2208
|
} catch {
|
|
2149
2209
|
}
|
|
2150
2210
|
}
|
|
@@ -2154,21 +2214,21 @@ function installToClaude() {
|
|
|
2154
2214
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2155
2215
|
};
|
|
2156
2216
|
try {
|
|
2157
|
-
|
|
2217
|
+
fs12.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
|
|
2158
2218
|
return true;
|
|
2159
2219
|
} catch {
|
|
2160
2220
|
return false;
|
|
2161
2221
|
}
|
|
2162
2222
|
}
|
|
2163
2223
|
function installToVSCodeGlobal() {
|
|
2164
|
-
const dir =
|
|
2165
|
-
if (!
|
|
2166
|
-
|
|
2224
|
+
const dir = path13.dirname(VSCODE_GLOBAL_CONFIG);
|
|
2225
|
+
if (!fs12.existsSync(dir)) {
|
|
2226
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
2167
2227
|
}
|
|
2168
2228
|
let settings = {};
|
|
2169
|
-
if (
|
|
2229
|
+
if (fs12.existsSync(VSCODE_GLOBAL_CONFIG)) {
|
|
2170
2230
|
try {
|
|
2171
|
-
settings = JSON.parse(
|
|
2231
|
+
settings = JSON.parse(fs12.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
2172
2232
|
} catch {
|
|
2173
2233
|
}
|
|
2174
2234
|
}
|
|
@@ -2178,22 +2238,22 @@ function installToVSCodeGlobal() {
|
|
|
2178
2238
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2179
2239
|
};
|
|
2180
2240
|
try {
|
|
2181
|
-
|
|
2241
|
+
fs12.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
|
|
2182
2242
|
return true;
|
|
2183
2243
|
} catch {
|
|
2184
2244
|
return false;
|
|
2185
2245
|
}
|
|
2186
2246
|
}
|
|
2187
2247
|
function installToVSCodeWorkspace(workspacePath) {
|
|
2188
|
-
const vscodeDir =
|
|
2189
|
-
const configPath =
|
|
2190
|
-
if (!
|
|
2191
|
-
|
|
2248
|
+
const vscodeDir = path13.join(workspacePath, ".vscode");
|
|
2249
|
+
const configPath = path13.join(vscodeDir, "mcp.json");
|
|
2250
|
+
if (!fs12.existsSync(vscodeDir)) {
|
|
2251
|
+
fs12.mkdirSync(vscodeDir, { recursive: true });
|
|
2192
2252
|
}
|
|
2193
2253
|
let config = { servers: {} };
|
|
2194
|
-
if (
|
|
2254
|
+
if (fs12.existsSync(configPath)) {
|
|
2195
2255
|
try {
|
|
2196
|
-
config = JSON.parse(
|
|
2256
|
+
config = JSON.parse(fs12.readFileSync(configPath, "utf-8"));
|
|
2197
2257
|
} catch {
|
|
2198
2258
|
}
|
|
2199
2259
|
}
|
|
@@ -2203,7 +2263,7 @@ function installToVSCodeWorkspace(workspacePath) {
|
|
|
2203
2263
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2204
2264
|
};
|
|
2205
2265
|
try {
|
|
2206
|
-
|
|
2266
|
+
fs12.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
2207
2267
|
return true;
|
|
2208
2268
|
} catch {
|
|
2209
2269
|
return false;
|
|
@@ -2227,9 +2287,9 @@ var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG, VSCODE_GLOBAL_CONFIG;
|
|
|
2227
2287
|
var init_install = __esm({
|
|
2228
2288
|
"src/mcp/install.ts"() {
|
|
2229
2289
|
"use strict";
|
|
2230
|
-
ANTIGRAVITY_CONFIG =
|
|
2231
|
-
CLAUDE_CONFIG =
|
|
2232
|
-
VSCODE_GLOBAL_CONFIG =
|
|
2290
|
+
ANTIGRAVITY_CONFIG = path13.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
|
|
2291
|
+
CLAUDE_CONFIG = path13.join(os.homedir(), ".config/claude/claude_desktop_config.json");
|
|
2292
|
+
VSCODE_GLOBAL_CONFIG = path13.join(os.homedir(), ".config/Code/User/settings.json");
|
|
2233
2293
|
}
|
|
2234
2294
|
});
|
|
2235
2295
|
|
|
@@ -2314,8 +2374,8 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
2314
2374
|
}
|
|
2315
2375
|
async function handleConfigureGlobalPath() {
|
|
2316
2376
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
2317
|
-
const
|
|
2318
|
-
const
|
|
2377
|
+
const fs20 = await import("fs");
|
|
2378
|
+
const path18 = await import("path");
|
|
2319
2379
|
note2(
|
|
2320
2380
|
`MCP Hub requires a ${pc3.bold("global storage path")} to store its configuration
|
|
2321
2381
|
and coordinate across projects.
|
|
@@ -2329,8 +2389,8 @@ locally in each project. MCP needs a central location.`,
|
|
|
2329
2389
|
return false;
|
|
2330
2390
|
}
|
|
2331
2391
|
try {
|
|
2332
|
-
if (!
|
|
2333
|
-
|
|
2392
|
+
if (!fs20.existsSync(resolvedPath)) {
|
|
2393
|
+
fs20.mkdirSync(resolvedPath, { recursive: true });
|
|
2334
2394
|
}
|
|
2335
2395
|
const config = loadMCPConfig();
|
|
2336
2396
|
saveMCPConfig(config);
|
|
@@ -2338,7 +2398,7 @@ locally in each project. MCP needs a central location.`,
|
|
|
2338
2398
|
`${pc3.green("\u2713")} Global path configured: ${pc3.cyan(resolvedPath)}
|
|
2339
2399
|
|
|
2340
2400
|
MCP config will be stored at:
|
|
2341
|
-
${
|
|
2401
|
+
${path18.join(resolvedPath, "mcp.yaml")}`,
|
|
2342
2402
|
"Configuration Saved"
|
|
2343
2403
|
);
|
|
2344
2404
|
return true;
|
|
@@ -2815,7 +2875,7 @@ __export(App_exports, {
|
|
|
2815
2875
|
});
|
|
2816
2876
|
import { useState as useState4, useEffect as useEffect4 } from "react";
|
|
2817
2877
|
import { Box as Box10, useInput as useInput3, useApp } from "ink";
|
|
2818
|
-
import
|
|
2878
|
+
import fs13 from "fs";
|
|
2819
2879
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2820
2880
|
var TABS, App;
|
|
2821
2881
|
var init_App = __esm({
|
|
@@ -2884,18 +2944,18 @@ var init_App = __esm({
|
|
|
2884
2944
|
useEffect4(() => {
|
|
2885
2945
|
const logPath = getLogFilePath();
|
|
2886
2946
|
let lastSize = 0;
|
|
2887
|
-
if (
|
|
2888
|
-
const stats =
|
|
2947
|
+
if (fs13.existsSync(logPath)) {
|
|
2948
|
+
const stats = fs13.statSync(logPath);
|
|
2889
2949
|
lastSize = stats.size;
|
|
2890
2950
|
}
|
|
2891
2951
|
const interval = setInterval(() => {
|
|
2892
|
-
if (
|
|
2893
|
-
const stats =
|
|
2952
|
+
if (fs13.existsSync(logPath)) {
|
|
2953
|
+
const stats = fs13.statSync(logPath);
|
|
2894
2954
|
if (stats.size > lastSize) {
|
|
2895
2955
|
const buffer = Buffer.alloc(stats.size - lastSize);
|
|
2896
|
-
const fd =
|
|
2897
|
-
|
|
2898
|
-
|
|
2956
|
+
const fd = fs13.openSync(logPath, "r");
|
|
2957
|
+
fs13.readSync(fd, buffer, 0, buffer.length, lastSize);
|
|
2958
|
+
fs13.closeSync(fd);
|
|
2899
2959
|
const newContent = buffer.toString("utf-8");
|
|
2900
2960
|
const newLines = newContent.split("\n").filter((l) => l.trim());
|
|
2901
2961
|
setLogs((prev) => {
|
|
@@ -3229,8 +3289,8 @@ var init_mcp = __esm({
|
|
|
3229
3289
|
// src/commands/wizard/setup-flow.ts
|
|
3230
3290
|
import { group, select as select2, multiselect as multiselect3, confirm as confirm4, spinner as spinner3, note as note7, outro as outro2, cancel as cancel2, isCancel as isCancel6 } from "@clack/prompts";
|
|
3231
3291
|
import pc8 from "picocolors";
|
|
3232
|
-
import * as
|
|
3233
|
-
import * as
|
|
3292
|
+
import * as fs14 from "fs";
|
|
3293
|
+
import * as path14 from "path";
|
|
3234
3294
|
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
3235
3295
|
const s = spinner3();
|
|
3236
3296
|
const config = await group(
|
|
@@ -3279,7 +3339,21 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
3279
3339
|
exposeToMCP: () => confirm4({
|
|
3280
3340
|
message: "Expose this project to MCP (AI Agent) server?",
|
|
3281
3341
|
initialValue: true
|
|
3282
|
-
})
|
|
3342
|
+
}),
|
|
3343
|
+
enableRAG: () => confirm4({
|
|
3344
|
+
message: "Enable Semantic Search (Local Mini RAG)?",
|
|
3345
|
+
initialValue: false
|
|
3346
|
+
// Default false because it's heavy
|
|
3347
|
+
}),
|
|
3348
|
+
enableRAGConfirm: ({ results }) => {
|
|
3349
|
+
if (results.enableRAG) {
|
|
3350
|
+
return confirm4({
|
|
3351
|
+
message: `${pc8.yellow("Warning:")} This will download a ~100MB model (Xenova/all-MiniLM-L6-v2) on first use. Proceed?`,
|
|
3352
|
+
initialValue: true
|
|
3353
|
+
});
|
|
3354
|
+
}
|
|
3355
|
+
return Promise.resolve(true);
|
|
3356
|
+
}
|
|
3283
3357
|
},
|
|
3284
3358
|
{
|
|
3285
3359
|
onCancel: () => {
|
|
@@ -3300,6 +3374,22 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
3300
3374
|
process.exit(1);
|
|
3301
3375
|
}
|
|
3302
3376
|
}
|
|
3377
|
+
if (config.storageMode === "global") {
|
|
3378
|
+
const targetGlobalPath = path14.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
|
|
3379
|
+
if (fs14.existsSync(targetGlobalPath)) {
|
|
3380
|
+
const overwriteAction = await select2({
|
|
3381
|
+
message: `Project '${workspaceName}' already exists globally.`,
|
|
3382
|
+
options: [
|
|
3383
|
+
{ value: "overwrite", label: "Overwrite existing project", hint: "Will replace global config" },
|
|
3384
|
+
{ value: "cancel", label: "Cancel setup" }
|
|
3385
|
+
]
|
|
3386
|
+
});
|
|
3387
|
+
if (isCancel6(overwriteAction) || overwriteAction === "cancel") {
|
|
3388
|
+
cancel2("Setup cancelled.");
|
|
3389
|
+
process.exit(0);
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3303
3393
|
s.start("Generating configuration");
|
|
3304
3394
|
try {
|
|
3305
3395
|
await generateConfiguration({
|
|
@@ -3308,7 +3398,8 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
3308
3398
|
tools: config.tools,
|
|
3309
3399
|
linkedProjects: config.linkedProjects,
|
|
3310
3400
|
addToGitignore: config.addToGitignore,
|
|
3311
|
-
exposeToMCP: config.exposeToMCP
|
|
3401
|
+
exposeToMCP: config.exposeToMCP,
|
|
3402
|
+
enableRAG: config.enableRAG && config.enableRAGConfirm
|
|
3312
3403
|
}, workspacePath, workspaceName, existingProjects);
|
|
3313
3404
|
s.stop("Configuration generated");
|
|
3314
3405
|
const dataPaths = getDataPaths(
|
|
@@ -3370,27 +3461,29 @@ async function generateConfiguration(config, workspacePath, workspaceName, allPr
|
|
|
3370
3461
|
const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
3371
3462
|
for (const dataPath of dataPaths) {
|
|
3372
3463
|
ensureDir(dataPath);
|
|
3373
|
-
ensureDir(
|
|
3374
|
-
ensureDir(
|
|
3375
|
-
ensureDir(
|
|
3376
|
-
ensureDir(
|
|
3464
|
+
ensureDir(path14.join(dataPath, "knowledge"));
|
|
3465
|
+
ensureDir(path14.join(dataPath, "refs"));
|
|
3466
|
+
ensureDir(path14.join(dataPath, "tasks"));
|
|
3467
|
+
ensureDir(path14.join(dataPath, "templates"));
|
|
3377
3468
|
}
|
|
3378
3469
|
const agentCoreDir = getAgentCoreDir();
|
|
3379
3470
|
syncMetadataToAll(agentCoreDir, dataPaths);
|
|
3380
|
-
copyDirToAllStoragePaths(
|
|
3471
|
+
copyDirToAllStoragePaths(path14.join(agentCoreDir, "templates"), "templates", dataPaths);
|
|
3381
3472
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
3382
|
-
if (config.
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3473
|
+
if (config.storageMode === "workspace") {
|
|
3474
|
+
if (config.tools.includes("copilot")) {
|
|
3475
|
+
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
3476
|
+
ensureDir(copilotPath);
|
|
3477
|
+
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
3478
|
+
}
|
|
3479
|
+
if (config.tools.includes("antigravity")) {
|
|
3480
|
+
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
3481
|
+
ensureDir(antigravityPath);
|
|
3482
|
+
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
const workspaceConfigPath = path14.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
3486
|
+
ensureDir(path14.dirname(workspaceConfigPath));
|
|
3394
3487
|
let configContent = `# RRCE-Workflow Configuration
|
|
3395
3488
|
version: 1
|
|
3396
3489
|
|
|
@@ -3418,7 +3511,7 @@ linked_projects:
|
|
|
3418
3511
|
`;
|
|
3419
3512
|
});
|
|
3420
3513
|
}
|
|
3421
|
-
|
|
3514
|
+
fs14.writeFileSync(workspaceConfigPath, configContent);
|
|
3422
3515
|
if (config.addToGitignore) {
|
|
3423
3516
|
updateGitignore(workspacePath, config.storageMode, config.tools);
|
|
3424
3517
|
}
|
|
@@ -3435,10 +3528,30 @@ linked_projects:
|
|
|
3435
3528
|
const mcpConfig = loadMCPConfig3();
|
|
3436
3529
|
const currentProjectName = workspaceName;
|
|
3437
3530
|
if (config.storageMode === "workspace") {
|
|
3438
|
-
setProjectConfig2(
|
|
3531
|
+
setProjectConfig2(
|
|
3532
|
+
mcpConfig,
|
|
3533
|
+
currentProjectName,
|
|
3534
|
+
true,
|
|
3535
|
+
void 0,
|
|
3536
|
+
// permissions
|
|
3537
|
+
void 0,
|
|
3538
|
+
// path
|
|
3539
|
+
config.enableRAG ? { enabled: true } : void 0
|
|
3540
|
+
// semanticSearch
|
|
3541
|
+
);
|
|
3439
3542
|
saveMCPConfig2(mcpConfig);
|
|
3440
3543
|
} else {
|
|
3441
|
-
setProjectConfig2(
|
|
3544
|
+
setProjectConfig2(
|
|
3545
|
+
mcpConfig,
|
|
3546
|
+
currentProjectName,
|
|
3547
|
+
true,
|
|
3548
|
+
void 0,
|
|
3549
|
+
// permissions
|
|
3550
|
+
void 0,
|
|
3551
|
+
// path
|
|
3552
|
+
config.enableRAG ? { enabled: true } : void 0
|
|
3553
|
+
// semanticSearch
|
|
3554
|
+
);
|
|
3442
3555
|
saveMCPConfig2(mcpConfig);
|
|
3443
3556
|
}
|
|
3444
3557
|
} catch (e) {
|
|
@@ -3447,8 +3560,8 @@ linked_projects:
|
|
|
3447
3560
|
}
|
|
3448
3561
|
}
|
|
3449
3562
|
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
3450
|
-
const globalPath =
|
|
3451
|
-
const workspacePath =
|
|
3563
|
+
const globalPath = path14.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
|
|
3564
|
+
const workspacePath = path14.join(workspaceRoot, ".rrce-workflow");
|
|
3452
3565
|
switch (mode) {
|
|
3453
3566
|
case "global":
|
|
3454
3567
|
return [globalPath];
|
|
@@ -3459,7 +3572,7 @@ function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
|
3459
3572
|
}
|
|
3460
3573
|
}
|
|
3461
3574
|
function updateGitignore(workspacePath, storageMode, tools) {
|
|
3462
|
-
const gitignorePath =
|
|
3575
|
+
const gitignorePath = path14.join(workspacePath, ".gitignore");
|
|
3463
3576
|
const entries = [];
|
|
3464
3577
|
if (storageMode === "workspace") {
|
|
3465
3578
|
entries.push(".rrce-workflow/");
|
|
@@ -3475,8 +3588,8 @@ function updateGitignore(workspacePath, storageMode, tools) {
|
|
|
3475
3588
|
}
|
|
3476
3589
|
try {
|
|
3477
3590
|
let content = "";
|
|
3478
|
-
if (
|
|
3479
|
-
content =
|
|
3591
|
+
if (fs14.existsSync(gitignorePath)) {
|
|
3592
|
+
content = fs14.readFileSync(gitignorePath, "utf-8");
|
|
3480
3593
|
}
|
|
3481
3594
|
const lines = content.split("\n").map((line) => line.trim());
|
|
3482
3595
|
const newEntries = [];
|
|
@@ -3501,7 +3614,7 @@ function updateGitignore(workspacePath, storageMode, tools) {
|
|
|
3501
3614
|
newContent += "\n# rrce-workflow generated folders (uncomment to ignore)\n";
|
|
3502
3615
|
}
|
|
3503
3616
|
newContent += newEntries.map((e) => `# ${e}`).join("\n") + "\n";
|
|
3504
|
-
|
|
3617
|
+
fs14.writeFileSync(gitignorePath, newContent);
|
|
3505
3618
|
return true;
|
|
3506
3619
|
} catch {
|
|
3507
3620
|
return false;
|
|
@@ -3522,7 +3635,7 @@ var init_setup_flow = __esm({
|
|
|
3522
3635
|
// src/commands/wizard/link-flow.ts
|
|
3523
3636
|
import { multiselect as multiselect4, spinner as spinner4, note as note8, outro as outro3, cancel as cancel3, isCancel as isCancel7, confirm as confirm5 } from "@clack/prompts";
|
|
3524
3637
|
import pc9 from "picocolors";
|
|
3525
|
-
import * as
|
|
3638
|
+
import * as fs15 from "fs";
|
|
3526
3639
|
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
3527
3640
|
const projects = scanForProjects({
|
|
3528
3641
|
excludeWorkspace: workspaceName,
|
|
@@ -3560,7 +3673,7 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
3560
3673
|
const s = spinner4();
|
|
3561
3674
|
s.start("Linking projects");
|
|
3562
3675
|
const configFilePath = getConfigPath(workspacePath);
|
|
3563
|
-
let configContent =
|
|
3676
|
+
let configContent = fs15.readFileSync(configFilePath, "utf-8");
|
|
3564
3677
|
if (configContent.includes("linked_projects:")) {
|
|
3565
3678
|
const lines = configContent.split("\n");
|
|
3566
3679
|
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
@@ -3587,7 +3700,7 @@ linked_projects:
|
|
|
3587
3700
|
`;
|
|
3588
3701
|
});
|
|
3589
3702
|
}
|
|
3590
|
-
|
|
3703
|
+
fs15.writeFileSync(configFilePath, configContent);
|
|
3591
3704
|
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
3592
3705
|
s.stop("Projects linked");
|
|
3593
3706
|
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
@@ -3629,15 +3742,15 @@ var init_link_flow = __esm({
|
|
|
3629
3742
|
// src/commands/wizard/sync-flow.ts
|
|
3630
3743
|
import { confirm as confirm6, spinner as spinner5, note as note9, outro as outro4, cancel as cancel4, isCancel as isCancel8 } from "@clack/prompts";
|
|
3631
3744
|
import pc10 from "picocolors";
|
|
3632
|
-
import * as
|
|
3633
|
-
import * as
|
|
3745
|
+
import * as fs16 from "fs";
|
|
3746
|
+
import * as path15 from "path";
|
|
3634
3747
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
3635
3748
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
3636
3749
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
3637
|
-
const globalPath =
|
|
3750
|
+
const globalPath = path15.join(customGlobalPath, "workspaces", workspaceName);
|
|
3638
3751
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
3639
3752
|
const existingDirs = subdirs.filter(
|
|
3640
|
-
(dir) =>
|
|
3753
|
+
(dir) => fs16.existsSync(path15.join(localPath, dir))
|
|
3641
3754
|
);
|
|
3642
3755
|
if (existingDirs.length === 0) {
|
|
3643
3756
|
outro4(pc10.yellow("No data found in workspace storage to sync."));
|
|
@@ -3663,8 +3776,8 @@ Destination: ${pc10.cyan(globalPath)}`,
|
|
|
3663
3776
|
try {
|
|
3664
3777
|
ensureDir(globalPath);
|
|
3665
3778
|
for (const dir of existingDirs) {
|
|
3666
|
-
const srcDir =
|
|
3667
|
-
const destDir =
|
|
3779
|
+
const srcDir = path15.join(localPath, dir);
|
|
3780
|
+
const destDir = path15.join(globalPath, dir);
|
|
3668
3781
|
ensureDir(destDir);
|
|
3669
3782
|
copyDirRecursive(srcDir, destDir);
|
|
3670
3783
|
}
|
|
@@ -3696,8 +3809,8 @@ var init_sync_flow = __esm({
|
|
|
3696
3809
|
// src/commands/wizard/update-flow.ts
|
|
3697
3810
|
import { confirm as confirm7, spinner as spinner6, note as note10, outro as outro5, cancel as cancel5, isCancel as isCancel9 } from "@clack/prompts";
|
|
3698
3811
|
import pc11 from "picocolors";
|
|
3699
|
-
import * as
|
|
3700
|
-
import * as
|
|
3812
|
+
import * as fs17 from "fs";
|
|
3813
|
+
import * as path16 from "path";
|
|
3701
3814
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
3702
3815
|
const s = spinner6();
|
|
3703
3816
|
s.start("Checking for updates");
|
|
@@ -3727,10 +3840,10 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
3727
3840
|
}
|
|
3728
3841
|
s.start("Updating from package");
|
|
3729
3842
|
for (const dataPath of dataPaths) {
|
|
3730
|
-
copyDirToAllStoragePaths(
|
|
3843
|
+
copyDirToAllStoragePaths(path16.join(agentCoreDir, "templates"), "templates", [dataPath]);
|
|
3731
3844
|
}
|
|
3732
3845
|
const configFilePath = getConfigPath(workspacePath);
|
|
3733
|
-
const configContent =
|
|
3846
|
+
const configContent = fs17.readFileSync(configFilePath, "utf-8");
|
|
3734
3847
|
if (configContent.includes("copilot: true")) {
|
|
3735
3848
|
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
3736
3849
|
ensureDir(copilotPath);
|
|
@@ -3758,8 +3871,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
3758
3871
|
}
|
|
3759
3872
|
}
|
|
3760
3873
|
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
3761
|
-
const globalPath =
|
|
3762
|
-
const workspacePath =
|
|
3874
|
+
const globalPath = path16.join(customGlobalPath, "workspaces", workspaceName);
|
|
3875
|
+
const workspacePath = path16.join(workspaceRoot, ".rrce-workflow");
|
|
3763
3876
|
switch (mode) {
|
|
3764
3877
|
case "global":
|
|
3765
3878
|
return [globalPath];
|
|
@@ -3778,26 +3891,103 @@ var init_update_flow = __esm({
|
|
|
3778
3891
|
}
|
|
3779
3892
|
});
|
|
3780
3893
|
|
|
3894
|
+
// src/commands/wizard/delete-flow.ts
|
|
3895
|
+
import { multiselect as multiselect5, confirm as confirm8, spinner as spinner7, note as note11, cancel as cancel6, isCancel as isCancel10 } from "@clack/prompts";
|
|
3896
|
+
import pc12 from "picocolors";
|
|
3897
|
+
import * as fs18 from "fs";
|
|
3898
|
+
async function runDeleteGlobalProjectFlow(availableProjects) {
|
|
3899
|
+
const globalProjects = availableProjects.filter((p) => p.source === "global");
|
|
3900
|
+
if (globalProjects.length === 0) {
|
|
3901
|
+
note11("No globally stored projects found to delete.", "Info");
|
|
3902
|
+
return;
|
|
3903
|
+
}
|
|
3904
|
+
const selectedProjects = await multiselect5({
|
|
3905
|
+
message: "Select global projects to DELETE (Irreversible)",
|
|
3906
|
+
options: globalProjects.map((p) => ({
|
|
3907
|
+
value: p.name,
|
|
3908
|
+
label: p.name,
|
|
3909
|
+
hint: p.dataPath
|
|
3910
|
+
})),
|
|
3911
|
+
required: false
|
|
3912
|
+
});
|
|
3913
|
+
if (isCancel10(selectedProjects)) {
|
|
3914
|
+
cancel6("Deletion cancelled.");
|
|
3915
|
+
return;
|
|
3916
|
+
}
|
|
3917
|
+
const projectsToDelete = selectedProjects;
|
|
3918
|
+
if (projectsToDelete.length === 0) {
|
|
3919
|
+
note11("No projects selected.", "Cancelled");
|
|
3920
|
+
return;
|
|
3921
|
+
}
|
|
3922
|
+
const confirmed = await confirm8({
|
|
3923
|
+
message: `${pc12.red("WARNING:")} This will PERMANENTLY DELETE the knowledge/config for ${projectsToDelete.length} detected global projects.
|
|
3924
|
+
Are you sure?`,
|
|
3925
|
+
initialValue: false
|
|
3926
|
+
});
|
|
3927
|
+
if (!confirmed || isCancel10(confirmed)) {
|
|
3928
|
+
cancel6("Deletion cancelled.");
|
|
3929
|
+
return;
|
|
3930
|
+
}
|
|
3931
|
+
const s = spinner7();
|
|
3932
|
+
s.start("Deleting projects...");
|
|
3933
|
+
try {
|
|
3934
|
+
const mcpConfig = loadMCPConfig();
|
|
3935
|
+
let configChanged = false;
|
|
3936
|
+
for (const projectName of projectsToDelete) {
|
|
3937
|
+
const project = globalProjects.find((p) => p.name === projectName);
|
|
3938
|
+
if (!project) continue;
|
|
3939
|
+
if (fs18.existsSync(project.dataPath)) {
|
|
3940
|
+
fs18.rmSync(project.dataPath, { recursive: true, force: true });
|
|
3941
|
+
}
|
|
3942
|
+
const newConfig = removeProjectConfig(mcpConfig, projectName);
|
|
3943
|
+
configChanged = true;
|
|
3944
|
+
}
|
|
3945
|
+
if (configChanged) {
|
|
3946
|
+
saveMCPConfig(mcpConfig);
|
|
3947
|
+
}
|
|
3948
|
+
s.stop(`Successfully deleted ${projectsToDelete.length} projects.`);
|
|
3949
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
3950
|
+
} catch (error) {
|
|
3951
|
+
s.stop("Error occurred during deletion");
|
|
3952
|
+
note11(`Failed to delete some projects: ${error}`, "Error");
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
var init_delete_flow = __esm({
|
|
3956
|
+
"src/commands/wizard/delete-flow.ts"() {
|
|
3957
|
+
"use strict";
|
|
3958
|
+
init_detection();
|
|
3959
|
+
init_config();
|
|
3960
|
+
}
|
|
3961
|
+
});
|
|
3962
|
+
|
|
3781
3963
|
// src/commands/wizard/index.ts
|
|
3782
3964
|
var wizard_exports = {};
|
|
3783
3965
|
__export(wizard_exports, {
|
|
3784
3966
|
runWizard: () => runWizard
|
|
3785
3967
|
});
|
|
3786
|
-
import { intro as intro2, select as
|
|
3787
|
-
import
|
|
3788
|
-
import * as
|
|
3968
|
+
import { intro as intro2, select as select4, spinner as spinner8, note as note12, outro as outro7, isCancel as isCancel11 } from "@clack/prompts";
|
|
3969
|
+
import pc13 from "picocolors";
|
|
3970
|
+
import * as fs19 from "fs";
|
|
3789
3971
|
async function runWizard() {
|
|
3790
|
-
intro2(
|
|
3791
|
-
const s =
|
|
3972
|
+
intro2(pc13.cyan(pc13.inverse(" RRCE-Workflow Setup ")));
|
|
3973
|
+
const s = spinner8();
|
|
3792
3974
|
s.start("Detecting environment");
|
|
3793
3975
|
const workspacePath = detectWorkspaceRoot();
|
|
3794
3976
|
const workspaceName = getWorkspaceName(workspacePath);
|
|
3795
3977
|
const gitUser = getGitUser();
|
|
3978
|
+
try {
|
|
3979
|
+
const mcpConfig = loadMCPConfig();
|
|
3980
|
+
const { config: cleanConfig, removed } = cleanStaleProjects(mcpConfig);
|
|
3981
|
+
if (removed.length > 0) {
|
|
3982
|
+
saveMCPConfig(cleanConfig);
|
|
3983
|
+
}
|
|
3984
|
+
} catch (e) {
|
|
3985
|
+
}
|
|
3796
3986
|
await new Promise((r) => setTimeout(r, 800));
|
|
3797
3987
|
s.stop("Environment detected");
|
|
3798
|
-
|
|
3799
|
-
`Git User: ${
|
|
3800
|
-
Workspace: ${
|
|
3988
|
+
note12(
|
|
3989
|
+
`Git User: ${pc13.bold(gitUser || "(not found)")}
|
|
3990
|
+
Workspace: ${pc13.bold(workspaceName)}`,
|
|
3801
3991
|
"Context"
|
|
3802
3992
|
);
|
|
3803
3993
|
const detectedProjects = scanForProjects({
|
|
@@ -3805,18 +3995,18 @@ Workspace: ${pc12.bold(workspaceName)}`,
|
|
|
3805
3995
|
workspacePath
|
|
3806
3996
|
});
|
|
3807
3997
|
const configFilePath = getConfigPath(workspacePath);
|
|
3808
|
-
const isAlreadyConfigured =
|
|
3998
|
+
const isAlreadyConfigured = fs19.existsSync(configFilePath);
|
|
3809
3999
|
let currentStorageMode = null;
|
|
3810
4000
|
if (isAlreadyConfigured) {
|
|
3811
4001
|
try {
|
|
3812
|
-
const configContent =
|
|
4002
|
+
const configContent = fs19.readFileSync(configFilePath, "utf-8");
|
|
3813
4003
|
const modeMatch = configContent.match(/mode:\s*(global|workspace)/);
|
|
3814
4004
|
currentStorageMode = modeMatch?.[1] ?? null;
|
|
3815
4005
|
} catch {
|
|
3816
4006
|
}
|
|
3817
4007
|
}
|
|
3818
4008
|
const localDataPath = getLocalWorkspacePath(workspacePath);
|
|
3819
|
-
const hasLocalData =
|
|
4009
|
+
const hasLocalData = fs19.existsSync(localDataPath);
|
|
3820
4010
|
if (isAlreadyConfigured) {
|
|
3821
4011
|
const menuOptions = [];
|
|
3822
4012
|
menuOptions.push({
|
|
@@ -3824,6 +4014,13 @@ Workspace: ${pc12.bold(workspaceName)}`,
|
|
|
3824
4014
|
label: "\u{1F50C} Configure MCP Server",
|
|
3825
4015
|
hint: "Expose projects to AI assistants (VSCode, Antigravity, Claude)"
|
|
3826
4016
|
});
|
|
4017
|
+
if (detectedProjects.some((p) => p.source === "global")) {
|
|
4018
|
+
menuOptions.push({
|
|
4019
|
+
value: "delete-global",
|
|
4020
|
+
label: "\u{1F5D1}\uFE0F Delete global project(s)",
|
|
4021
|
+
hint: "Remove knowledge and configuration"
|
|
4022
|
+
});
|
|
4023
|
+
}
|
|
3827
4024
|
if (detectedProjects.length > 0) {
|
|
3828
4025
|
menuOptions.push({
|
|
3829
4026
|
value: "link",
|
|
@@ -3841,18 +4038,22 @@ Workspace: ${pc12.bold(workspaceName)}`,
|
|
|
3841
4038
|
menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
|
|
3842
4039
|
menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
|
|
3843
4040
|
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
3844
|
-
const action = await
|
|
4041
|
+
const action = await select4({
|
|
3845
4042
|
message: "This workspace is already configured. What would you like to do?",
|
|
3846
4043
|
options: menuOptions
|
|
3847
4044
|
});
|
|
3848
|
-
if (
|
|
3849
|
-
|
|
4045
|
+
if (isCancel11(action) || action === "exit") {
|
|
4046
|
+
outro7("Exited.");
|
|
3850
4047
|
process.exit(0);
|
|
3851
4048
|
}
|
|
3852
4049
|
if (action === "mcp") {
|
|
3853
4050
|
await runMCP();
|
|
3854
4051
|
return;
|
|
3855
4052
|
}
|
|
4053
|
+
if (action === "delete-global") {
|
|
4054
|
+
await runDeleteGlobalProjectFlow(detectedProjects);
|
|
4055
|
+
return;
|
|
4056
|
+
}
|
|
3856
4057
|
if (action === "link") {
|
|
3857
4058
|
await runLinkProjectsFlow(workspacePath, workspaceName);
|
|
3858
4059
|
return;
|
|
@@ -3880,7 +4081,9 @@ var init_wizard = __esm({
|
|
|
3880
4081
|
init_link_flow();
|
|
3881
4082
|
init_sync_flow();
|
|
3882
4083
|
init_update_flow();
|
|
4084
|
+
init_delete_flow();
|
|
3883
4085
|
init_mcp();
|
|
4086
|
+
init_config();
|
|
3884
4087
|
}
|
|
3885
4088
|
});
|
|
3886
4089
|
|
|
@@ -3889,18 +4092,18 @@ init_wizard();
|
|
|
3889
4092
|
|
|
3890
4093
|
// src/commands/selector.ts
|
|
3891
4094
|
init_prompts();
|
|
3892
|
-
import { intro as intro3, select as
|
|
3893
|
-
import
|
|
3894
|
-
import * as
|
|
4095
|
+
import { intro as intro3, select as select5, note as note13, cancel as cancel8, isCancel as isCancel12, outro as outro8 } from "@clack/prompts";
|
|
4096
|
+
import pc14 from "picocolors";
|
|
4097
|
+
import * as path17 from "path";
|
|
3895
4098
|
async function runSelector() {
|
|
3896
|
-
const workspaceName =
|
|
3897
|
-
intro3(
|
|
4099
|
+
const workspaceName = path17.basename(process.cwd());
|
|
4100
|
+
intro3(pc14.cyan(pc14.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
3898
4101
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
3899
4102
|
if (prompts.length === 0) {
|
|
3900
|
-
|
|
4103
|
+
cancel8("No agents found. Run `rrce-workflow` to set up.");
|
|
3901
4104
|
process.exit(0);
|
|
3902
4105
|
}
|
|
3903
|
-
const selection = await
|
|
4106
|
+
const selection = await select5({
|
|
3904
4107
|
message: "Select an agent:",
|
|
3905
4108
|
options: [
|
|
3906
4109
|
{
|
|
@@ -3920,8 +4123,8 @@ async function runSelector() {
|
|
|
3920
4123
|
}))
|
|
3921
4124
|
]
|
|
3922
4125
|
});
|
|
3923
|
-
if (
|
|
3924
|
-
|
|
4126
|
+
if (isCancel12(selection)) {
|
|
4127
|
+
cancel8("Selection cancelled.");
|
|
3925
4128
|
process.exit(0);
|
|
3926
4129
|
}
|
|
3927
4130
|
if (selection === "mcp") {
|
|
@@ -3935,12 +4138,12 @@ async function runSelector() {
|
|
|
3935
4138
|
return;
|
|
3936
4139
|
}
|
|
3937
4140
|
const prompt = selection;
|
|
3938
|
-
|
|
4141
|
+
note13(
|
|
3939
4142
|
`Use this agent in your IDE by invoking:
|
|
3940
|
-
${
|
|
4143
|
+
${pc14.bold(pc14.cyan(`@${prompt.frontmatter.name}`))}`,
|
|
3941
4144
|
"Agent Selected"
|
|
3942
4145
|
);
|
|
3943
|
-
|
|
4146
|
+
outro8("Done");
|
|
3944
4147
|
}
|
|
3945
4148
|
|
|
3946
4149
|
// src/index.ts
|