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.
Files changed (2) hide show
  1. package/dist/index.js +383 -180
  2. 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 path7 from "path";
747
+ import * as path8 from "path";
716
748
  async function resolveGlobalPath() {
717
- const defaultPath = getDefaultRRCEHome();
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 = path7.join(process.env.HOME || "~", ".local", "share", "rrce-workflow");
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 = path7.join(expandedPath, ".rrce-workflow");
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 fs7 from "fs";
825
- import * as path8 from "path";
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 path8.join(rrceHome, "mcp.yaml");
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 = path8.join(workspaceRoot, ".rrce-workflow", "config.yaml");
836
- if (fs7.existsSync(configPath)) {
837
- const content = fs7.readFileSync(configPath, "utf-8");
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 (!fs7.existsSync(configPath)) {
891
+ if (!fs8.existsSync(configPath)) {
856
892
  return { ...DEFAULT_MCP_CONFIG };
857
893
  }
858
894
  try {
859
- const content = fs7.readFileSync(configPath, "utf-8");
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 = path8.dirname(configPath);
868
- if (!fs7.existsSync(dir)) {
869
- fs7.mkdirSync(dir, { recursive: true });
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
- fs7.writeFileSync(configPath, content);
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 fs8 from "fs";
1101
- import * as path9 from "path";
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 path9.join(rrceHome, "mcp-server.log");
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 = path9.dirname(this.logPath);
1137
- if (!fs8.existsSync(dir)) {
1138
- fs8.mkdirSync(dir, { recursive: true });
1196
+ const dir = path10.dirname(this.logPath);
1197
+ if (!fs9.existsSync(dir)) {
1198
+ fs9.mkdirSync(dir, { recursive: true });
1139
1199
  }
1140
- fs8.appendFileSync(this.logPath, logMessage);
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 fs9 from "fs";
1165
- import * as path10 from "path";
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 (fs9.existsSync(this.indexPath)) {
1266
+ if (fs10.existsSync(this.indexPath)) {
1207
1267
  try {
1208
- const data = fs9.readFileSync(this.indexPath, "utf-8");
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 = path10.dirname(this.indexPath);
1235
- if (!fs9.existsSync(dir)) {
1236
- fs9.mkdirSync(dir, { recursive: true });
1294
+ const dir = path11.dirname(this.indexPath);
1295
+ if (!fs10.existsSync(dir)) {
1296
+ fs10.mkdirSync(dir, { recursive: true });
1237
1297
  }
1238
- fs9.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2));
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 fs10 from "fs";
1355
- import * as path11 from "path";
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 = path11.join(activeProject.dataPath, "config.yaml");
1423
+ const localConfigPath = path12.join(activeProject.dataPath, "config.yaml");
1364
1424
  let cfgContent = null;
1365
- if (fs10.existsSync(path11.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
1366
- cfgContent = fs10.readFileSync(path11.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
1367
- } else if (fs10.existsSync(path11.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
1368
- cfgContent = fs10.readFileSync(path11.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
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 = path11.join(project.knowledgePath, "project-context.md");
1429
- if (!fs10.existsSync(contextPath)) {
1488
+ const contextPath = path12.join(project.knowledgePath, "project-context.md");
1489
+ if (!fs11.existsSync(contextPath)) {
1430
1490
  return null;
1431
1491
  }
1432
- return fs10.readFileSync(contextPath, "utf-8");
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 || !fs10.existsSync(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 = fs10.readdirSync(project.tasksPath, { withFileTypes: true });
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 = path11.join(project.tasksPath, dir.name, "meta.json");
1454
- if (fs10.existsSync(metaPath)) {
1513
+ const metaPath = path12.join(project.tasksPath, dir.name, "meta.json");
1514
+ if (fs11.existsSync(metaPath)) {
1455
1515
  try {
1456
- const meta = JSON.parse(fs10.readFileSync(metaPath, "utf-8"));
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 = path11.join(project.knowledgePath, "embeddings.json");
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: path11.relative(project.knowledgePath, r.filePath),
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 = fs10.readdirSync(project.knowledgePath);
1557
+ const files = fs11.readdirSync(project.knowledgePath);
1498
1558
  for (const file of files) {
1499
1559
  if (!file.endsWith(".md")) continue;
1500
- const filePath = path11.join(project.knowledgePath, file);
1501
- const content = fs10.readFileSync(filePath, "utf-8");
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 || !fs10.existsSync(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 = path11.join(project.knowledgePath, "embeddings.json");
1600
+ const indexPath = path12.join(project.knowledgePath, "embeddings.json");
1541
1601
  const rag = new RAGService(indexPath, projConfig.semanticSearch.model);
1542
- const files = fs10.readdirSync(project.knowledgePath).filter((f) => f.endsWith(".md"));
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 = path11.join(project.knowledgePath, file);
1546
- const content = fs10.readFileSync(filePath, "utf-8");
1547
- await rag.indexFile(path11.join(project.knowledgePath, file), content);
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 fs11 from "fs";
2050
- import * as path12 from "path";
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 (!fs11.existsSync(ANTIGRAVITY_CONFIG)) return false;
2121
+ if (!fs12.existsSync(ANTIGRAVITY_CONFIG)) return false;
2062
2122
  try {
2063
- const content = JSON.parse(fs11.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
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 (!fs11.existsSync(CLAUDE_CONFIG)) return false;
2130
+ if (!fs12.existsSync(CLAUDE_CONFIG)) return false;
2071
2131
  try {
2072
- const content = JSON.parse(fs11.readFileSync(CLAUDE_CONFIG, "utf-8"));
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 (!fs11.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
2139
+ if (!fs12.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
2080
2140
  try {
2081
- const content = JSON.parse(fs11.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
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 = path12.join(workspacePath, ".vscode", "mcp.json");
2089
- if (!fs11.existsSync(configPath)) return false;
2148
+ const configPath = path13.join(workspacePath, ".vscode", "mcp.json");
2149
+ if (!fs12.existsSync(configPath)) return false;
2090
2150
  try {
2091
- const content = JSON.parse(fs11.readFileSync(configPath, "utf-8"));
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 = path12.dirname(ANTIGRAVITY_CONFIG);
2117
- if (!fs11.existsSync(dir)) {
2118
- fs11.mkdirSync(dir, { recursive: true });
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 (fs11.existsSync(ANTIGRAVITY_CONFIG)) {
2181
+ if (fs12.existsSync(ANTIGRAVITY_CONFIG)) {
2122
2182
  try {
2123
- config = JSON.parse(fs11.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
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
- fs11.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
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 = path12.dirname(CLAUDE_CONFIG);
2141
- if (!fs11.existsSync(dir)) {
2142
- fs11.mkdirSync(dir, { recursive: true });
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 (fs11.existsSync(CLAUDE_CONFIG)) {
2205
+ if (fs12.existsSync(CLAUDE_CONFIG)) {
2146
2206
  try {
2147
- config = JSON.parse(fs11.readFileSync(CLAUDE_CONFIG, "utf-8"));
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
- fs11.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
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 = path12.dirname(VSCODE_GLOBAL_CONFIG);
2165
- if (!fs11.existsSync(dir)) {
2166
- fs11.mkdirSync(dir, { recursive: true });
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 (fs11.existsSync(VSCODE_GLOBAL_CONFIG)) {
2229
+ if (fs12.existsSync(VSCODE_GLOBAL_CONFIG)) {
2170
2230
  try {
2171
- settings = JSON.parse(fs11.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
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
- fs11.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
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 = path12.join(workspacePath, ".vscode");
2189
- const configPath = path12.join(vscodeDir, "mcp.json");
2190
- if (!fs11.existsSync(vscodeDir)) {
2191
- fs11.mkdirSync(vscodeDir, { recursive: true });
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 (fs11.existsSync(configPath)) {
2254
+ if (fs12.existsSync(configPath)) {
2195
2255
  try {
2196
- config = JSON.parse(fs11.readFileSync(configPath, "utf-8"));
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
- fs11.writeFileSync(configPath, JSON.stringify(config, null, 2));
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 = path12.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
2231
- CLAUDE_CONFIG = path12.join(os.homedir(), ".config/claude/claude_desktop_config.json");
2232
- VSCODE_GLOBAL_CONFIG = path12.join(os.homedir(), ".config/Code/User/settings.json");
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 fs18 = await import("fs");
2318
- const path17 = await import("path");
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 (!fs18.existsSync(resolvedPath)) {
2333
- fs18.mkdirSync(resolvedPath, { recursive: true });
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
- ${path17.join(resolvedPath, "mcp.yaml")}`,
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 fs12 from "fs";
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 (fs12.existsSync(logPath)) {
2888
- const stats = fs12.statSync(logPath);
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 (fs12.existsSync(logPath)) {
2893
- const stats = fs12.statSync(logPath);
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 = fs12.openSync(logPath, "r");
2897
- fs12.readSync(fd, buffer, 0, buffer.length, lastSize);
2898
- fs12.closeSync(fd);
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 fs13 from "fs";
3233
- import * as path13 from "path";
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(path13.join(dataPath, "knowledge"));
3374
- ensureDir(path13.join(dataPath, "refs"));
3375
- ensureDir(path13.join(dataPath, "tasks"));
3376
- ensureDir(path13.join(dataPath, "templates"));
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(path13.join(agentCoreDir, "templates"), "templates", dataPaths);
3471
+ copyDirToAllStoragePaths(path14.join(agentCoreDir, "templates"), "templates", dataPaths);
3381
3472
  const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
3382
- if (config.tools.includes("copilot")) {
3383
- const copilotPath = getAgentPromptPath(workspacePath, "copilot");
3384
- ensureDir(copilotPath);
3385
- copyPromptsToDir(prompts, copilotPath, ".agent.md");
3386
- }
3387
- if (config.tools.includes("antigravity")) {
3388
- const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
3389
- ensureDir(antigravityPath);
3390
- copyPromptsToDir(prompts, antigravityPath, ".md");
3391
- }
3392
- const workspaceConfigPath = path13.join(workspacePath, ".rrce-workflow", "config.yaml");
3393
- ensureDir(path13.dirname(workspaceConfigPath));
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
- fs13.writeFileSync(workspaceConfigPath, configContent);
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(mcpConfig, currentProjectName, true);
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(mcpConfig, currentProjectName, true);
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 = path13.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
3451
- const workspacePath = path13.join(workspaceRoot, ".rrce-workflow");
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 = path13.join(workspacePath, ".gitignore");
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 (fs13.existsSync(gitignorePath)) {
3479
- content = fs13.readFileSync(gitignorePath, "utf-8");
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
- fs13.writeFileSync(gitignorePath, newContent);
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 fs14 from "fs";
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 = fs14.readFileSync(configFilePath, "utf-8");
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
- fs14.writeFileSync(configFilePath, configContent);
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 fs15 from "fs";
3633
- import * as path14 from "path";
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 = path14.join(customGlobalPath, "workspaces", workspaceName);
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) => fs15.existsSync(path14.join(localPath, 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 = path14.join(localPath, dir);
3667
- const destDir = path14.join(globalPath, dir);
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 fs16 from "fs";
3700
- import * as path15 from "path";
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(path15.join(agentCoreDir, "templates"), "templates", [dataPath]);
3843
+ copyDirToAllStoragePaths(path16.join(agentCoreDir, "templates"), "templates", [dataPath]);
3731
3844
  }
3732
3845
  const configFilePath = getConfigPath(workspacePath);
3733
- const configContent = fs16.readFileSync(configFilePath, "utf-8");
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 = path15.join(customGlobalPath, "workspaces", workspaceName);
3762
- const workspacePath = path15.join(workspaceRoot, ".rrce-workflow");
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 select3, spinner as spinner7, note as note11, outro as outro6, isCancel as isCancel10 } from "@clack/prompts";
3787
- import pc12 from "picocolors";
3788
- import * as fs17 from "fs";
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(pc12.cyan(pc12.inverse(" RRCE-Workflow Setup ")));
3791
- const s = spinner7();
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
- note11(
3799
- `Git User: ${pc12.bold(gitUser || "(not found)")}
3800
- Workspace: ${pc12.bold(workspaceName)}`,
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 = fs17.existsSync(configFilePath);
3998
+ const isAlreadyConfigured = fs19.existsSync(configFilePath);
3809
3999
  let currentStorageMode = null;
3810
4000
  if (isAlreadyConfigured) {
3811
4001
  try {
3812
- const configContent = fs17.readFileSync(configFilePath, "utf-8");
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 = fs17.existsSync(localDataPath);
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 select3({
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 (isCancel10(action) || action === "exit") {
3849
- outro6("Exited.");
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 select4, note as note12, cancel as cancel7, isCancel as isCancel11, outro as outro7 } from "@clack/prompts";
3893
- import pc13 from "picocolors";
3894
- import * as path16 from "path";
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 = path16.basename(process.cwd());
3897
- intro3(pc13.cyan(pc13.inverse(` RRCE-Workflow | ${workspaceName} `)));
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
- cancel7("No agents found. Run `rrce-workflow` to set up.");
4103
+ cancel8("No agents found. Run `rrce-workflow` to set up.");
3901
4104
  process.exit(0);
3902
4105
  }
3903
- const selection = await select4({
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 (isCancel11(selection)) {
3924
- cancel7("Selection cancelled.");
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
- note12(
4141
+ note13(
3939
4142
  `Use this agent in your IDE by invoking:
3940
- ${pc13.bold(pc13.cyan(`@${prompt.frontmatter.name}`))}`,
4143
+ ${pc14.bold(pc14.cyan(`@${prompt.frontmatter.name}`))}`,
3941
4144
  "Agent Selected"
3942
4145
  );
3943
- outro7("Done");
4146
+ outro8("Done");
3944
4147
  }
3945
4148
 
3946
4149
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.46",
3
+ "version": "0.2.48",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",