rrce-workflow 0.2.28 → 0.2.29
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 +519 -431
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,22 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
// src/lib/git.ts
|
|
12
|
+
import { execSync } from "child_process";
|
|
13
|
+
function getGitUser() {
|
|
14
|
+
try {
|
|
15
|
+
const result = execSync("git config user.name", { encoding: "utf-8" });
|
|
16
|
+
return result.trim() || null;
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
var init_git = __esm({
|
|
22
|
+
"src/lib/git.ts"() {
|
|
23
|
+
"use strict";
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
11
27
|
// src/lib/paths.ts
|
|
12
28
|
import * as fs from "fs";
|
|
13
29
|
import * as path from "path";
|
|
@@ -366,6 +382,128 @@ var init_prompts = __esm({
|
|
|
366
382
|
}
|
|
367
383
|
});
|
|
368
384
|
|
|
385
|
+
// src/commands/wizard/utils.ts
|
|
386
|
+
import * as fs4 from "fs";
|
|
387
|
+
import * as path4 from "path";
|
|
388
|
+
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
389
|
+
for (const prompt of prompts) {
|
|
390
|
+
const baseName = path4.basename(prompt.filePath, ".md");
|
|
391
|
+
const targetName = baseName + extension;
|
|
392
|
+
const targetPath = path4.join(targetDir, targetName);
|
|
393
|
+
const content = fs4.readFileSync(prompt.filePath, "utf-8");
|
|
394
|
+
fs4.writeFileSync(targetPath, content);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function copyDirRecursive(src, dest) {
|
|
398
|
+
const entries = fs4.readdirSync(src, { withFileTypes: true });
|
|
399
|
+
for (const entry of entries) {
|
|
400
|
+
const srcPath = path4.join(src, entry.name);
|
|
401
|
+
const destPath = path4.join(dest, entry.name);
|
|
402
|
+
if (entry.isDirectory()) {
|
|
403
|
+
ensureDir(destPath);
|
|
404
|
+
copyDirRecursive(srcPath, destPath);
|
|
405
|
+
} else {
|
|
406
|
+
fs4.copyFileSync(srcPath, destPath);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
var init_utils = __esm({
|
|
411
|
+
"src/commands/wizard/utils.ts"() {
|
|
412
|
+
"use strict";
|
|
413
|
+
init_paths();
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// src/commands/wizard/vscode.ts
|
|
418
|
+
import * as fs5 from "fs";
|
|
419
|
+
import * as path5 from "path";
|
|
420
|
+
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
421
|
+
const workspaceFilePath = path5.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
422
|
+
let workspace;
|
|
423
|
+
if (fs5.existsSync(workspaceFilePath)) {
|
|
424
|
+
try {
|
|
425
|
+
const content = fs5.readFileSync(workspaceFilePath, "utf-8");
|
|
426
|
+
workspace = JSON.parse(content);
|
|
427
|
+
} catch {
|
|
428
|
+
workspace = { folders: [], settings: {} };
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
431
|
+
workspace = { folders: [], settings: {} };
|
|
432
|
+
}
|
|
433
|
+
if (!workspace.settings) {
|
|
434
|
+
workspace.settings = {};
|
|
435
|
+
}
|
|
436
|
+
workspace.folders = workspace.folders.filter(
|
|
437
|
+
(f) => f.path === "." || !f.name?.startsWith("\u{1F4C1}") && !f.name?.startsWith("\u{1F4DA}") && !f.name?.startsWith("\u{1F4CE}") && !f.name?.startsWith("\u{1F4CB}")
|
|
438
|
+
);
|
|
439
|
+
const mainFolderIndex = workspace.folders.findIndex((f) => f.path === ".");
|
|
440
|
+
if (mainFolderIndex === -1) {
|
|
441
|
+
workspace.folders.unshift({
|
|
442
|
+
path: ".",
|
|
443
|
+
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
444
|
+
});
|
|
445
|
+
} else {
|
|
446
|
+
workspace.folders[mainFolderIndex] = {
|
|
447
|
+
path: ".",
|
|
448
|
+
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
const referenceFolderPaths = [];
|
|
452
|
+
const isDetectedProjects = linkedProjects.length > 0 && typeof linkedProjects[0] === "object";
|
|
453
|
+
if (isDetectedProjects) {
|
|
454
|
+
const projects = linkedProjects;
|
|
455
|
+
for (const project of projects) {
|
|
456
|
+
const sourceLabel = project.source === "global" ? "global" : "local";
|
|
457
|
+
const folderPath = project.dataPath;
|
|
458
|
+
if (fs5.existsSync(folderPath)) {
|
|
459
|
+
referenceFolderPaths.push(folderPath);
|
|
460
|
+
workspace.folders.push({
|
|
461
|
+
path: folderPath,
|
|
462
|
+
name: `\u{1F4C1} ${project.name} [${sourceLabel}]`
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
} else {
|
|
467
|
+
const projectNames = linkedProjects;
|
|
468
|
+
const rrceHome = customGlobalPath || getRRCEHome();
|
|
469
|
+
for (const projectName of projectNames) {
|
|
470
|
+
const folderPath = path5.join(rrceHome, "workspaces", projectName);
|
|
471
|
+
if (fs5.existsSync(folderPath)) {
|
|
472
|
+
referenceFolderPaths.push(folderPath);
|
|
473
|
+
workspace.folders.push({
|
|
474
|
+
path: folderPath,
|
|
475
|
+
name: `\u{1F4C1} ${projectName} [global]`
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (referenceFolderPaths.length > 0) {
|
|
481
|
+
const readonlyPatterns = {};
|
|
482
|
+
for (const folderPath of referenceFolderPaths) {
|
|
483
|
+
readonlyPatterns[`${folderPath}/**`] = true;
|
|
484
|
+
}
|
|
485
|
+
const existingReadonly = workspace.settings["files.readonlyInclude"] || {};
|
|
486
|
+
const cleanedReadonly = {};
|
|
487
|
+
for (const [pattern, value] of Object.entries(existingReadonly)) {
|
|
488
|
+
if (!pattern.includes(".rrce-workflow") && !pattern.includes("rrce-workflow/workspaces")) {
|
|
489
|
+
cleanedReadonly[pattern] = value;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
workspace.settings["files.readonlyInclude"] = {
|
|
493
|
+
...cleanedReadonly,
|
|
494
|
+
...readonlyPatterns
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
fs5.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, 2));
|
|
498
|
+
}
|
|
499
|
+
var init_vscode = __esm({
|
|
500
|
+
"src/commands/wizard/vscode.ts"() {
|
|
501
|
+
"use strict";
|
|
502
|
+
init_paths();
|
|
503
|
+
init_detection();
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
|
|
369
507
|
// src/lib/autocomplete-prompt.ts
|
|
370
508
|
import * as fs6 from "fs";
|
|
371
509
|
import * as path6 from "path";
|
|
@@ -583,20 +721,20 @@ var init_types = __esm({
|
|
|
583
721
|
});
|
|
584
722
|
|
|
585
723
|
// src/mcp/config.ts
|
|
586
|
-
import * as
|
|
587
|
-
import * as
|
|
724
|
+
import * as fs7 from "fs";
|
|
725
|
+
import * as path8 from "path";
|
|
588
726
|
function getMCPConfigPath() {
|
|
589
727
|
const workspaceRoot = detectWorkspaceRoot();
|
|
590
728
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
591
|
-
return
|
|
729
|
+
return path8.join(rrceHome, "mcp.yaml");
|
|
592
730
|
}
|
|
593
731
|
function ensureMCPGlobalPath() {
|
|
594
732
|
const workspaceRoot = detectWorkspaceRoot();
|
|
595
733
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
596
734
|
if (rrceHome.startsWith(".") || rrceHome.includes(".rrce-workflow/")) {
|
|
597
|
-
const configPath =
|
|
598
|
-
if (
|
|
599
|
-
const content =
|
|
735
|
+
const configPath = path8.join(workspaceRoot, ".rrce-workflow", "config.yaml");
|
|
736
|
+
if (fs7.existsSync(configPath)) {
|
|
737
|
+
const content = fs7.readFileSync(configPath, "utf-8");
|
|
600
738
|
const modeMatch = content.match(/mode:\s*(global|workspace)/);
|
|
601
739
|
if (modeMatch?.[1] === "workspace") {
|
|
602
740
|
return {
|
|
@@ -614,11 +752,11 @@ function ensureMCPGlobalPath() {
|
|
|
614
752
|
}
|
|
615
753
|
function loadMCPConfig() {
|
|
616
754
|
const configPath = getMCPConfigPath();
|
|
617
|
-
if (!
|
|
755
|
+
if (!fs7.existsSync(configPath)) {
|
|
618
756
|
return { ...DEFAULT_MCP_CONFIG };
|
|
619
757
|
}
|
|
620
758
|
try {
|
|
621
|
-
const content =
|
|
759
|
+
const content = fs7.readFileSync(configPath, "utf-8");
|
|
622
760
|
return parseMCPConfig(content);
|
|
623
761
|
} catch {
|
|
624
762
|
return { ...DEFAULT_MCP_CONFIG };
|
|
@@ -626,12 +764,12 @@ function loadMCPConfig() {
|
|
|
626
764
|
}
|
|
627
765
|
function saveMCPConfig(config) {
|
|
628
766
|
const configPath = getMCPConfigPath();
|
|
629
|
-
const dir =
|
|
630
|
-
if (!
|
|
631
|
-
|
|
767
|
+
const dir = path8.dirname(configPath);
|
|
768
|
+
if (!fs7.existsSync(dir)) {
|
|
769
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
632
770
|
}
|
|
633
771
|
const content = serializeMCPConfig(config);
|
|
634
|
-
|
|
772
|
+
fs7.writeFileSync(configPath, content);
|
|
635
773
|
}
|
|
636
774
|
function parseMCPConfig(content) {
|
|
637
775
|
const config = { ...DEFAULT_MCP_CONFIG, projects: [] };
|
|
@@ -794,12 +932,12 @@ __export(logger_exports, {
|
|
|
794
932
|
getLogFilePath: () => getLogFilePath,
|
|
795
933
|
logger: () => logger
|
|
796
934
|
});
|
|
797
|
-
import * as
|
|
798
|
-
import * as
|
|
935
|
+
import * as fs8 from "fs";
|
|
936
|
+
import * as path9 from "path";
|
|
799
937
|
function getLogFilePath() {
|
|
800
938
|
const workspaceRoot = detectWorkspaceRoot();
|
|
801
939
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
802
|
-
return
|
|
940
|
+
return path9.join(rrceHome, "mcp-server.log");
|
|
803
941
|
}
|
|
804
942
|
var Logger, logger;
|
|
805
943
|
var init_logger = __esm({
|
|
@@ -830,11 +968,11 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
830
968
|
}
|
|
831
969
|
logMessage += "\n";
|
|
832
970
|
try {
|
|
833
|
-
const dir =
|
|
834
|
-
if (!
|
|
835
|
-
|
|
971
|
+
const dir = path9.dirname(this.logPath);
|
|
972
|
+
if (!fs8.existsSync(dir)) {
|
|
973
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
836
974
|
}
|
|
837
|
-
|
|
975
|
+
fs8.appendFileSync(this.logPath, logMessage);
|
|
838
976
|
} catch (e) {
|
|
839
977
|
console.error(`[Logger Failure] Could not write to ${this.logPath}`, e);
|
|
840
978
|
console.error(logMessage);
|
|
@@ -858,8 +996,8 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
858
996
|
});
|
|
859
997
|
|
|
860
998
|
// src/mcp/resources.ts
|
|
861
|
-
import * as
|
|
862
|
-
import * as
|
|
999
|
+
import * as fs9 from "fs";
|
|
1000
|
+
import * as path10 from "path";
|
|
863
1001
|
function getExposedProjects() {
|
|
864
1002
|
const config = loadMCPConfig();
|
|
865
1003
|
const allProjects = scanForProjects();
|
|
@@ -886,11 +1024,11 @@ function getProjectContext(projectName) {
|
|
|
886
1024
|
if (!project?.knowledgePath) {
|
|
887
1025
|
return null;
|
|
888
1026
|
}
|
|
889
|
-
const contextPath =
|
|
890
|
-
if (!
|
|
1027
|
+
const contextPath = path10.join(project.knowledgePath, "project-context.md");
|
|
1028
|
+
if (!fs9.existsSync(contextPath)) {
|
|
891
1029
|
return null;
|
|
892
1030
|
}
|
|
893
|
-
return
|
|
1031
|
+
return fs9.readFileSync(contextPath, "utf-8");
|
|
894
1032
|
}
|
|
895
1033
|
function getProjectTasks(projectName) {
|
|
896
1034
|
const config = loadMCPConfig();
|
|
@@ -903,18 +1041,18 @@ function getProjectTasks(projectName) {
|
|
|
903
1041
|
}
|
|
904
1042
|
const projects = scanForProjects();
|
|
905
1043
|
const project = projects.find((p) => p.name === projectName);
|
|
906
|
-
if (!project?.tasksPath || !
|
|
1044
|
+
if (!project?.tasksPath || !fs9.existsSync(project.tasksPath)) {
|
|
907
1045
|
return [];
|
|
908
1046
|
}
|
|
909
1047
|
const tasks = [];
|
|
910
1048
|
try {
|
|
911
|
-
const taskDirs =
|
|
1049
|
+
const taskDirs = fs9.readdirSync(project.tasksPath, { withFileTypes: true });
|
|
912
1050
|
for (const dir of taskDirs) {
|
|
913
1051
|
if (!dir.isDirectory()) continue;
|
|
914
|
-
const metaPath =
|
|
915
|
-
if (
|
|
1052
|
+
const metaPath = path10.join(project.tasksPath, dir.name, "meta.json");
|
|
1053
|
+
if (fs9.existsSync(metaPath)) {
|
|
916
1054
|
try {
|
|
917
|
-
const meta = JSON.parse(
|
|
1055
|
+
const meta = JSON.parse(fs9.readFileSync(metaPath, "utf-8"));
|
|
918
1056
|
tasks.push(meta);
|
|
919
1057
|
} catch {
|
|
920
1058
|
}
|
|
@@ -933,11 +1071,11 @@ function searchKnowledge(query) {
|
|
|
933
1071
|
const permissions = getProjectPermissions(config, project.name);
|
|
934
1072
|
if (!permissions.knowledge || !project.knowledgePath) continue;
|
|
935
1073
|
try {
|
|
936
|
-
const files =
|
|
1074
|
+
const files = fs9.readdirSync(project.knowledgePath);
|
|
937
1075
|
for (const file of files) {
|
|
938
1076
|
if (!file.endsWith(".md")) continue;
|
|
939
|
-
const filePath =
|
|
940
|
-
const content =
|
|
1077
|
+
const filePath = path10.join(project.knowledgePath, file);
|
|
1078
|
+
const content = fs9.readFileSync(filePath, "utf-8");
|
|
941
1079
|
const lines = content.split("\n");
|
|
942
1080
|
const matches = [];
|
|
943
1081
|
for (const line of lines) {
|
|
@@ -1105,8 +1243,9 @@ function registerResourceHandlers(server) {
|
|
|
1105
1243
|
};
|
|
1106
1244
|
}
|
|
1107
1245
|
const projectMatch = uri.match(/^rrce:\/\/projects\/([^/]+)\/(.+)$/);
|
|
1108
|
-
if (projectMatch) {
|
|
1109
|
-
const
|
|
1246
|
+
if (projectMatch && projectMatch[1] && projectMatch[2]) {
|
|
1247
|
+
const projectName = projectMatch[1];
|
|
1248
|
+
const resourceType = projectMatch[2];
|
|
1110
1249
|
const content = resourceType === "context" ? getProjectContext(projectName) : JSON.stringify(getProjectTasks(projectName), null, 2);
|
|
1111
1250
|
if (content === null) throw new Error(`Resource not found: ${uri}`);
|
|
1112
1251
|
return {
|
|
@@ -1357,8 +1496,8 @@ var init_server = __esm({
|
|
|
1357
1496
|
});
|
|
1358
1497
|
|
|
1359
1498
|
// src/mcp/install.ts
|
|
1360
|
-
import * as
|
|
1361
|
-
import * as
|
|
1499
|
+
import * as fs10 from "fs";
|
|
1500
|
+
import * as path11 from "path";
|
|
1362
1501
|
import * as os from "os";
|
|
1363
1502
|
function checkInstallStatus(workspacePath) {
|
|
1364
1503
|
return {
|
|
@@ -1369,37 +1508,37 @@ function checkInstallStatus(workspacePath) {
|
|
|
1369
1508
|
};
|
|
1370
1509
|
}
|
|
1371
1510
|
function checkAntigravityConfig() {
|
|
1372
|
-
if (!
|
|
1511
|
+
if (!fs10.existsSync(ANTIGRAVITY_CONFIG)) return false;
|
|
1373
1512
|
try {
|
|
1374
|
-
const content = JSON.parse(
|
|
1513
|
+
const content = JSON.parse(fs10.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
1375
1514
|
return !!content.mcpServers?.["rrce"];
|
|
1376
1515
|
} catch {
|
|
1377
1516
|
return false;
|
|
1378
1517
|
}
|
|
1379
1518
|
}
|
|
1380
1519
|
function checkClaudeConfig() {
|
|
1381
|
-
if (!
|
|
1520
|
+
if (!fs10.existsSync(CLAUDE_CONFIG)) return false;
|
|
1382
1521
|
try {
|
|
1383
|
-
const content = JSON.parse(
|
|
1522
|
+
const content = JSON.parse(fs10.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
1384
1523
|
return !!content.mcpServers?.["rrce"];
|
|
1385
1524
|
} catch {
|
|
1386
1525
|
return false;
|
|
1387
1526
|
}
|
|
1388
1527
|
}
|
|
1389
1528
|
function checkVSCodeGlobalConfig() {
|
|
1390
|
-
if (!
|
|
1529
|
+
if (!fs10.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
|
|
1391
1530
|
try {
|
|
1392
|
-
const content = JSON.parse(
|
|
1531
|
+
const content = JSON.parse(fs10.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
1393
1532
|
return !!content["mcp.servers"]?.["rrce"];
|
|
1394
1533
|
} catch {
|
|
1395
1534
|
return false;
|
|
1396
1535
|
}
|
|
1397
1536
|
}
|
|
1398
1537
|
function checkVSCodeWorkspaceConfig(workspacePath) {
|
|
1399
|
-
const configPath =
|
|
1400
|
-
if (!
|
|
1538
|
+
const configPath = path11.join(workspacePath, ".vscode", "mcp.json");
|
|
1539
|
+
if (!fs10.existsSync(configPath)) return false;
|
|
1401
1540
|
try {
|
|
1402
|
-
const content = JSON.parse(
|
|
1541
|
+
const content = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
1403
1542
|
return !!content.servers?.["rrce"];
|
|
1404
1543
|
} catch {
|
|
1405
1544
|
return false;
|
|
@@ -1424,14 +1563,14 @@ function installToConfig(target, workspacePath) {
|
|
|
1424
1563
|
}
|
|
1425
1564
|
}
|
|
1426
1565
|
function installToAntigravity() {
|
|
1427
|
-
const dir =
|
|
1428
|
-
if (!
|
|
1429
|
-
|
|
1566
|
+
const dir = path11.dirname(ANTIGRAVITY_CONFIG);
|
|
1567
|
+
if (!fs10.existsSync(dir)) {
|
|
1568
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
1430
1569
|
}
|
|
1431
1570
|
let config = { mcpServers: {} };
|
|
1432
|
-
if (
|
|
1571
|
+
if (fs10.existsSync(ANTIGRAVITY_CONFIG)) {
|
|
1433
1572
|
try {
|
|
1434
|
-
config = JSON.parse(
|
|
1573
|
+
config = JSON.parse(fs10.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
1435
1574
|
} catch {
|
|
1436
1575
|
}
|
|
1437
1576
|
}
|
|
@@ -1441,21 +1580,21 @@ function installToAntigravity() {
|
|
|
1441
1580
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1442
1581
|
};
|
|
1443
1582
|
try {
|
|
1444
|
-
|
|
1583
|
+
fs10.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
|
|
1445
1584
|
return true;
|
|
1446
1585
|
} catch {
|
|
1447
1586
|
return false;
|
|
1448
1587
|
}
|
|
1449
1588
|
}
|
|
1450
1589
|
function installToClaude() {
|
|
1451
|
-
const dir =
|
|
1452
|
-
if (!
|
|
1453
|
-
|
|
1590
|
+
const dir = path11.dirname(CLAUDE_CONFIG);
|
|
1591
|
+
if (!fs10.existsSync(dir)) {
|
|
1592
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
1454
1593
|
}
|
|
1455
1594
|
let config = { mcpServers: {} };
|
|
1456
|
-
if (
|
|
1595
|
+
if (fs10.existsSync(CLAUDE_CONFIG)) {
|
|
1457
1596
|
try {
|
|
1458
|
-
config = JSON.parse(
|
|
1597
|
+
config = JSON.parse(fs10.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
1459
1598
|
} catch {
|
|
1460
1599
|
}
|
|
1461
1600
|
}
|
|
@@ -1465,21 +1604,21 @@ function installToClaude() {
|
|
|
1465
1604
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1466
1605
|
};
|
|
1467
1606
|
try {
|
|
1468
|
-
|
|
1607
|
+
fs10.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
|
|
1469
1608
|
return true;
|
|
1470
1609
|
} catch {
|
|
1471
1610
|
return false;
|
|
1472
1611
|
}
|
|
1473
1612
|
}
|
|
1474
1613
|
function installToVSCodeGlobal() {
|
|
1475
|
-
const dir =
|
|
1476
|
-
if (!
|
|
1477
|
-
|
|
1614
|
+
const dir = path11.dirname(VSCODE_GLOBAL_CONFIG);
|
|
1615
|
+
if (!fs10.existsSync(dir)) {
|
|
1616
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
1478
1617
|
}
|
|
1479
1618
|
let settings = {};
|
|
1480
|
-
if (
|
|
1619
|
+
if (fs10.existsSync(VSCODE_GLOBAL_CONFIG)) {
|
|
1481
1620
|
try {
|
|
1482
|
-
settings = JSON.parse(
|
|
1621
|
+
settings = JSON.parse(fs10.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
1483
1622
|
} catch {
|
|
1484
1623
|
}
|
|
1485
1624
|
}
|
|
@@ -1489,22 +1628,22 @@ function installToVSCodeGlobal() {
|
|
|
1489
1628
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1490
1629
|
};
|
|
1491
1630
|
try {
|
|
1492
|
-
|
|
1631
|
+
fs10.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
|
|
1493
1632
|
return true;
|
|
1494
1633
|
} catch {
|
|
1495
1634
|
return false;
|
|
1496
1635
|
}
|
|
1497
1636
|
}
|
|
1498
1637
|
function installToVSCodeWorkspace(workspacePath) {
|
|
1499
|
-
const vscodeDir =
|
|
1500
|
-
const configPath =
|
|
1501
|
-
if (!
|
|
1502
|
-
|
|
1638
|
+
const vscodeDir = path11.join(workspacePath, ".vscode");
|
|
1639
|
+
const configPath = path11.join(vscodeDir, "mcp.json");
|
|
1640
|
+
if (!fs10.existsSync(vscodeDir)) {
|
|
1641
|
+
fs10.mkdirSync(vscodeDir, { recursive: true });
|
|
1503
1642
|
}
|
|
1504
1643
|
let config = { servers: {} };
|
|
1505
|
-
if (
|
|
1644
|
+
if (fs10.existsSync(configPath)) {
|
|
1506
1645
|
try {
|
|
1507
|
-
config = JSON.parse(
|
|
1646
|
+
config = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
1508
1647
|
} catch {
|
|
1509
1648
|
}
|
|
1510
1649
|
}
|
|
@@ -1514,7 +1653,7 @@ function installToVSCodeWorkspace(workspacePath) {
|
|
|
1514
1653
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
1515
1654
|
};
|
|
1516
1655
|
try {
|
|
1517
|
-
|
|
1656
|
+
fs10.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
1518
1657
|
return true;
|
|
1519
1658
|
} catch {
|
|
1520
1659
|
return false;
|
|
@@ -1538,9 +1677,9 @@ var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG, VSCODE_GLOBAL_CONFIG;
|
|
|
1538
1677
|
var init_install = __esm({
|
|
1539
1678
|
"src/mcp/install.ts"() {
|
|
1540
1679
|
"use strict";
|
|
1541
|
-
ANTIGRAVITY_CONFIG =
|
|
1542
|
-
CLAUDE_CONFIG =
|
|
1543
|
-
VSCODE_GLOBAL_CONFIG =
|
|
1680
|
+
ANTIGRAVITY_CONFIG = path11.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
|
|
1681
|
+
CLAUDE_CONFIG = path11.join(os.homedir(), ".config/claude/claude_desktop_config.json");
|
|
1682
|
+
VSCODE_GLOBAL_CONFIG = path11.join(os.homedir(), ".config/Code/User/settings.json");
|
|
1544
1683
|
}
|
|
1545
1684
|
});
|
|
1546
1685
|
|
|
@@ -1549,8 +1688,8 @@ var mcp_exports = {};
|
|
|
1549
1688
|
__export(mcp_exports, {
|
|
1550
1689
|
runMCP: () => runMCP
|
|
1551
1690
|
});
|
|
1552
|
-
import { intro, outro
|
|
1553
|
-
import
|
|
1691
|
+
import { intro, outro, select as select2, multiselect, confirm, spinner, note as note2, cancel, isCancel as isCancel2, text } from "@clack/prompts";
|
|
1692
|
+
import pc3 from "picocolors";
|
|
1554
1693
|
async function runMCP(subcommand2) {
|
|
1555
1694
|
if (subcommand2) {
|
|
1556
1695
|
switch (subcommand2) {
|
|
@@ -1570,57 +1709,60 @@ async function runMCP(subcommand2) {
|
|
|
1570
1709
|
return;
|
|
1571
1710
|
}
|
|
1572
1711
|
}
|
|
1573
|
-
intro(
|
|
1712
|
+
intro(pc3.bgCyan(pc3.black(" RRCE MCP Hub ")));
|
|
1574
1713
|
const workspacePath = detectWorkspaceRoot();
|
|
1575
1714
|
const globalPathCheck = await ensureMCPGlobalPath();
|
|
1576
1715
|
if (!globalPathCheck.configured) {
|
|
1577
1716
|
const configured = await handleConfigureGlobalPath();
|
|
1578
1717
|
if (!configured) {
|
|
1579
|
-
|
|
1718
|
+
outro(pc3.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
1580
1719
|
return;
|
|
1581
1720
|
}
|
|
1582
1721
|
}
|
|
1583
|
-
const status = checkInstallStatus(workspacePath);
|
|
1584
1722
|
const installed = isInstalledAnywhere(workspacePath);
|
|
1585
1723
|
if (!installed) {
|
|
1586
|
-
|
|
1587
|
-
`${
|
|
1724
|
+
note2(
|
|
1725
|
+
`${pc3.bold("Welcome to RRCE MCP Hub!")}
|
|
1588
1726
|
|
|
1589
1727
|
MCP (Model Context Protocol) allows AI assistants to access your
|
|
1590
1728
|
project knowledge in real-time. Let's get you set up.`,
|
|
1591
1729
|
"Getting Started"
|
|
1592
1730
|
);
|
|
1593
|
-
const shouldInstall = await
|
|
1731
|
+
const shouldInstall = await confirm({
|
|
1594
1732
|
message: "Install MCP server to your IDE(s)?",
|
|
1595
1733
|
initialValue: true
|
|
1596
1734
|
});
|
|
1597
|
-
if (shouldInstall && !
|
|
1735
|
+
if (shouldInstall && !isCancel2(shouldInstall)) {
|
|
1598
1736
|
await handleInstallWizard(workspacePath);
|
|
1599
|
-
|
|
1600
|
-
const
|
|
1737
|
+
const config2 = loadMCPConfig();
|
|
1738
|
+
const exposedCount2 = config2.projects.filter((p) => p.expose).length;
|
|
1739
|
+
if (exposedCount2 === 0) {
|
|
1740
|
+
await handleConfigure();
|
|
1741
|
+
}
|
|
1742
|
+
const shouldStart = await confirm({
|
|
1601
1743
|
message: "Start the MCP server now?",
|
|
1602
1744
|
initialValue: true
|
|
1603
1745
|
});
|
|
1604
|
-
if (shouldStart && !
|
|
1746
|
+
if (shouldStart && !isCancel2(shouldStart)) {
|
|
1605
1747
|
await handleStartServer();
|
|
1606
1748
|
}
|
|
1607
1749
|
}
|
|
1608
|
-
|
|
1750
|
+
outro(pc3.green("MCP Hub setup complete!"));
|
|
1609
1751
|
return;
|
|
1610
1752
|
}
|
|
1611
1753
|
const config = loadMCPConfig();
|
|
1612
1754
|
const exposedCount = config.projects.filter((p) => p.expose).length;
|
|
1613
1755
|
if (exposedCount === 0 && !config.defaults.includeNew) {
|
|
1614
|
-
|
|
1756
|
+
note2("MCP is installed but no projects are exposed. Let's configure that.", "Configuration Needed");
|
|
1615
1757
|
await handleConfigure();
|
|
1616
1758
|
}
|
|
1617
1759
|
let running = true;
|
|
1618
1760
|
while (running) {
|
|
1619
1761
|
const serverStatus = getMCPServerStatus();
|
|
1620
|
-
const serverLabel = serverStatus.running ?
|
|
1762
|
+
const serverLabel = serverStatus.running ? pc3.green("\u25CF Running") : pc3.dim("\u25CB Stopped");
|
|
1621
1763
|
const currentStatus = checkInstallStatus(workspacePath);
|
|
1622
1764
|
const installedCount = [currentStatus.antigravity, currentStatus.claude, currentStatus.vscodeGlobal, currentStatus.vscodeWorkspace].filter(Boolean).length;
|
|
1623
|
-
const action = await
|
|
1765
|
+
const action = await select2({
|
|
1624
1766
|
message: "What would you like to do?",
|
|
1625
1767
|
options: [
|
|
1626
1768
|
{ value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: serverLabel },
|
|
@@ -1631,8 +1773,8 @@ project knowledge in real-time. Let's get you set up.`,
|
|
|
1631
1773
|
{ value: "exit", label: "\u21A9 Exit", hint: "Return to shell" }
|
|
1632
1774
|
]
|
|
1633
1775
|
});
|
|
1634
|
-
if (
|
|
1635
|
-
|
|
1776
|
+
if (isCancel2(action)) {
|
|
1777
|
+
cancel("MCP Hub closed.");
|
|
1636
1778
|
return;
|
|
1637
1779
|
}
|
|
1638
1780
|
switch (action) {
|
|
@@ -1656,7 +1798,7 @@ project knowledge in real-time. Let's get you set up.`,
|
|
|
1656
1798
|
break;
|
|
1657
1799
|
}
|
|
1658
1800
|
}
|
|
1659
|
-
|
|
1801
|
+
outro(pc3.green("MCP Hub closed."));
|
|
1660
1802
|
}
|
|
1661
1803
|
async function handleInstallWizard(workspacePath) {
|
|
1662
1804
|
const status = checkInstallStatus(workspacePath);
|
|
@@ -1664,25 +1806,25 @@ async function handleInstallWizard(workspacePath) {
|
|
|
1664
1806
|
{
|
|
1665
1807
|
value: "antigravity",
|
|
1666
1808
|
label: "Antigravity IDE",
|
|
1667
|
-
hint: status.antigravity ?
|
|
1809
|
+
hint: status.antigravity ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
1668
1810
|
},
|
|
1669
1811
|
{
|
|
1670
1812
|
value: "vscode-global",
|
|
1671
|
-
label: "VSCode (Global)",
|
|
1672
|
-
hint: status.vscodeGlobal ?
|
|
1813
|
+
label: "VSCode (Global Settings)",
|
|
1814
|
+
hint: status.vscodeGlobal ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
1673
1815
|
},
|
|
1674
1816
|
{
|
|
1675
1817
|
value: "vscode-workspace",
|
|
1676
|
-
label: "VSCode (
|
|
1677
|
-
hint: status.vscodeWorkspace ?
|
|
1818
|
+
label: "VSCode (Workspace Config)",
|
|
1819
|
+
hint: status.vscodeWorkspace ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
1678
1820
|
},
|
|
1679
1821
|
{
|
|
1680
1822
|
value: "claude",
|
|
1681
1823
|
label: "Claude Desktop",
|
|
1682
|
-
hint: status.claude ?
|
|
1824
|
+
hint: status.claude ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")
|
|
1683
1825
|
}
|
|
1684
1826
|
];
|
|
1685
|
-
const selected = await
|
|
1827
|
+
const selected = await multiselect({
|
|
1686
1828
|
message: "Select where to install RRCE MCP Server:",
|
|
1687
1829
|
options,
|
|
1688
1830
|
initialValues: [
|
|
@@ -1693,16 +1835,16 @@ async function handleInstallWizard(workspacePath) {
|
|
|
1693
1835
|
],
|
|
1694
1836
|
required: false
|
|
1695
1837
|
});
|
|
1696
|
-
if (
|
|
1838
|
+
if (isCancel2(selected)) return;
|
|
1697
1839
|
const targets = selected;
|
|
1698
1840
|
const results = [];
|
|
1699
1841
|
for (const target of targets) {
|
|
1700
1842
|
const success = installToConfig(target, workspacePath);
|
|
1701
1843
|
const label = getTargetLabel(target);
|
|
1702
|
-
results.push(`${label}: ${success ?
|
|
1844
|
+
results.push(`${label}: ${success ? pc3.green("\u2713 Success") : pc3.red("\u2717 Failed")}`);
|
|
1703
1845
|
}
|
|
1704
1846
|
if (results.length > 0) {
|
|
1705
|
-
|
|
1847
|
+
note2(results.join("\n"), "Installation Results");
|
|
1706
1848
|
}
|
|
1707
1849
|
}
|
|
1708
1850
|
async function handleStartServer() {
|
|
@@ -1715,73 +1857,83 @@ async function handleStartServer() {
|
|
|
1715
1857
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
1716
1858
|
});
|
|
1717
1859
|
if (exposedProjects.length === 0) {
|
|
1718
|
-
const shouldConfig = await
|
|
1860
|
+
const shouldConfig = await confirm({
|
|
1719
1861
|
message: "No projects are currently exposed. Configure now?",
|
|
1720
1862
|
initialValue: true
|
|
1721
1863
|
});
|
|
1722
|
-
if (shouldConfig && !
|
|
1864
|
+
if (shouldConfig && !isCancel2(shouldConfig)) {
|
|
1723
1865
|
await handleConfigure();
|
|
1724
1866
|
return handleStartServer();
|
|
1725
1867
|
}
|
|
1726
1868
|
}
|
|
1727
|
-
const
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1869
|
+
const status = getMCPServerStatus();
|
|
1870
|
+
let newPort = config.server.port;
|
|
1871
|
+
if (!status.running) {
|
|
1872
|
+
const portInput = await text({
|
|
1873
|
+
message: "Select port for MCP Server",
|
|
1874
|
+
initialValue: config.server.port.toString(),
|
|
1875
|
+
placeholder: "3200",
|
|
1876
|
+
validate(value) {
|
|
1877
|
+
if (isNaN(Number(value))) return "Port must be a number";
|
|
1878
|
+
}
|
|
1879
|
+
});
|
|
1880
|
+
if (isCancel2(portInput)) return;
|
|
1881
|
+
newPort = parseInt(portInput, 10);
|
|
1882
|
+
if (newPort !== config.server.port) {
|
|
1883
|
+
config.server.port = newPort;
|
|
1884
|
+
saveMCPConfig(config);
|
|
1733
1885
|
}
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
if (newPort !== config.server.port) {
|
|
1738
|
-
config.server.port = newPort;
|
|
1739
|
-
saveMCPConfig(config);
|
|
1886
|
+
} else {
|
|
1887
|
+
newPort = status.port || newPort;
|
|
1888
|
+
note2(`Server is already running on port ${newPort}`, "Info");
|
|
1740
1889
|
}
|
|
1741
1890
|
console.clear();
|
|
1742
1891
|
const logPath = getLogFilePath2();
|
|
1743
|
-
const workspacePath = detectWorkspaceRoot();
|
|
1744
1892
|
const exposedNames = exposedProjects.map((p) => p.name).slice(0, 5);
|
|
1745
|
-
const exposedLabel = exposedNames.length > 0 ? exposedNames.join(", ") + (exposedProjects.length > 5 ? ` (+${exposedProjects.length - 5} more)` : "") :
|
|
1893
|
+
const exposedLabel = exposedNames.length > 0 ? exposedNames.join(", ") + (exposedProjects.length > 5 ? ` (+${exposedProjects.length - 5} more)` : "") : pc3.dim("(none)");
|
|
1746
1894
|
const render = (logs = []) => {
|
|
1747
1895
|
console.clear();
|
|
1748
|
-
console.log(
|
|
1749
|
-
console.log(
|
|
1750
|
-
console.log(
|
|
1896
|
+
console.log(pc3.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
1897
|
+
console.log(pc3.cyan("\u2551") + pc3.bold(pc3.white(" RRCE MCP Hub Running ")) + pc3.cyan("\u2551"));
|
|
1898
|
+
console.log(pc3.cyan("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
1751
1899
|
const logLines = logs.slice(-10);
|
|
1752
1900
|
const emptyLines = 10 - logLines.length;
|
|
1753
1901
|
for (let i = 0; i < emptyLines; i++) {
|
|
1754
|
-
console.log(
|
|
1902
|
+
console.log(pc3.cyan("\u2551") + " ".repeat(63) + pc3.cyan("\u2551"));
|
|
1755
1903
|
}
|
|
1756
1904
|
for (const line of logLines) {
|
|
1757
|
-
const
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
console.log(
|
|
1905
|
+
const cleanLine = line.replace(/\u001b\[\d+m/g, "");
|
|
1906
|
+
const truncated = cleanLine.substring(0, 61).padEnd(61);
|
|
1907
|
+
console.log(pc3.cyan("\u2551") + " " + pc3.dim(truncated) + " " + pc3.cyan("\u2551"));
|
|
1908
|
+
}
|
|
1909
|
+
console.log(pc3.cyan("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
1910
|
+
const infoLine = ` \u{1F4CB} ${exposedLabel} \u2502 Port: ${newPort} \u2502 PID: ${process.pid || "?"}`.substring(0, 61).padEnd(61);
|
|
1911
|
+
console.log(pc3.cyan("\u2551") + pc3.yellow(infoLine) + " " + pc3.cyan("\u2551"));
|
|
1912
|
+
console.log(pc3.cyan("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
1764
1913
|
const cmdLine = ` q:Quit p:Projects i:Install r:Reload c:Clear ?:Help`;
|
|
1765
|
-
console.log(
|
|
1766
|
-
console.log(
|
|
1914
|
+
console.log(pc3.cyan("\u2551") + pc3.dim(cmdLine.padEnd(63)) + pc3.cyan("\u2551"));
|
|
1915
|
+
console.log(pc3.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
1767
1916
|
};
|
|
1768
1917
|
let logBuffer = [];
|
|
1769
1918
|
render(logBuffer);
|
|
1770
1919
|
try {
|
|
1771
|
-
|
|
1920
|
+
if (!status.running) {
|
|
1921
|
+
await startMCPServer();
|
|
1922
|
+
}
|
|
1772
1923
|
let lastSize = 0;
|
|
1773
1924
|
if (fs16.existsSync(logPath)) {
|
|
1774
1925
|
const stats = fs16.statSync(logPath);
|
|
1775
1926
|
lastSize = stats.size;
|
|
1776
1927
|
}
|
|
1777
1928
|
let isRunning = true;
|
|
1929
|
+
let interval;
|
|
1778
1930
|
if (process.stdin.setRawMode) {
|
|
1779
1931
|
process.stdin.setRawMode(true);
|
|
1780
1932
|
process.stdin.resume();
|
|
1781
1933
|
process.stdin.setEncoding("utf8");
|
|
1782
1934
|
}
|
|
1783
1935
|
return new Promise((resolve) => {
|
|
1784
|
-
const cleanup = () => {
|
|
1936
|
+
const cleanup = (shouldStopServer) => {
|
|
1785
1937
|
isRunning = false;
|
|
1786
1938
|
clearInterval(interval);
|
|
1787
1939
|
if (process.stdin.setRawMode) {
|
|
@@ -1789,26 +1941,30 @@ async function handleStartServer() {
|
|
|
1789
1941
|
}
|
|
1790
1942
|
process.stdin.removeListener("data", onKey);
|
|
1791
1943
|
process.stdin.pause();
|
|
1792
|
-
|
|
1944
|
+
if (shouldStopServer) {
|
|
1945
|
+
stopMCPServer();
|
|
1946
|
+
}
|
|
1793
1947
|
console.log("");
|
|
1794
1948
|
};
|
|
1795
1949
|
const onKey = async (key) => {
|
|
1796
1950
|
if (key === "" || key.toLowerCase() === "q") {
|
|
1797
|
-
cleanup();
|
|
1951
|
+
cleanup(true);
|
|
1798
1952
|
resolve();
|
|
1799
1953
|
return;
|
|
1800
1954
|
}
|
|
1801
1955
|
if (key.toLowerCase() === "p") {
|
|
1802
|
-
cleanup();
|
|
1956
|
+
cleanup(false);
|
|
1803
1957
|
console.clear();
|
|
1804
1958
|
await handleConfigure();
|
|
1959
|
+
await handleStartServer();
|
|
1805
1960
|
resolve();
|
|
1806
1961
|
return;
|
|
1807
1962
|
}
|
|
1808
1963
|
if (key.toLowerCase() === "i") {
|
|
1809
|
-
cleanup();
|
|
1964
|
+
cleanup(false);
|
|
1810
1965
|
console.clear();
|
|
1811
|
-
await handleInstallWizard(
|
|
1966
|
+
await handleInstallWizard(detectWorkspaceRoot());
|
|
1967
|
+
await handleStartServer();
|
|
1812
1968
|
resolve();
|
|
1813
1969
|
return;
|
|
1814
1970
|
}
|
|
@@ -1837,7 +1993,7 @@ async function handleStartServer() {
|
|
|
1837
1993
|
}
|
|
1838
1994
|
};
|
|
1839
1995
|
process.stdin.on("data", onKey);
|
|
1840
|
-
|
|
1996
|
+
interval = setInterval(() => {
|
|
1841
1997
|
if (!isRunning) return;
|
|
1842
1998
|
if (fs16.existsSync(logPath)) {
|
|
1843
1999
|
const stats = fs16.statSync(logPath);
|
|
@@ -1862,7 +2018,7 @@ async function handleStartServer() {
|
|
|
1862
2018
|
if (process.stdin.setRawMode) {
|
|
1863
2019
|
process.stdin.setRawMode(false);
|
|
1864
2020
|
}
|
|
1865
|
-
console.error(
|
|
2021
|
+
console.error(pc3.red("\nFailed to start/monitor server:"));
|
|
1866
2022
|
console.error(error);
|
|
1867
2023
|
}
|
|
1868
2024
|
}
|
|
@@ -1870,11 +2026,11 @@ async function handleConfigureGlobalPath() {
|
|
|
1870
2026
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
1871
2027
|
const fs16 = await import("fs");
|
|
1872
2028
|
const path16 = await import("path");
|
|
1873
|
-
|
|
1874
|
-
`MCP Hub requires a ${
|
|
2029
|
+
note2(
|
|
2030
|
+
`MCP Hub requires a ${pc3.bold("global storage path")} to store its configuration
|
|
1875
2031
|
and coordinate across projects.
|
|
1876
2032
|
|
|
1877
|
-
Your current setup uses ${
|
|
2033
|
+
Your current setup uses ${pc3.cyan("workspace")} mode, which stores data
|
|
1878
2034
|
locally in each project. MCP needs a central location.`,
|
|
1879
2035
|
"Global Path Required"
|
|
1880
2036
|
);
|
|
@@ -1888,8 +2044,8 @@ locally in each project. MCP needs a central location.`,
|
|
|
1888
2044
|
}
|
|
1889
2045
|
const config = loadMCPConfig();
|
|
1890
2046
|
saveMCPConfig(config);
|
|
1891
|
-
|
|
1892
|
-
`${
|
|
2047
|
+
note2(
|
|
2048
|
+
`${pc3.green("\u2713")} Global path configured: ${pc3.cyan(resolvedPath)}
|
|
1893
2049
|
|
|
1894
2050
|
MCP config will be stored at:
|
|
1895
2051
|
${path16.join(resolvedPath, "mcp.yaml")}`,
|
|
@@ -1897,15 +2053,15 @@ ${path16.join(resolvedPath, "mcp.yaml")}`,
|
|
|
1897
2053
|
);
|
|
1898
2054
|
return true;
|
|
1899
2055
|
} catch (error) {
|
|
1900
|
-
|
|
1901
|
-
`${
|
|
2056
|
+
note2(
|
|
2057
|
+
`${pc3.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
|
|
1902
2058
|
"Error"
|
|
1903
2059
|
);
|
|
1904
2060
|
return false;
|
|
1905
2061
|
}
|
|
1906
2062
|
}
|
|
1907
2063
|
async function handleShowStatus() {
|
|
1908
|
-
const s =
|
|
2064
|
+
const s = spinner();
|
|
1909
2065
|
s.start("Loading projects...");
|
|
1910
2066
|
const config = loadMCPConfig();
|
|
1911
2067
|
const projects = scanForProjects();
|
|
@@ -1913,47 +2069,47 @@ async function handleShowStatus() {
|
|
|
1913
2069
|
const installStatus = checkInstallStatus(workspacePath);
|
|
1914
2070
|
s.stop("Projects loaded");
|
|
1915
2071
|
if (projects.length === 0) {
|
|
1916
|
-
|
|
2072
|
+
note2('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
1917
2073
|
return;
|
|
1918
2074
|
}
|
|
1919
2075
|
const lines = [
|
|
1920
|
-
`${
|
|
2076
|
+
`${pc3.bold("Installation Status")}`,
|
|
1921
2077
|
"",
|
|
1922
|
-
` Antigravity: ${installStatus.antigravity ?
|
|
1923
|
-
` VSCode (Global): ${installStatus.vscodeGlobal ?
|
|
1924
|
-
` VSCode (Workspace): ${installStatus.vscodeWorkspace ?
|
|
1925
|
-
` Claude Desktop: ${installStatus.claude ?
|
|
2078
|
+
` Antigravity: ${installStatus.antigravity ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
|
|
2079
|
+
` VSCode (Global): ${installStatus.vscodeGlobal ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
|
|
2080
|
+
` VSCode (Workspace): ${installStatus.vscodeWorkspace ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
|
|
2081
|
+
` Claude Desktop: ${installStatus.claude ? pc3.green("\u2713 Installed") : pc3.dim("Not installed")}`,
|
|
1926
2082
|
"",
|
|
1927
|
-
`${
|
|
2083
|
+
`${pc3.bold("Project Status")}`,
|
|
1928
2084
|
""
|
|
1929
2085
|
];
|
|
1930
2086
|
for (const project of projects) {
|
|
1931
2087
|
const projectConfig = config.projects.find((p) => p.name === project.name);
|
|
1932
2088
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
1933
|
-
const status = isExposed ?
|
|
1934
|
-
const source =
|
|
2089
|
+
const status = isExposed ? pc3.green("\u2713 exposed") : pc3.dim("\u25CB hidden");
|
|
2090
|
+
const source = pc3.dim(`(${project.source})`);
|
|
1935
2091
|
lines.push(` ${status} ${project.name} ${source}`);
|
|
1936
2092
|
}
|
|
1937
2093
|
lines.push("");
|
|
1938
|
-
lines.push(
|
|
2094
|
+
lines.push(pc3.dim(`Config: ${getMCPConfigPath()}`));
|
|
1939
2095
|
const serverStatus = getMCPServerStatus();
|
|
1940
2096
|
if (serverStatus.running) {
|
|
1941
|
-
lines.push(
|
|
2097
|
+
lines.push(pc3.green(`Server: running on port ${serverStatus.port}`));
|
|
1942
2098
|
} else {
|
|
1943
|
-
lines.push(
|
|
2099
|
+
lines.push(pc3.dim("Server: not running"));
|
|
1944
2100
|
}
|
|
1945
|
-
|
|
2101
|
+
note2(lines.join("\n"), "MCP Hub Status");
|
|
1946
2102
|
}
|
|
1947
2103
|
async function handleConfigure() {
|
|
1948
2104
|
const { logger: logger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
1949
|
-
const s =
|
|
2105
|
+
const s = spinner();
|
|
1950
2106
|
s.start("Scanning for projects...");
|
|
1951
2107
|
const config = loadMCPConfig();
|
|
1952
2108
|
const projects = scanForProjects();
|
|
1953
2109
|
logger2.info("Configure: Loaded config", { projects: config.projects, defaultMode: config.defaults.includeNew });
|
|
1954
2110
|
s.stop("Projects found");
|
|
1955
2111
|
if (projects.length === 0) {
|
|
1956
|
-
|
|
2112
|
+
note2('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
1957
2113
|
return;
|
|
1958
2114
|
}
|
|
1959
2115
|
const options = projects.map((project) => {
|
|
@@ -1961,7 +2117,7 @@ async function handleConfigure() {
|
|
|
1961
2117
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
1962
2118
|
return {
|
|
1963
2119
|
value: project.name,
|
|
1964
|
-
label: `${project.name} ${
|
|
2120
|
+
label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
|
|
1965
2121
|
hint: project.dataPath
|
|
1966
2122
|
};
|
|
1967
2123
|
});
|
|
@@ -1969,13 +2125,13 @@ async function handleConfigure() {
|
|
|
1969
2125
|
const cfg = config.projects.find((c) => c.name === p.name);
|
|
1970
2126
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
1971
2127
|
}).map((p) => p.name);
|
|
1972
|
-
const selected = await
|
|
2128
|
+
const selected = await multiselect({
|
|
1973
2129
|
message: "Select projects to expose via MCP:",
|
|
1974
2130
|
options,
|
|
1975
2131
|
initialValues: currentlyExposed,
|
|
1976
2132
|
required: false
|
|
1977
2133
|
});
|
|
1978
|
-
if (
|
|
2134
|
+
if (isCancel2(selected)) {
|
|
1979
2135
|
return;
|
|
1980
2136
|
}
|
|
1981
2137
|
const selectedNames = selected;
|
|
@@ -1987,8 +2143,8 @@ async function handleConfigure() {
|
|
|
1987
2143
|
saveMCPConfig(config);
|
|
1988
2144
|
logger2.info("Configure: Config saved", config);
|
|
1989
2145
|
const exposedCount = selectedNames.length;
|
|
1990
|
-
|
|
1991
|
-
`${
|
|
2146
|
+
note2(
|
|
2147
|
+
`${pc3.green("\u2713")} Configuration saved!
|
|
1992
2148
|
|
|
1993
2149
|
Exposed projects: ${exposedCount}
|
|
1994
2150
|
Hidden projects: ${projects.length - exposedCount}`,
|
|
@@ -1998,57 +2154,57 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
1998
2154
|
async function handleStopServer() {
|
|
1999
2155
|
const status = getMCPServerStatus();
|
|
2000
2156
|
if (!status.running) {
|
|
2001
|
-
|
|
2157
|
+
note2("MCP server is not running.", "Status");
|
|
2002
2158
|
return;
|
|
2003
2159
|
}
|
|
2004
|
-
const confirmed = await
|
|
2160
|
+
const confirmed = await confirm({
|
|
2005
2161
|
message: "Stop the MCP server?",
|
|
2006
2162
|
initialValue: true
|
|
2007
2163
|
});
|
|
2008
|
-
if (
|
|
2164
|
+
if (isCancel2(confirmed) || !confirmed) {
|
|
2009
2165
|
return;
|
|
2010
2166
|
}
|
|
2011
2167
|
stopMCPServer();
|
|
2012
|
-
|
|
2168
|
+
note2(pc3.green("MCP server stopped."), "Server Stopped");
|
|
2013
2169
|
}
|
|
2014
2170
|
function showHelp() {
|
|
2015
2171
|
const help = `
|
|
2016
|
-
${
|
|
2172
|
+
${pc3.bold("RRCE MCP Hub")} - Cross-project AI assistant server
|
|
2017
2173
|
|
|
2018
|
-
${
|
|
2174
|
+
${pc3.bold("ABOUT")}
|
|
2019
2175
|
MCP (Model Context Protocol) allows AI assistants like Claude to
|
|
2020
2176
|
access your project knowledge in real-time. The RRCE MCP Hub
|
|
2021
2177
|
provides a central server that exposes selected projects.
|
|
2022
2178
|
|
|
2023
|
-
${
|
|
2024
|
-
${
|
|
2025
|
-
${
|
|
2026
|
-
${
|
|
2027
|
-
${
|
|
2179
|
+
${pc3.bold("MENU OPTIONS")}
|
|
2180
|
+
${pc3.cyan("Start MCP server")} Start the server for AI access
|
|
2181
|
+
${pc3.cyan("Configure projects")} Choose which projects to expose
|
|
2182
|
+
${pc3.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
|
|
2183
|
+
${pc3.cyan("View status")} See which projects are exposed
|
|
2028
2184
|
|
|
2029
|
-
${
|
|
2030
|
-
${
|
|
2031
|
-
${
|
|
2032
|
-
${
|
|
2033
|
-
${
|
|
2185
|
+
${pc3.bold("DIRECT COMMANDS")}
|
|
2186
|
+
${pc3.dim("rrce-workflow mcp start")} Start server directly
|
|
2187
|
+
${pc3.dim("rrce-workflow mcp stop")} Stop server directly
|
|
2188
|
+
${pc3.dim("rrce-workflow mcp status")} Show status directly
|
|
2189
|
+
${pc3.dim("rrce-workflow mcp help")} Show this help
|
|
2034
2190
|
|
|
2035
|
-
${
|
|
2036
|
-
${
|
|
2037
|
-
${
|
|
2038
|
-
${
|
|
2039
|
-
${
|
|
2191
|
+
${pc3.bold("IDE INSTALLATION")}
|
|
2192
|
+
${pc3.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
|
|
2193
|
+
${pc3.cyan("VSCode Global")} ~/.config/Code/User/settings.json
|
|
2194
|
+
${pc3.cyan("VSCode Workspace")} .vscode/mcp.json
|
|
2195
|
+
${pc3.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
|
|
2040
2196
|
|
|
2041
|
-
${
|
|
2042
|
-
${
|
|
2043
|
-
${
|
|
2044
|
-
${
|
|
2197
|
+
${pc3.bold("SERVER COMMANDS")} (while running)
|
|
2198
|
+
${pc3.cyan("q")} Stop and quit ${pc3.cyan("p")} Reconfigure projects
|
|
2199
|
+
${pc3.cyan("i")} Install to IDE ${pc3.cyan("r")} Reload config
|
|
2200
|
+
${pc3.cyan("c")} Clear logs ${pc3.cyan("?")} Show help
|
|
2045
2201
|
|
|
2046
|
-
${
|
|
2047
|
-
${
|
|
2048
|
-
${
|
|
2049
|
-
${
|
|
2202
|
+
${pc3.bold("RESOURCES EXPOSED")}
|
|
2203
|
+
${pc3.cyan("rrce://projects")} List all exposed projects
|
|
2204
|
+
${pc3.cyan("rrce://projects/{name}/context")} Get project context
|
|
2205
|
+
${pc3.cyan("rrce://projects/{name}/tasks")} Get project tasks
|
|
2050
2206
|
`;
|
|
2051
|
-
|
|
2207
|
+
note2(help.trim(), "Help");
|
|
2052
2208
|
}
|
|
2053
2209
|
var init_mcp = __esm({
|
|
2054
2210
|
"src/mcp/index.ts"() {
|
|
@@ -2061,154 +2217,16 @@ var init_mcp = __esm({
|
|
|
2061
2217
|
}
|
|
2062
2218
|
});
|
|
2063
2219
|
|
|
2064
|
-
// src/commands/wizard/index.ts
|
|
2065
|
-
import { intro as intro2, select as select4, spinner as spinner6, note as note7, outro as outro6, isCancel as isCancel7 } from "@clack/prompts";
|
|
2066
|
-
import pc8 from "picocolors";
|
|
2067
|
-
import * as fs15 from "fs";
|
|
2068
|
-
|
|
2069
|
-
// src/lib/git.ts
|
|
2070
|
-
import { execSync } from "child_process";
|
|
2071
|
-
function getGitUser() {
|
|
2072
|
-
try {
|
|
2073
|
-
const result = execSync("git config user.name", { encoding: "utf-8" });
|
|
2074
|
-
return result.trim() || null;
|
|
2075
|
-
} catch {
|
|
2076
|
-
return null;
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
// src/commands/wizard/index.ts
|
|
2081
|
-
init_paths();
|
|
2082
|
-
init_detection();
|
|
2083
|
-
|
|
2084
|
-
// src/commands/wizard/setup-flow.ts
|
|
2085
|
-
init_paths();
|
|
2086
|
-
init_prompts();
|
|
2087
|
-
import { group, select as select2, multiselect, confirm, spinner, note as note2, outro, cancel } from "@clack/prompts";
|
|
2088
|
-
import pc3 from "picocolors";
|
|
2089
|
-
import * as fs7 from "fs";
|
|
2090
|
-
import * as path8 from "path";
|
|
2091
|
-
|
|
2092
|
-
// src/commands/wizard/utils.ts
|
|
2093
|
-
init_paths();
|
|
2094
|
-
import * as fs4 from "fs";
|
|
2095
|
-
import * as path4 from "path";
|
|
2096
|
-
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
2097
|
-
for (const prompt of prompts) {
|
|
2098
|
-
const baseName = path4.basename(prompt.filePath, ".md");
|
|
2099
|
-
const targetName = baseName + extension;
|
|
2100
|
-
const targetPath = path4.join(targetDir, targetName);
|
|
2101
|
-
const content = fs4.readFileSync(prompt.filePath, "utf-8");
|
|
2102
|
-
fs4.writeFileSync(targetPath, content);
|
|
2103
|
-
}
|
|
2104
|
-
}
|
|
2105
|
-
function copyDirRecursive(src, dest) {
|
|
2106
|
-
const entries = fs4.readdirSync(src, { withFileTypes: true });
|
|
2107
|
-
for (const entry of entries) {
|
|
2108
|
-
const srcPath = path4.join(src, entry.name);
|
|
2109
|
-
const destPath = path4.join(dest, entry.name);
|
|
2110
|
-
if (entry.isDirectory()) {
|
|
2111
|
-
ensureDir(destPath);
|
|
2112
|
-
copyDirRecursive(srcPath, destPath);
|
|
2113
|
-
} else {
|
|
2114
|
-
fs4.copyFileSync(srcPath, destPath);
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
|
-
|
|
2119
|
-
// src/commands/wizard/vscode.ts
|
|
2120
|
-
init_paths();
|
|
2121
|
-
init_detection();
|
|
2122
|
-
import * as fs5 from "fs";
|
|
2123
|
-
import * as path5 from "path";
|
|
2124
|
-
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
2125
|
-
const workspaceFilePath = path5.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
2126
|
-
let workspace;
|
|
2127
|
-
if (fs5.existsSync(workspaceFilePath)) {
|
|
2128
|
-
try {
|
|
2129
|
-
const content = fs5.readFileSync(workspaceFilePath, "utf-8");
|
|
2130
|
-
workspace = JSON.parse(content);
|
|
2131
|
-
} catch {
|
|
2132
|
-
workspace = { folders: [], settings: {} };
|
|
2133
|
-
}
|
|
2134
|
-
} else {
|
|
2135
|
-
workspace = { folders: [], settings: {} };
|
|
2136
|
-
}
|
|
2137
|
-
if (!workspace.settings) {
|
|
2138
|
-
workspace.settings = {};
|
|
2139
|
-
}
|
|
2140
|
-
workspace.folders = workspace.folders.filter(
|
|
2141
|
-
(f) => f.path === "." || !f.name?.startsWith("\u{1F4C1}") && !f.name?.startsWith("\u{1F4DA}") && !f.name?.startsWith("\u{1F4CE}") && !f.name?.startsWith("\u{1F4CB}")
|
|
2142
|
-
);
|
|
2143
|
-
const mainFolderIndex = workspace.folders.findIndex((f) => f.path === ".");
|
|
2144
|
-
if (mainFolderIndex === -1) {
|
|
2145
|
-
workspace.folders.unshift({
|
|
2146
|
-
path: ".",
|
|
2147
|
-
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
2148
|
-
});
|
|
2149
|
-
} else {
|
|
2150
|
-
workspace.folders[mainFolderIndex] = {
|
|
2151
|
-
path: ".",
|
|
2152
|
-
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
2153
|
-
};
|
|
2154
|
-
}
|
|
2155
|
-
const referenceFolderPaths = [];
|
|
2156
|
-
const isDetectedProjects = linkedProjects.length > 0 && typeof linkedProjects[0] === "object";
|
|
2157
|
-
if (isDetectedProjects) {
|
|
2158
|
-
const projects = linkedProjects;
|
|
2159
|
-
for (const project of projects) {
|
|
2160
|
-
const sourceLabel = project.source === "global" ? "global" : "local";
|
|
2161
|
-
const folderPath = project.dataPath;
|
|
2162
|
-
if (fs5.existsSync(folderPath)) {
|
|
2163
|
-
referenceFolderPaths.push(folderPath);
|
|
2164
|
-
workspace.folders.push({
|
|
2165
|
-
path: folderPath,
|
|
2166
|
-
name: `\u{1F4C1} ${project.name} [${sourceLabel}]`
|
|
2167
|
-
});
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
} else {
|
|
2171
|
-
const projectNames = linkedProjects;
|
|
2172
|
-
const rrceHome = customGlobalPath || getRRCEHome();
|
|
2173
|
-
for (const projectName of projectNames) {
|
|
2174
|
-
const folderPath = path5.join(rrceHome, "workspaces", projectName);
|
|
2175
|
-
if (fs5.existsSync(folderPath)) {
|
|
2176
|
-
referenceFolderPaths.push(folderPath);
|
|
2177
|
-
workspace.folders.push({
|
|
2178
|
-
path: folderPath,
|
|
2179
|
-
name: `\u{1F4C1} ${projectName} [global]`
|
|
2180
|
-
});
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
if (referenceFolderPaths.length > 0) {
|
|
2185
|
-
const readonlyPatterns = {};
|
|
2186
|
-
for (const folderPath of referenceFolderPaths) {
|
|
2187
|
-
readonlyPatterns[`${folderPath}/**`] = true;
|
|
2188
|
-
}
|
|
2189
|
-
const existingReadonly = workspace.settings["files.readonlyInclude"] || {};
|
|
2190
|
-
const cleanedReadonly = {};
|
|
2191
|
-
for (const [pattern, value] of Object.entries(existingReadonly)) {
|
|
2192
|
-
if (!pattern.includes(".rrce-workflow") && !pattern.includes("rrce-workflow/workspaces")) {
|
|
2193
|
-
cleanedReadonly[pattern] = value;
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
workspace.settings["files.readonlyInclude"] = {
|
|
2197
|
-
...cleanedReadonly,
|
|
2198
|
-
...readonlyPatterns
|
|
2199
|
-
};
|
|
2200
|
-
}
|
|
2201
|
-
fs5.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, 2));
|
|
2202
|
-
}
|
|
2203
|
-
|
|
2204
2220
|
// src/commands/wizard/setup-flow.ts
|
|
2205
|
-
|
|
2206
|
-
|
|
2221
|
+
import { group, select as select3, multiselect as multiselect2, confirm as confirm2, spinner as spinner2, note as note3, outro as outro2, cancel as cancel2, isCancel as isCancel3 } from "@clack/prompts";
|
|
2222
|
+
import pc4 from "picocolors";
|
|
2223
|
+
import * as fs11 from "fs";
|
|
2224
|
+
import * as path12 from "path";
|
|
2207
2225
|
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
2208
|
-
const s =
|
|
2226
|
+
const s = spinner2();
|
|
2209
2227
|
const config = await group(
|
|
2210
2228
|
{
|
|
2211
|
-
storageMode: () =>
|
|
2229
|
+
storageMode: () => select3({
|
|
2212
2230
|
message: "Where should workflow data be stored?",
|
|
2213
2231
|
options: [
|
|
2214
2232
|
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
|
|
@@ -2216,7 +2234,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2216
2234
|
],
|
|
2217
2235
|
initialValue: "global"
|
|
2218
2236
|
}),
|
|
2219
|
-
tools: () =>
|
|
2237
|
+
tools: () => multiselect2({
|
|
2220
2238
|
message: "Which AI tools do you use?",
|
|
2221
2239
|
options: [
|
|
2222
2240
|
{ value: "copilot", label: "GitHub Copilot", hint: "VSCode" },
|
|
@@ -2228,44 +2246,44 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2228
2246
|
if (existingProjects.length === 0) {
|
|
2229
2247
|
return Promise.resolve([]);
|
|
2230
2248
|
}
|
|
2231
|
-
return
|
|
2249
|
+
return multiselect2({
|
|
2232
2250
|
message: "Link knowledge from other projects?",
|
|
2233
2251
|
options: existingProjects.map((project) => ({
|
|
2234
2252
|
value: `${project.name}:${project.source}`,
|
|
2235
2253
|
// Unique key
|
|
2236
|
-
label: `${project.name} ${
|
|
2237
|
-
hint:
|
|
2254
|
+
label: `${project.name} ${pc4.dim(`(${project.source})`)}`,
|
|
2255
|
+
hint: pc4.dim(
|
|
2238
2256
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
2239
2257
|
)
|
|
2240
2258
|
})),
|
|
2241
2259
|
required: false
|
|
2242
2260
|
});
|
|
2243
2261
|
},
|
|
2244
|
-
addToGitignore: () =>
|
|
2262
|
+
addToGitignore: () => confirm2({
|
|
2245
2263
|
message: "Add generated folders to .gitignore? (as comments - uncomment if needed)",
|
|
2246
2264
|
initialValue: true
|
|
2247
2265
|
}),
|
|
2248
|
-
confirm: () =>
|
|
2266
|
+
confirm: () => confirm2({
|
|
2249
2267
|
message: "Create configuration?",
|
|
2250
2268
|
initialValue: true
|
|
2251
2269
|
})
|
|
2252
2270
|
},
|
|
2253
2271
|
{
|
|
2254
2272
|
onCancel: () => {
|
|
2255
|
-
|
|
2273
|
+
cancel2("Setup process cancelled.");
|
|
2256
2274
|
process.exit(0);
|
|
2257
2275
|
}
|
|
2258
2276
|
}
|
|
2259
2277
|
);
|
|
2260
2278
|
if (!config.confirm) {
|
|
2261
|
-
|
|
2279
|
+
outro2("Setup cancelled by user.");
|
|
2262
2280
|
process.exit(0);
|
|
2263
2281
|
}
|
|
2264
2282
|
let customGlobalPath;
|
|
2265
2283
|
if (config.storageMode === "global") {
|
|
2266
2284
|
customGlobalPath = await resolveGlobalPath();
|
|
2267
2285
|
if (!customGlobalPath) {
|
|
2268
|
-
|
|
2286
|
+
cancel2("Setup cancelled - no writable global path available.");
|
|
2269
2287
|
process.exit(1);
|
|
2270
2288
|
}
|
|
2271
2289
|
}
|
|
@@ -2289,7 +2307,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2289
2307
|
`Storage: ${config.storageMode}`
|
|
2290
2308
|
];
|
|
2291
2309
|
if (customGlobalPath && customGlobalPath !== getDefaultRRCEHome()) {
|
|
2292
|
-
summary.push(`Global path: ${
|
|
2310
|
+
summary.push(`Global path: ${pc4.cyan(customGlobalPath)}`);
|
|
2293
2311
|
}
|
|
2294
2312
|
if (dataPaths.length > 0) {
|
|
2295
2313
|
summary.push(`Data paths:`);
|
|
@@ -2302,17 +2320,26 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2302
2320
|
const linkedProjects = config.linkedProjects;
|
|
2303
2321
|
if (linkedProjects.length > 0) {
|
|
2304
2322
|
summary.push(`Linked projects: ${linkedProjects.join(", ")}`);
|
|
2305
|
-
summary.push(`Workspace file: ${
|
|
2323
|
+
summary.push(`Workspace file: ${pc4.cyan(`${workspaceName}.code-workspace`)}`);
|
|
2306
2324
|
}
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2325
|
+
note3(summary.join("\n"), "Setup Summary");
|
|
2326
|
+
const shouldConfigureMCP = await confirm2({
|
|
2327
|
+
message: "Would you like to configure the MCP server now?",
|
|
2328
|
+
initialValue: true
|
|
2329
|
+
});
|
|
2330
|
+
if (shouldConfigureMCP && !isCancel3(shouldConfigureMCP)) {
|
|
2331
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
2332
|
+
await runMCP2();
|
|
2310
2333
|
} else {
|
|
2311
|
-
|
|
2334
|
+
if (linkedProjects.length > 0) {
|
|
2335
|
+
outro2(pc4.green(`\u2713 Setup complete! Open ${pc4.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
2336
|
+
} else {
|
|
2337
|
+
outro2(pc4.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
2338
|
+
}
|
|
2312
2339
|
}
|
|
2313
2340
|
} catch (error) {
|
|
2314
2341
|
s.stop("Error occurred");
|
|
2315
|
-
|
|
2342
|
+
cancel2(`Failed to setup: ${error instanceof Error ? error.message : String(error)}`);
|
|
2316
2343
|
process.exit(1);
|
|
2317
2344
|
}
|
|
2318
2345
|
}
|
|
@@ -2320,14 +2347,14 @@ async function generateConfiguration(config, workspacePath, workspaceName, allPr
|
|
|
2320
2347
|
const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
2321
2348
|
for (const dataPath of dataPaths) {
|
|
2322
2349
|
ensureDir(dataPath);
|
|
2323
|
-
ensureDir(
|
|
2324
|
-
ensureDir(
|
|
2325
|
-
ensureDir(
|
|
2326
|
-
ensureDir(
|
|
2350
|
+
ensureDir(path12.join(dataPath, "knowledge"));
|
|
2351
|
+
ensureDir(path12.join(dataPath, "refs"));
|
|
2352
|
+
ensureDir(path12.join(dataPath, "tasks"));
|
|
2353
|
+
ensureDir(path12.join(dataPath, "templates"));
|
|
2327
2354
|
}
|
|
2328
2355
|
const agentCoreDir = getAgentCoreDir();
|
|
2329
2356
|
syncMetadataToAll(agentCoreDir, dataPaths);
|
|
2330
|
-
copyDirToAllStoragePaths(
|
|
2357
|
+
copyDirToAllStoragePaths(path12.join(agentCoreDir, "templates"), "templates", dataPaths);
|
|
2331
2358
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
2332
2359
|
if (config.tools.includes("copilot")) {
|
|
2333
2360
|
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
@@ -2339,8 +2366,8 @@ async function generateConfiguration(config, workspacePath, workspaceName, allPr
|
|
|
2339
2366
|
ensureDir(antigravityPath);
|
|
2340
2367
|
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
2341
2368
|
}
|
|
2342
|
-
const workspaceConfigPath =
|
|
2343
|
-
ensureDir(
|
|
2369
|
+
const workspaceConfigPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
2370
|
+
ensureDir(path12.dirname(workspaceConfigPath));
|
|
2344
2371
|
let configContent = `# RRCE-Workflow Configuration
|
|
2345
2372
|
version: 1
|
|
2346
2373
|
|
|
@@ -2368,7 +2395,7 @@ linked_projects:
|
|
|
2368
2395
|
`;
|
|
2369
2396
|
});
|
|
2370
2397
|
}
|
|
2371
|
-
|
|
2398
|
+
fs11.writeFileSync(workspaceConfigPath, configContent);
|
|
2372
2399
|
if (config.addToGitignore) {
|
|
2373
2400
|
updateGitignore(workspacePath, config.storageMode, config.tools);
|
|
2374
2401
|
}
|
|
@@ -2380,8 +2407,8 @@ linked_projects:
|
|
|
2380
2407
|
}
|
|
2381
2408
|
}
|
|
2382
2409
|
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
2383
|
-
const globalPath =
|
|
2384
|
-
const workspacePath =
|
|
2410
|
+
const globalPath = path12.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
|
|
2411
|
+
const workspacePath = path12.join(workspaceRoot, ".rrce-workflow");
|
|
2385
2412
|
switch (mode) {
|
|
2386
2413
|
case "global":
|
|
2387
2414
|
return [globalPath];
|
|
@@ -2392,7 +2419,7 @@ function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
|
2392
2419
|
}
|
|
2393
2420
|
}
|
|
2394
2421
|
function updateGitignore(workspacePath, storageMode, tools) {
|
|
2395
|
-
const gitignorePath =
|
|
2422
|
+
const gitignorePath = path12.join(workspacePath, ".gitignore");
|
|
2396
2423
|
const entries = [];
|
|
2397
2424
|
if (storageMode === "workspace") {
|
|
2398
2425
|
entries.push(".rrce-workflow/");
|
|
@@ -2408,8 +2435,8 @@ function updateGitignore(workspacePath, storageMode, tools) {
|
|
|
2408
2435
|
}
|
|
2409
2436
|
try {
|
|
2410
2437
|
let content = "";
|
|
2411
|
-
if (
|
|
2412
|
-
content =
|
|
2438
|
+
if (fs11.existsSync(gitignorePath)) {
|
|
2439
|
+
content = fs11.readFileSync(gitignorePath, "utf-8");
|
|
2413
2440
|
}
|
|
2414
2441
|
const lines = content.split("\n").map((line) => line.trim());
|
|
2415
2442
|
const newEntries = [];
|
|
@@ -2434,57 +2461,66 @@ function updateGitignore(workspacePath, storageMode, tools) {
|
|
|
2434
2461
|
newContent += "\n# rrce-workflow generated folders (uncomment to ignore)\n";
|
|
2435
2462
|
}
|
|
2436
2463
|
newContent += newEntries.map((e) => `# ${e}`).join("\n") + "\n";
|
|
2437
|
-
|
|
2464
|
+
fs11.writeFileSync(gitignorePath, newContent);
|
|
2438
2465
|
return true;
|
|
2439
2466
|
} catch {
|
|
2440
2467
|
return false;
|
|
2441
2468
|
}
|
|
2442
2469
|
}
|
|
2470
|
+
var init_setup_flow = __esm({
|
|
2471
|
+
"src/commands/wizard/setup-flow.ts"() {
|
|
2472
|
+
"use strict";
|
|
2473
|
+
init_paths();
|
|
2474
|
+
init_prompts();
|
|
2475
|
+
init_utils();
|
|
2476
|
+
init_vscode();
|
|
2477
|
+
init_detection();
|
|
2478
|
+
init_tui_utils();
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2443
2481
|
|
|
2444
2482
|
// src/commands/wizard/link-flow.ts
|
|
2445
|
-
|
|
2446
|
-
import
|
|
2447
|
-
import
|
|
2448
|
-
import * as fs8 from "fs";
|
|
2449
|
-
init_detection();
|
|
2483
|
+
import { multiselect as multiselect3, spinner as spinner3, note as note4, outro as outro3, cancel as cancel3, isCancel as isCancel4 } from "@clack/prompts";
|
|
2484
|
+
import pc5 from "picocolors";
|
|
2485
|
+
import * as fs12 from "fs";
|
|
2450
2486
|
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
2451
2487
|
const projects = scanForProjects({
|
|
2452
2488
|
excludeWorkspace: workspaceName,
|
|
2453
2489
|
workspacePath
|
|
2454
2490
|
});
|
|
2455
2491
|
if (projects.length === 0) {
|
|
2456
|
-
|
|
2492
|
+
outro3(pc5.yellow("No other projects found. Try setting up another project first."));
|
|
2457
2493
|
return;
|
|
2458
2494
|
}
|
|
2459
2495
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
2460
|
-
const linkedProjects = await
|
|
2496
|
+
const linkedProjects = await multiselect3({
|
|
2461
2497
|
message: "Select projects to link:",
|
|
2462
2498
|
options: projects.map((project) => ({
|
|
2463
2499
|
value: `${project.name}:${project.source}`,
|
|
2464
2500
|
// Unique key
|
|
2465
|
-
label: `${project.name} ${
|
|
2466
|
-
hint:
|
|
2501
|
+
label: `${project.name} ${pc5.dim(`(${project.source})`)}`,
|
|
2502
|
+
hint: pc5.dim(
|
|
2467
2503
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
2468
2504
|
)
|
|
2469
2505
|
})),
|
|
2470
2506
|
required: true
|
|
2471
2507
|
});
|
|
2472
|
-
if (
|
|
2473
|
-
|
|
2508
|
+
if (isCancel4(linkedProjects)) {
|
|
2509
|
+
cancel3("Cancelled.");
|
|
2474
2510
|
process.exit(0);
|
|
2475
2511
|
}
|
|
2476
2512
|
const selectedKeys = linkedProjects;
|
|
2477
2513
|
if (selectedKeys.length === 0) {
|
|
2478
|
-
|
|
2514
|
+
outro3("No projects selected.");
|
|
2479
2515
|
return;
|
|
2480
2516
|
}
|
|
2481
2517
|
const selectedProjects = projects.filter(
|
|
2482
2518
|
(p) => selectedKeys.includes(`${p.name}:${p.source}`)
|
|
2483
2519
|
);
|
|
2484
|
-
const s =
|
|
2520
|
+
const s = spinner3();
|
|
2485
2521
|
s.start("Linking projects");
|
|
2486
2522
|
const configFilePath = getConfigPath(workspacePath);
|
|
2487
|
-
let configContent =
|
|
2523
|
+
let configContent = fs12.readFileSync(configFilePath, "utf-8");
|
|
2488
2524
|
if (configContent.includes("linked_projects:")) {
|
|
2489
2525
|
const lines = configContent.split("\n");
|
|
2490
2526
|
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
@@ -2511,60 +2547,67 @@ linked_projects:
|
|
|
2511
2547
|
`;
|
|
2512
2548
|
});
|
|
2513
2549
|
}
|
|
2514
|
-
|
|
2550
|
+
fs12.writeFileSync(configFilePath, configContent);
|
|
2515
2551
|
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
2516
2552
|
s.stop("Projects linked");
|
|
2517
2553
|
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
2518
2554
|
const summary = [
|
|
2519
2555
|
`Linked projects:`,
|
|
2520
|
-
...selectedProjects.map((p) => ` \u2713 ${p.name} ${
|
|
2556
|
+
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc5.dim(`(${p.source})`)}`),
|
|
2521
2557
|
``,
|
|
2522
|
-
`Workspace file: ${
|
|
2558
|
+
`Workspace file: ${pc5.cyan(workspaceFile)}`
|
|
2523
2559
|
];
|
|
2524
|
-
|
|
2525
|
-
|
|
2560
|
+
note4(summary.join("\n"), "Link Summary");
|
|
2561
|
+
outro3(pc5.green(`\u2713 Projects linked! Open ${pc5.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
2526
2562
|
}
|
|
2563
|
+
var init_link_flow = __esm({
|
|
2564
|
+
"src/commands/wizard/link-flow.ts"() {
|
|
2565
|
+
"use strict";
|
|
2566
|
+
init_paths();
|
|
2567
|
+
init_vscode();
|
|
2568
|
+
init_detection();
|
|
2569
|
+
}
|
|
2570
|
+
});
|
|
2527
2571
|
|
|
2528
2572
|
// src/commands/wizard/sync-flow.ts
|
|
2529
|
-
|
|
2530
|
-
import
|
|
2531
|
-
import
|
|
2532
|
-
import * as
|
|
2533
|
-
import * as path9 from "path";
|
|
2573
|
+
import { confirm as confirm3, spinner as spinner4, note as note5, outro as outro4, cancel as cancel4, isCancel as isCancel5 } from "@clack/prompts";
|
|
2574
|
+
import pc6 from "picocolors";
|
|
2575
|
+
import * as fs13 from "fs";
|
|
2576
|
+
import * as path13 from "path";
|
|
2534
2577
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
2535
2578
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
2536
2579
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
2537
|
-
const globalPath =
|
|
2580
|
+
const globalPath = path13.join(customGlobalPath, "workspaces", workspaceName);
|
|
2538
2581
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
2539
2582
|
const existingDirs = subdirs.filter(
|
|
2540
|
-
(dir) =>
|
|
2583
|
+
(dir) => fs13.existsSync(path13.join(localPath, dir))
|
|
2541
2584
|
);
|
|
2542
2585
|
if (existingDirs.length === 0) {
|
|
2543
|
-
|
|
2586
|
+
outro4(pc6.yellow("No data found in workspace storage to sync."));
|
|
2544
2587
|
return;
|
|
2545
2588
|
}
|
|
2546
|
-
|
|
2589
|
+
note5(
|
|
2547
2590
|
`The following will be copied to global storage:
|
|
2548
2591
|
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
2549
2592
|
|
|
2550
|
-
Destination: ${
|
|
2593
|
+
Destination: ${pc6.cyan(globalPath)}`,
|
|
2551
2594
|
"Sync Preview"
|
|
2552
2595
|
);
|
|
2553
|
-
const shouldSync = await
|
|
2596
|
+
const shouldSync = await confirm3({
|
|
2554
2597
|
message: "Proceed with sync to global storage?",
|
|
2555
2598
|
initialValue: true
|
|
2556
2599
|
});
|
|
2557
|
-
if (
|
|
2558
|
-
|
|
2600
|
+
if (isCancel5(shouldSync) || !shouldSync) {
|
|
2601
|
+
outro4("Sync cancelled.");
|
|
2559
2602
|
return;
|
|
2560
2603
|
}
|
|
2561
|
-
const s =
|
|
2604
|
+
const s = spinner4();
|
|
2562
2605
|
s.start("Syncing to global storage");
|
|
2563
2606
|
try {
|
|
2564
2607
|
ensureDir(globalPath);
|
|
2565
2608
|
for (const dir of existingDirs) {
|
|
2566
|
-
const srcDir =
|
|
2567
|
-
const destDir =
|
|
2609
|
+
const srcDir = path13.join(localPath, dir);
|
|
2610
|
+
const destDir = path13.join(globalPath, dir);
|
|
2568
2611
|
ensureDir(destDir);
|
|
2569
2612
|
copyDirRecursive(srcDir, destDir);
|
|
2570
2613
|
}
|
|
@@ -2573,28 +2616,33 @@ Destination: ${pc5.cyan(globalPath)}`,
|
|
|
2573
2616
|
`Synced directories:`,
|
|
2574
2617
|
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
2575
2618
|
``,
|
|
2576
|
-
`Global path: ${
|
|
2619
|
+
`Global path: ${pc6.cyan(globalPath)}`,
|
|
2577
2620
|
``,
|
|
2578
2621
|
`Other projects can now link this knowledge!`
|
|
2579
2622
|
];
|
|
2580
|
-
|
|
2581
|
-
|
|
2623
|
+
note5(summary.join("\n"), "Sync Summary");
|
|
2624
|
+
outro4(pc6.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
2582
2625
|
} catch (error) {
|
|
2583
2626
|
s.stop("Error occurred");
|
|
2584
|
-
|
|
2627
|
+
cancel4(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
2585
2628
|
process.exit(1);
|
|
2586
2629
|
}
|
|
2587
2630
|
}
|
|
2631
|
+
var init_sync_flow = __esm({
|
|
2632
|
+
"src/commands/wizard/sync-flow.ts"() {
|
|
2633
|
+
"use strict";
|
|
2634
|
+
init_paths();
|
|
2635
|
+
init_utils();
|
|
2636
|
+
}
|
|
2637
|
+
});
|
|
2588
2638
|
|
|
2589
2639
|
// src/commands/wizard/update-flow.ts
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
import
|
|
2593
|
-
import
|
|
2594
|
-
import * as fs10 from "fs";
|
|
2595
|
-
import * as path10 from "path";
|
|
2640
|
+
import { confirm as confirm4, spinner as spinner5, note as note6, outro as outro5, cancel as cancel5, isCancel as isCancel6 } from "@clack/prompts";
|
|
2641
|
+
import pc7 from "picocolors";
|
|
2642
|
+
import * as fs14 from "fs";
|
|
2643
|
+
import * as path14 from "path";
|
|
2596
2644
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
2597
|
-
const s =
|
|
2645
|
+
const s = spinner5();
|
|
2598
2646
|
s.start("Checking for updates");
|
|
2599
2647
|
try {
|
|
2600
2648
|
const agentCoreDir = getAgentCoreDir();
|
|
@@ -2603,7 +2651,7 @@ async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
|
2603
2651
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
2604
2652
|
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
2605
2653
|
s.stop("Updates found");
|
|
2606
|
-
|
|
2654
|
+
note6(
|
|
2607
2655
|
`The following will be updated from the package:
|
|
2608
2656
|
\u2022 prompts/ (${prompts.length} agent prompts)
|
|
2609
2657
|
\u2022 templates/ (output templates)
|
|
@@ -2612,20 +2660,20 @@ Target locations:
|
|
|
2612
2660
|
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
2613
2661
|
"Update Preview"
|
|
2614
2662
|
);
|
|
2615
|
-
const shouldUpdate = await
|
|
2663
|
+
const shouldUpdate = await confirm4({
|
|
2616
2664
|
message: "Proceed with update?",
|
|
2617
2665
|
initialValue: true
|
|
2618
2666
|
});
|
|
2619
|
-
if (
|
|
2620
|
-
|
|
2667
|
+
if (isCancel6(shouldUpdate) || !shouldUpdate) {
|
|
2668
|
+
outro5("Update cancelled.");
|
|
2621
2669
|
return;
|
|
2622
2670
|
}
|
|
2623
2671
|
s.start("Updating from package");
|
|
2624
2672
|
for (const dataPath of dataPaths) {
|
|
2625
|
-
copyDirToAllStoragePaths(
|
|
2673
|
+
copyDirToAllStoragePaths(path14.join(agentCoreDir, "templates"), "templates", [dataPath]);
|
|
2626
2674
|
}
|
|
2627
2675
|
const configFilePath = getConfigPath(workspacePath);
|
|
2628
|
-
const configContent =
|
|
2676
|
+
const configContent = fs14.readFileSync(configFilePath, "utf-8");
|
|
2629
2677
|
if (configContent.includes("copilot: true")) {
|
|
2630
2678
|
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
2631
2679
|
ensureDir(copilotPath);
|
|
@@ -2644,17 +2692,17 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
2644
2692
|
``,
|
|
2645
2693
|
`Your configuration and knowledge files were preserved.`
|
|
2646
2694
|
];
|
|
2647
|
-
|
|
2648
|
-
|
|
2695
|
+
note6(summary.join("\n"), "Update Summary");
|
|
2696
|
+
outro5(pc7.green("\u2713 Successfully updated from package!"));
|
|
2649
2697
|
} catch (error) {
|
|
2650
2698
|
s.stop("Error occurred");
|
|
2651
|
-
|
|
2699
|
+
cancel5(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
2652
2700
|
process.exit(1);
|
|
2653
2701
|
}
|
|
2654
2702
|
}
|
|
2655
2703
|
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
2656
|
-
const globalPath =
|
|
2657
|
-
const workspacePath =
|
|
2704
|
+
const globalPath = path14.join(customGlobalPath, "workspaces", workspaceName);
|
|
2705
|
+
const workspacePath = path14.join(workspaceRoot, ".rrce-workflow");
|
|
2658
2706
|
switch (mode) {
|
|
2659
2707
|
case "global":
|
|
2660
2708
|
return [globalPath];
|
|
@@ -2664,9 +2712,23 @@ function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot,
|
|
|
2664
2712
|
return [globalPath];
|
|
2665
2713
|
}
|
|
2666
2714
|
}
|
|
2715
|
+
var init_update_flow = __esm({
|
|
2716
|
+
"src/commands/wizard/update-flow.ts"() {
|
|
2717
|
+
"use strict";
|
|
2718
|
+
init_paths();
|
|
2719
|
+
init_prompts();
|
|
2720
|
+
init_utils();
|
|
2721
|
+
}
|
|
2722
|
+
});
|
|
2667
2723
|
|
|
2668
2724
|
// src/commands/wizard/index.ts
|
|
2669
|
-
|
|
2725
|
+
var wizard_exports = {};
|
|
2726
|
+
__export(wizard_exports, {
|
|
2727
|
+
runWizard: () => runWizard
|
|
2728
|
+
});
|
|
2729
|
+
import { intro as intro2, select as select4, spinner as spinner6, note as note7, outro as outro6, isCancel as isCancel7 } from "@clack/prompts";
|
|
2730
|
+
import pc8 from "picocolors";
|
|
2731
|
+
import * as fs15 from "fs";
|
|
2670
2732
|
async function runWizard() {
|
|
2671
2733
|
intro2(pc8.cyan(pc8.inverse(" RRCE-Workflow Setup ")));
|
|
2672
2734
|
const s = spinner6();
|
|
@@ -2748,6 +2810,22 @@ Workspace: ${pc8.bold(workspaceName)}`,
|
|
|
2748
2810
|
}
|
|
2749
2811
|
await runSetupFlow(workspacePath, workspaceName, detectedProjects);
|
|
2750
2812
|
}
|
|
2813
|
+
var init_wizard = __esm({
|
|
2814
|
+
"src/commands/wizard/index.ts"() {
|
|
2815
|
+
"use strict";
|
|
2816
|
+
init_git();
|
|
2817
|
+
init_paths();
|
|
2818
|
+
init_detection();
|
|
2819
|
+
init_setup_flow();
|
|
2820
|
+
init_link_flow();
|
|
2821
|
+
init_sync_flow();
|
|
2822
|
+
init_update_flow();
|
|
2823
|
+
init_mcp();
|
|
2824
|
+
}
|
|
2825
|
+
});
|
|
2826
|
+
|
|
2827
|
+
// src/index.ts
|
|
2828
|
+
init_wizard();
|
|
2751
2829
|
|
|
2752
2830
|
// src/commands/selector.ts
|
|
2753
2831
|
init_prompts();
|
|
@@ -2767,9 +2845,14 @@ async function runSelector() {
|
|
|
2767
2845
|
options: [
|
|
2768
2846
|
{
|
|
2769
2847
|
value: "mcp",
|
|
2770
|
-
label: "Manage MCP Hub",
|
|
2848
|
+
label: "\u{1F50C} Manage MCP Hub",
|
|
2771
2849
|
hint: "Configure & Start MCP Server"
|
|
2772
2850
|
},
|
|
2851
|
+
{
|
|
2852
|
+
value: "wizard",
|
|
2853
|
+
label: "\u2728 Run Setup Wizard",
|
|
2854
|
+
hint: "Configure workspace & agents"
|
|
2855
|
+
},
|
|
2773
2856
|
...prompts.map((p) => ({
|
|
2774
2857
|
value: p,
|
|
2775
2858
|
label: p.frontmatter.name,
|
|
@@ -2786,6 +2869,11 @@ async function runSelector() {
|
|
|
2786
2869
|
await runMCP2();
|
|
2787
2870
|
return;
|
|
2788
2871
|
}
|
|
2872
|
+
if (selection === "wizard") {
|
|
2873
|
+
const { runWizard: runWizard2 } = await Promise.resolve().then(() => (init_wizard(), wizard_exports));
|
|
2874
|
+
await runWizard2();
|
|
2875
|
+
return;
|
|
2876
|
+
}
|
|
2789
2877
|
const prompt = selection;
|
|
2790
2878
|
note8(
|
|
2791
2879
|
`Use this agent in your IDE by invoking:
|