rrce-workflow 0.2.49 → 0.2.51
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 +1034 -1119
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -25,29 +25,6 @@ var init_git = __esm({
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
// src/lib/paths.ts
|
|
28
|
-
var paths_exports = {};
|
|
29
|
-
__export(paths_exports, {
|
|
30
|
-
checkWriteAccess: () => checkWriteAccess,
|
|
31
|
-
copyDirToAllStoragePaths: () => copyDirToAllStoragePaths,
|
|
32
|
-
copyToAllStoragePaths: () => copyToAllStoragePaths,
|
|
33
|
-
detectWorkspaceRoot: () => detectWorkspaceRoot,
|
|
34
|
-
ensureDir: () => ensureDir,
|
|
35
|
-
getAgentPromptPath: () => getAgentPromptPath,
|
|
36
|
-
getConfigPath: () => getConfigPath,
|
|
37
|
-
getDefaultRRCEHome: () => getDefaultRRCEHome,
|
|
38
|
-
getEffectiveRRCEHome: () => getEffectiveRRCEHome,
|
|
39
|
-
getGlobalProjectKnowledgePath: () => getGlobalProjectKnowledgePath,
|
|
40
|
-
getGlobalWorkspacePath: () => getGlobalWorkspacePath,
|
|
41
|
-
getLocalWorkspacePath: () => getLocalWorkspacePath,
|
|
42
|
-
getRRCEHome: () => getRRCEHome,
|
|
43
|
-
getSuggestedGlobalPaths: () => getSuggestedGlobalPaths,
|
|
44
|
-
getWorkspaceName: () => getWorkspaceName,
|
|
45
|
-
listGlobalProjects: () => listGlobalProjects,
|
|
46
|
-
resolveAllDataPaths: () => resolveAllDataPaths,
|
|
47
|
-
resolveDataPath: () => resolveDataPath,
|
|
48
|
-
syncMetadataToAll: () => syncMetadataToAll,
|
|
49
|
-
writeToAllStoragePaths: () => writeToAllStoragePaths
|
|
50
|
-
});
|
|
51
28
|
import * as fs from "fs";
|
|
52
29
|
import * as path from "path";
|
|
53
30
|
function detectWorkspaceRoot() {
|
|
@@ -77,49 +54,9 @@ function getConfigPath(workspaceRoot) {
|
|
|
77
54
|
function getWorkspaceName(workspaceRoot) {
|
|
78
55
|
return path.basename(workspaceRoot);
|
|
79
56
|
}
|
|
80
|
-
function resolveDataPath(mode, workspaceName, workspaceRoot) {
|
|
81
|
-
switch (mode) {
|
|
82
|
-
case "global":
|
|
83
|
-
return path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
84
|
-
case "workspace":
|
|
85
|
-
return path.join(workspaceRoot, ".rrce-workflow");
|
|
86
|
-
default:
|
|
87
|
-
return path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
function resolveAllDataPaths(mode, workspaceName, workspaceRoot) {
|
|
91
|
-
const globalPath = path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
92
|
-
const workspacePath = path.join(workspaceRoot, ".rrce-workflow");
|
|
93
|
-
switch (mode) {
|
|
94
|
-
case "global":
|
|
95
|
-
return [globalPath];
|
|
96
|
-
case "workspace":
|
|
97
|
-
return [workspacePath];
|
|
98
|
-
default:
|
|
99
|
-
return [globalPath];
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
57
|
function getRRCEHome() {
|
|
103
58
|
return RRCE_HOME;
|
|
104
59
|
}
|
|
105
|
-
function listGlobalProjects(excludeWorkspace) {
|
|
106
|
-
const workspacesDir = path.join(RRCE_HOME, "workspaces");
|
|
107
|
-
if (!fs.existsSync(workspacesDir)) {
|
|
108
|
-
return [];
|
|
109
|
-
}
|
|
110
|
-
try {
|
|
111
|
-
const entries = fs.readdirSync(workspacesDir, { withFileTypes: true });
|
|
112
|
-
return entries.filter((entry) => entry.isDirectory() && entry.name !== excludeWorkspace).map((entry) => entry.name);
|
|
113
|
-
} catch {
|
|
114
|
-
return [];
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
function getGlobalProjectKnowledgePath(projectName) {
|
|
118
|
-
return path.join(RRCE_HOME, "workspaces", projectName, "knowledge");
|
|
119
|
-
}
|
|
120
|
-
function getGlobalWorkspacePath(workspaceName) {
|
|
121
|
-
return path.join(RRCE_HOME, "workspaces", workspaceName);
|
|
122
|
-
}
|
|
123
60
|
function getLocalWorkspacePath(workspaceRoot) {
|
|
124
61
|
return path.join(workspaceRoot, ".rrce-workflow");
|
|
125
62
|
}
|
|
@@ -143,13 +80,6 @@ function copyToAllStoragePaths(sourceFile, relativePath, dataPaths) {
|
|
|
143
80
|
fs.writeFileSync(targetPath, content);
|
|
144
81
|
}
|
|
145
82
|
}
|
|
146
|
-
function writeToAllStoragePaths(content, relativePath, dataPaths) {
|
|
147
|
-
for (const dataPath of dataPaths) {
|
|
148
|
-
const targetPath = path.join(dataPath, relativePath);
|
|
149
|
-
ensureDir(path.dirname(targetPath));
|
|
150
|
-
fs.writeFileSync(targetPath, content);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
83
|
function copyDirToAllStoragePaths(sourceDir, relativeDir, dataPaths) {
|
|
154
84
|
if (!fs.existsSync(sourceDir)) {
|
|
155
85
|
return;
|
|
@@ -194,25 +124,6 @@ function checkWriteAccess(dirPath) {
|
|
|
194
124
|
function getDefaultRRCEHome() {
|
|
195
125
|
return process.env.RRCE_HOME || path.join(process.env.HOME || "~", ".rrce-workflow");
|
|
196
126
|
}
|
|
197
|
-
function getSuggestedGlobalPaths() {
|
|
198
|
-
const suggestions = [];
|
|
199
|
-
if (process.env.RRCE_HOME) {
|
|
200
|
-
suggestions.push({
|
|
201
|
-
path: process.env.RRCE_HOME,
|
|
202
|
-
label: "RRCE_HOME (environment)",
|
|
203
|
-
isWritable: checkWriteAccess(process.env.RRCE_HOME)
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
const homeDefault = path.join(process.env.HOME || "~", ".rrce-workflow");
|
|
207
|
-
if (!process.env.RRCE_HOME || process.env.RRCE_HOME !== homeDefault) {
|
|
208
|
-
suggestions.push({
|
|
209
|
-
path: homeDefault,
|
|
210
|
-
label: "~/.rrce-workflow (default)",
|
|
211
|
-
isWritable: checkWriteAccess(homeDefault)
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
return suggestions;
|
|
215
|
-
}
|
|
216
127
|
function getEffectiveRRCEHome(workspaceRoot) {
|
|
217
128
|
if (workspaceRoot) {
|
|
218
129
|
const configPath = getConfigPath(workspaceRoot);
|
|
@@ -390,212 +301,9 @@ var init_detection = __esm({
|
|
|
390
301
|
}
|
|
391
302
|
});
|
|
392
303
|
|
|
393
|
-
// src/
|
|
394
|
-
import { z } from "zod";
|
|
395
|
-
var PromptArgSchema, AutoIdentitySchema, PromptFrontmatterSchema;
|
|
396
|
-
var init_prompt = __esm({
|
|
397
|
-
"src/types/prompt.ts"() {
|
|
398
|
-
"use strict";
|
|
399
|
-
PromptArgSchema = z.object({
|
|
400
|
-
name: z.string(),
|
|
401
|
-
default: z.string().optional(),
|
|
402
|
-
prompt: z.string().optional()
|
|
403
|
-
});
|
|
404
|
-
AutoIdentitySchema = z.object({
|
|
405
|
-
user: z.string(),
|
|
406
|
-
model: z.string()
|
|
407
|
-
});
|
|
408
|
-
PromptFrontmatterSchema = z.object({
|
|
409
|
-
name: z.string(),
|
|
410
|
-
description: z.string(),
|
|
411
|
-
"argument-hint": z.union([z.string(), z.array(z.string())]).optional(),
|
|
412
|
-
tools: z.array(z.string()).optional(),
|
|
413
|
-
"required-args": z.array(PromptArgSchema).optional(),
|
|
414
|
-
"optional-args": z.array(PromptArgSchema).optional(),
|
|
415
|
-
"auto-identity": AutoIdentitySchema.optional()
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
// src/lib/prompts.ts
|
|
304
|
+
// src/lib/autocomplete-prompt.ts
|
|
421
305
|
import * as fs3 from "fs";
|
|
422
306
|
import * as path3 from "path";
|
|
423
|
-
import { fileURLToPath } from "url";
|
|
424
|
-
import matter from "gray-matter";
|
|
425
|
-
function parsePromptFile(filePath) {
|
|
426
|
-
try {
|
|
427
|
-
const fileContent = fs3.readFileSync(filePath, "utf-8");
|
|
428
|
-
const { data, content } = matter(fileContent);
|
|
429
|
-
const parsed = PromptFrontmatterSchema.safeParse(data);
|
|
430
|
-
if (!parsed.success) {
|
|
431
|
-
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
432
|
-
return null;
|
|
433
|
-
}
|
|
434
|
-
return {
|
|
435
|
-
frontmatter: parsed.data,
|
|
436
|
-
content: content.trim(),
|
|
437
|
-
filePath
|
|
438
|
-
};
|
|
439
|
-
} catch (error) {
|
|
440
|
-
console.error(`Error reading prompt file ${filePath}:`, error);
|
|
441
|
-
return null;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
function loadPromptsFromDir(dirPath) {
|
|
445
|
-
if (!fs3.existsSync(dirPath)) {
|
|
446
|
-
return [];
|
|
447
|
-
}
|
|
448
|
-
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".md"));
|
|
449
|
-
const prompts = [];
|
|
450
|
-
for (const file of files) {
|
|
451
|
-
const prompt = parsePromptFile(path3.join(dirPath, file));
|
|
452
|
-
if (prompt) {
|
|
453
|
-
prompts.push(prompt);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return prompts;
|
|
457
|
-
}
|
|
458
|
-
function getAgentCoreDir() {
|
|
459
|
-
return path3.join(__dirname, "..", "agent-core");
|
|
460
|
-
}
|
|
461
|
-
function getAgentCorePromptsDir() {
|
|
462
|
-
return path3.join(getAgentCoreDir(), "prompts");
|
|
463
|
-
}
|
|
464
|
-
var __filename, __dirname;
|
|
465
|
-
var init_prompts = __esm({
|
|
466
|
-
"src/lib/prompts.ts"() {
|
|
467
|
-
"use strict";
|
|
468
|
-
init_prompt();
|
|
469
|
-
__filename = fileURLToPath(import.meta.url);
|
|
470
|
-
__dirname = path3.dirname(__filename);
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
// src/commands/wizard/utils.ts
|
|
475
|
-
import * as fs4 from "fs";
|
|
476
|
-
import * as path4 from "path";
|
|
477
|
-
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
478
|
-
for (const prompt of prompts) {
|
|
479
|
-
const baseName = path4.basename(prompt.filePath, ".md");
|
|
480
|
-
const targetName = baseName + extension;
|
|
481
|
-
const targetPath = path4.join(targetDir, targetName);
|
|
482
|
-
const content = fs4.readFileSync(prompt.filePath, "utf-8");
|
|
483
|
-
fs4.writeFileSync(targetPath, content);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
function copyDirRecursive(src, dest) {
|
|
487
|
-
const entries = fs4.readdirSync(src, { withFileTypes: true });
|
|
488
|
-
for (const entry of entries) {
|
|
489
|
-
const srcPath = path4.join(src, entry.name);
|
|
490
|
-
const destPath = path4.join(dest, entry.name);
|
|
491
|
-
if (entry.isDirectory()) {
|
|
492
|
-
ensureDir(destPath);
|
|
493
|
-
copyDirRecursive(srcPath, destPath);
|
|
494
|
-
} else {
|
|
495
|
-
fs4.copyFileSync(srcPath, destPath);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
var init_utils = __esm({
|
|
500
|
-
"src/commands/wizard/utils.ts"() {
|
|
501
|
-
"use strict";
|
|
502
|
-
init_paths();
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
// src/commands/wizard/vscode.ts
|
|
507
|
-
import * as fs5 from "fs";
|
|
508
|
-
import * as path5 from "path";
|
|
509
|
-
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
510
|
-
const workspaceFilePath = path5.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
511
|
-
let workspace;
|
|
512
|
-
if (fs5.existsSync(workspaceFilePath)) {
|
|
513
|
-
try {
|
|
514
|
-
const content = fs5.readFileSync(workspaceFilePath, "utf-8");
|
|
515
|
-
workspace = JSON.parse(content);
|
|
516
|
-
} catch {
|
|
517
|
-
workspace = { folders: [], settings: {} };
|
|
518
|
-
}
|
|
519
|
-
} else {
|
|
520
|
-
workspace = { folders: [], settings: {} };
|
|
521
|
-
}
|
|
522
|
-
if (!workspace.settings) {
|
|
523
|
-
workspace.settings = {};
|
|
524
|
-
}
|
|
525
|
-
workspace.folders = workspace.folders.filter(
|
|
526
|
-
(f) => f.path === "." || !f.name?.startsWith("\u{1F4C1}") && !f.name?.startsWith("\u{1F4DA}") && !f.name?.startsWith("\u{1F4CE}") && !f.name?.startsWith("\u{1F4CB}")
|
|
527
|
-
);
|
|
528
|
-
const mainFolderIndex = workspace.folders.findIndex((f) => f.path === ".");
|
|
529
|
-
if (mainFolderIndex === -1) {
|
|
530
|
-
workspace.folders.unshift({
|
|
531
|
-
path: ".",
|
|
532
|
-
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
533
|
-
});
|
|
534
|
-
} else {
|
|
535
|
-
workspace.folders[mainFolderIndex] = {
|
|
536
|
-
path: ".",
|
|
537
|
-
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
const referenceFolderPaths = [];
|
|
541
|
-
const isDetectedProjects = linkedProjects.length > 0 && typeof linkedProjects[0] === "object";
|
|
542
|
-
if (isDetectedProjects) {
|
|
543
|
-
const projects = linkedProjects;
|
|
544
|
-
for (const project of projects) {
|
|
545
|
-
const sourceLabel = project.source === "global" ? "global" : "local";
|
|
546
|
-
const folderPath = project.dataPath;
|
|
547
|
-
if (fs5.existsSync(folderPath)) {
|
|
548
|
-
referenceFolderPaths.push(folderPath);
|
|
549
|
-
workspace.folders.push({
|
|
550
|
-
path: folderPath,
|
|
551
|
-
name: `\u{1F4C1} ${project.name} [${sourceLabel}]`
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
} else {
|
|
556
|
-
const projectNames = linkedProjects;
|
|
557
|
-
const rrceHome = customGlobalPath || getRRCEHome();
|
|
558
|
-
for (const projectName of projectNames) {
|
|
559
|
-
const folderPath = path5.join(rrceHome, "workspaces", projectName);
|
|
560
|
-
if (fs5.existsSync(folderPath)) {
|
|
561
|
-
referenceFolderPaths.push(folderPath);
|
|
562
|
-
workspace.folders.push({
|
|
563
|
-
path: folderPath,
|
|
564
|
-
name: `\u{1F4C1} ${projectName} [global]`
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
if (referenceFolderPaths.length > 0) {
|
|
570
|
-
const readonlyPatterns = {};
|
|
571
|
-
for (const folderPath of referenceFolderPaths) {
|
|
572
|
-
readonlyPatterns[`${folderPath}/**`] = true;
|
|
573
|
-
}
|
|
574
|
-
const existingReadonly = workspace.settings["files.readonlyInclude"] || {};
|
|
575
|
-
const cleanedReadonly = {};
|
|
576
|
-
for (const [pattern, value] of Object.entries(existingReadonly)) {
|
|
577
|
-
if (!pattern.includes(".rrce-workflow") && !pattern.includes("rrce-workflow/workspaces")) {
|
|
578
|
-
cleanedReadonly[pattern] = value;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
workspace.settings["files.readonlyInclude"] = {
|
|
582
|
-
...cleanedReadonly,
|
|
583
|
-
...readonlyPatterns
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
fs5.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, 2));
|
|
587
|
-
}
|
|
588
|
-
var init_vscode = __esm({
|
|
589
|
-
"src/commands/wizard/vscode.ts"() {
|
|
590
|
-
"use strict";
|
|
591
|
-
init_paths();
|
|
592
|
-
init_detection();
|
|
593
|
-
}
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
// src/lib/autocomplete-prompt.ts
|
|
597
|
-
import * as fs6 from "fs";
|
|
598
|
-
import * as path6 from "path";
|
|
599
307
|
import * as readline from "readline";
|
|
600
308
|
import pc from "picocolors";
|
|
601
309
|
function directoryPrompt(opts) {
|
|
@@ -654,19 +362,19 @@ function completeDirectory(line) {
|
|
|
654
362
|
prefix = "";
|
|
655
363
|
basePath = expanded;
|
|
656
364
|
} else {
|
|
657
|
-
dirToScan =
|
|
658
|
-
prefix =
|
|
365
|
+
dirToScan = path3.dirname(expanded);
|
|
366
|
+
prefix = path3.basename(expanded).toLowerCase();
|
|
659
367
|
basePath = dirToScan === "/" ? "/" : dirToScan + "/";
|
|
660
368
|
}
|
|
661
|
-
if (!
|
|
369
|
+
if (!fs3.existsSync(dirToScan)) {
|
|
662
370
|
return [[], line];
|
|
663
371
|
}
|
|
664
|
-
const entries =
|
|
372
|
+
const entries = fs3.readdirSync(dirToScan, { withFileTypes: true }).filter((entry) => {
|
|
665
373
|
if (!entry.isDirectory()) return false;
|
|
666
374
|
if (entry.name.startsWith(".") && !prefix.startsWith(".")) return false;
|
|
667
375
|
return prefix === "" || entry.name.toLowerCase().startsWith(prefix);
|
|
668
376
|
}).map((entry) => {
|
|
669
|
-
const fullPath =
|
|
377
|
+
const fullPath = path3.join(dirToScan, entry.name);
|
|
670
378
|
const displayPath = fullPath.startsWith(process.env.HOME || "") ? fullPath.replace(process.env.HOME || "", "~") : fullPath;
|
|
671
379
|
return displayPath + "/";
|
|
672
380
|
}).sort();
|
|
@@ -706,29 +414,29 @@ var init_autocomplete_prompt = __esm({
|
|
|
706
414
|
});
|
|
707
415
|
|
|
708
416
|
// src/lib/preferences.ts
|
|
709
|
-
import * as
|
|
710
|
-
import * as
|
|
417
|
+
import * as fs4 from "fs";
|
|
418
|
+
import * as path4 from "path";
|
|
711
419
|
function getPreferencesPath() {
|
|
712
420
|
const home = process.env.HOME || "~";
|
|
713
|
-
return
|
|
421
|
+
return path4.join(home, ".rrce-workflow", "preferences.json");
|
|
714
422
|
}
|
|
715
423
|
function loadUserPreferences() {
|
|
716
424
|
const prefPath = getPreferencesPath();
|
|
717
|
-
if (!
|
|
425
|
+
if (!fs4.existsSync(prefPath)) {
|
|
718
426
|
return {};
|
|
719
427
|
}
|
|
720
428
|
try {
|
|
721
|
-
return JSON.parse(
|
|
429
|
+
return JSON.parse(fs4.readFileSync(prefPath, "utf-8"));
|
|
722
430
|
} catch {
|
|
723
431
|
return {};
|
|
724
432
|
}
|
|
725
433
|
}
|
|
726
434
|
function saveUserPreferences(prefs) {
|
|
727
435
|
const prefPath = getPreferencesPath();
|
|
728
|
-
ensureDir(
|
|
436
|
+
ensureDir(path4.dirname(prefPath));
|
|
729
437
|
const current = loadUserPreferences();
|
|
730
438
|
const refined = { ...current, ...prefs };
|
|
731
|
-
|
|
439
|
+
fs4.writeFileSync(prefPath, JSON.stringify(refined, null, 2));
|
|
732
440
|
}
|
|
733
441
|
var init_preferences = __esm({
|
|
734
442
|
"src/lib/preferences.ts"() {
|
|
@@ -744,7 +452,7 @@ __export(tui_utils_exports, {
|
|
|
744
452
|
});
|
|
745
453
|
import { select, note, isCancel } from "@clack/prompts";
|
|
746
454
|
import pc2 from "picocolors";
|
|
747
|
-
import * as
|
|
455
|
+
import * as path5 from "path";
|
|
748
456
|
async function resolveGlobalPath() {
|
|
749
457
|
const prefs = loadUserPreferences();
|
|
750
458
|
const defaultPath = prefs.defaultGlobalPath || getDefaultRRCEHome();
|
|
@@ -783,7 +491,7 @@ Please choose a custom path instead.`,
|
|
|
783
491
|
}
|
|
784
492
|
return defaultPath;
|
|
785
493
|
}
|
|
786
|
-
const suggestedPath =
|
|
494
|
+
const suggestedPath = path5.join(process.env.HOME || "~", ".local", "share", "rrce-workflow");
|
|
787
495
|
const customPath = await directoryPrompt({
|
|
788
496
|
message: "Enter custom global path (Tab to autocomplete):",
|
|
789
497
|
defaultValue: suggestedPath,
|
|
@@ -802,7 +510,7 @@ Please choose a custom path instead.`,
|
|
|
802
510
|
}
|
|
803
511
|
let expandedPath = customPath;
|
|
804
512
|
if (!expandedPath.endsWith(".rrce-workflow")) {
|
|
805
|
-
expandedPath =
|
|
513
|
+
expandedPath = path5.join(expandedPath, ".rrce-workflow");
|
|
806
514
|
}
|
|
807
515
|
saveUserPreferences({ defaultGlobalPath: expandedPath });
|
|
808
516
|
return expandedPath;
|
|
@@ -816,33 +524,362 @@ var init_tui_utils = __esm({
|
|
|
816
524
|
}
|
|
817
525
|
});
|
|
818
526
|
|
|
819
|
-
// src/
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
tasks: true,
|
|
835
|
-
refs: true
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
};
|
|
839
|
-
DEFAULT_PERMISSIONS = {
|
|
840
|
-
knowledge: true,
|
|
841
|
-
tasks: true,
|
|
842
|
-
refs: true
|
|
843
|
-
};
|
|
527
|
+
// src/commands/wizard/setup-prompts.ts
|
|
528
|
+
import { select as select2, multiselect, confirm, isCancel as isCancel2, cancel } from "@clack/prompts";
|
|
529
|
+
import pc3 from "picocolors";
|
|
530
|
+
async function promptStorageMode() {
|
|
531
|
+
const result = await select2({
|
|
532
|
+
message: "Where should workflow data be stored?",
|
|
533
|
+
options: [
|
|
534
|
+
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
|
|
535
|
+
{ value: "workspace", label: "Workspace (.rrce-workflow/)", hint: "Self-contained, version with repo" }
|
|
536
|
+
],
|
|
537
|
+
initialValue: "global"
|
|
538
|
+
});
|
|
539
|
+
if (isCancel2(result)) {
|
|
540
|
+
cancel("Setup cancelled.");
|
|
541
|
+
process.exit(0);
|
|
844
542
|
}
|
|
845
|
-
|
|
543
|
+
return result;
|
|
544
|
+
}
|
|
545
|
+
async function promptTools() {
|
|
546
|
+
const result = await multiselect({
|
|
547
|
+
message: "Which AI tools do you use?",
|
|
548
|
+
options: [
|
|
549
|
+
{ value: "copilot", label: "GitHub Copilot", hint: "VSCode" },
|
|
550
|
+
{ value: "antigravity", label: "Antigravity IDE" }
|
|
551
|
+
],
|
|
552
|
+
required: false
|
|
553
|
+
});
|
|
554
|
+
if (isCancel2(result)) {
|
|
555
|
+
cancel("Setup cancelled.");
|
|
556
|
+
process.exit(0);
|
|
557
|
+
}
|
|
558
|
+
return result;
|
|
559
|
+
}
|
|
560
|
+
async function promptMCPExposure() {
|
|
561
|
+
const result = await confirm({
|
|
562
|
+
message: "Expose this project to MCP (AI Agent) server?",
|
|
563
|
+
initialValue: true
|
|
564
|
+
});
|
|
565
|
+
if (isCancel2(result)) {
|
|
566
|
+
cancel("Setup cancelled.");
|
|
567
|
+
process.exit(0);
|
|
568
|
+
}
|
|
569
|
+
return result;
|
|
570
|
+
}
|
|
571
|
+
async function promptLinkedProjects(existingProjects) {
|
|
572
|
+
if (existingProjects.length === 0) {
|
|
573
|
+
return [];
|
|
574
|
+
}
|
|
575
|
+
const result = await multiselect({
|
|
576
|
+
message: "Link knowledge from other projects?",
|
|
577
|
+
options: existingProjects.map((project) => ({
|
|
578
|
+
value: `${project.name}:${project.source}`,
|
|
579
|
+
label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
|
|
580
|
+
hint: pc3.dim(
|
|
581
|
+
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
582
|
+
)
|
|
583
|
+
})),
|
|
584
|
+
required: false
|
|
585
|
+
});
|
|
586
|
+
if (isCancel2(result)) {
|
|
587
|
+
cancel("Setup cancelled.");
|
|
588
|
+
process.exit(0);
|
|
589
|
+
}
|
|
590
|
+
return result;
|
|
591
|
+
}
|
|
592
|
+
async function promptGitignore() {
|
|
593
|
+
const result = await confirm({
|
|
594
|
+
message: "Add generated folders to .gitignore? (as comments - uncomment if needed)",
|
|
595
|
+
initialValue: true
|
|
596
|
+
});
|
|
597
|
+
if (isCancel2(result)) {
|
|
598
|
+
cancel("Setup cancelled.");
|
|
599
|
+
process.exit(0);
|
|
600
|
+
}
|
|
601
|
+
return result;
|
|
602
|
+
}
|
|
603
|
+
async function promptRAG() {
|
|
604
|
+
const result = await confirm({
|
|
605
|
+
message: `Enable Semantic Search (Local Mini RAG)?
|
|
606
|
+
${pc3.yellow("\u26A0 First use will download a ~100MB model")}`,
|
|
607
|
+
initialValue: true
|
|
608
|
+
});
|
|
609
|
+
if (isCancel2(result)) {
|
|
610
|
+
cancel("Setup cancelled.");
|
|
611
|
+
process.exit(0);
|
|
612
|
+
}
|
|
613
|
+
return result;
|
|
614
|
+
}
|
|
615
|
+
async function promptConfirmation() {
|
|
616
|
+
const result = await confirm({
|
|
617
|
+
message: "Create configuration?",
|
|
618
|
+
initialValue: true
|
|
619
|
+
});
|
|
620
|
+
if (isCancel2(result)) {
|
|
621
|
+
cancel("Setup cancelled.");
|
|
622
|
+
process.exit(0);
|
|
623
|
+
}
|
|
624
|
+
return result;
|
|
625
|
+
}
|
|
626
|
+
var init_setup_prompts = __esm({
|
|
627
|
+
"src/commands/wizard/setup-prompts.ts"() {
|
|
628
|
+
"use strict";
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
// src/types/prompt.ts
|
|
633
|
+
import { z } from "zod";
|
|
634
|
+
var PromptArgSchema, AutoIdentitySchema, PromptFrontmatterSchema;
|
|
635
|
+
var init_prompt = __esm({
|
|
636
|
+
"src/types/prompt.ts"() {
|
|
637
|
+
"use strict";
|
|
638
|
+
PromptArgSchema = z.object({
|
|
639
|
+
name: z.string(),
|
|
640
|
+
default: z.string().optional(),
|
|
641
|
+
prompt: z.string().optional()
|
|
642
|
+
});
|
|
643
|
+
AutoIdentitySchema = z.object({
|
|
644
|
+
user: z.string(),
|
|
645
|
+
model: z.string()
|
|
646
|
+
});
|
|
647
|
+
PromptFrontmatterSchema = z.object({
|
|
648
|
+
name: z.string(),
|
|
649
|
+
description: z.string(),
|
|
650
|
+
"argument-hint": z.union([z.string(), z.array(z.string())]).optional(),
|
|
651
|
+
tools: z.array(z.string()).optional(),
|
|
652
|
+
"required-args": z.array(PromptArgSchema).optional(),
|
|
653
|
+
"optional-args": z.array(PromptArgSchema).optional(),
|
|
654
|
+
"auto-identity": AutoIdentitySchema.optional()
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
// src/lib/prompts.ts
|
|
660
|
+
import * as fs5 from "fs";
|
|
661
|
+
import * as path6 from "path";
|
|
662
|
+
import { fileURLToPath } from "url";
|
|
663
|
+
import matter from "gray-matter";
|
|
664
|
+
function parsePromptFile(filePath) {
|
|
665
|
+
try {
|
|
666
|
+
const fileContent = fs5.readFileSync(filePath, "utf-8");
|
|
667
|
+
const { data, content } = matter(fileContent);
|
|
668
|
+
const parsed = PromptFrontmatterSchema.safeParse(data);
|
|
669
|
+
if (!parsed.success) {
|
|
670
|
+
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
return {
|
|
674
|
+
frontmatter: parsed.data,
|
|
675
|
+
content: content.trim(),
|
|
676
|
+
filePath
|
|
677
|
+
};
|
|
678
|
+
} catch (error) {
|
|
679
|
+
console.error(`Error reading prompt file ${filePath}:`, error);
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function loadPromptsFromDir(dirPath) {
|
|
684
|
+
if (!fs5.existsSync(dirPath)) {
|
|
685
|
+
return [];
|
|
686
|
+
}
|
|
687
|
+
const files = fs5.readdirSync(dirPath).filter((f) => f.endsWith(".md"));
|
|
688
|
+
const prompts = [];
|
|
689
|
+
for (const file of files) {
|
|
690
|
+
const prompt = parsePromptFile(path6.join(dirPath, file));
|
|
691
|
+
if (prompt) {
|
|
692
|
+
prompts.push(prompt);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return prompts;
|
|
696
|
+
}
|
|
697
|
+
function getAgentCoreDir() {
|
|
698
|
+
return path6.join(__dirname, "..", "agent-core");
|
|
699
|
+
}
|
|
700
|
+
function getAgentCorePromptsDir() {
|
|
701
|
+
return path6.join(getAgentCoreDir(), "prompts");
|
|
702
|
+
}
|
|
703
|
+
var __filename, __dirname;
|
|
704
|
+
var init_prompts = __esm({
|
|
705
|
+
"src/lib/prompts.ts"() {
|
|
706
|
+
"use strict";
|
|
707
|
+
init_prompt();
|
|
708
|
+
__filename = fileURLToPath(import.meta.url);
|
|
709
|
+
__dirname = path6.dirname(__filename);
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
// src/commands/wizard/utils.ts
|
|
714
|
+
import * as fs6 from "fs";
|
|
715
|
+
import * as path7 from "path";
|
|
716
|
+
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
717
|
+
for (const prompt of prompts) {
|
|
718
|
+
const baseName = path7.basename(prompt.filePath, ".md");
|
|
719
|
+
const targetName = baseName + extension;
|
|
720
|
+
const targetPath = path7.join(targetDir, targetName);
|
|
721
|
+
const content = fs6.readFileSync(prompt.filePath, "utf-8");
|
|
722
|
+
fs6.writeFileSync(targetPath, content);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function copyDirRecursive(src, dest) {
|
|
726
|
+
const entries = fs6.readdirSync(src, { withFileTypes: true });
|
|
727
|
+
for (const entry of entries) {
|
|
728
|
+
const srcPath = path7.join(src, entry.name);
|
|
729
|
+
const destPath = path7.join(dest, entry.name);
|
|
730
|
+
if (entry.isDirectory()) {
|
|
731
|
+
ensureDir(destPath);
|
|
732
|
+
copyDirRecursive(srcPath, destPath);
|
|
733
|
+
} else {
|
|
734
|
+
fs6.copyFileSync(srcPath, destPath);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
var init_utils = __esm({
|
|
739
|
+
"src/commands/wizard/utils.ts"() {
|
|
740
|
+
"use strict";
|
|
741
|
+
init_paths();
|
|
742
|
+
}
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
// src/commands/wizard/vscode.ts
|
|
746
|
+
import * as fs7 from "fs";
|
|
747
|
+
import * as path8 from "path";
|
|
748
|
+
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
749
|
+
const workspaceFilePath = path8.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
750
|
+
let workspace;
|
|
751
|
+
if (fs7.existsSync(workspaceFilePath)) {
|
|
752
|
+
try {
|
|
753
|
+
const content = fs7.readFileSync(workspaceFilePath, "utf-8");
|
|
754
|
+
workspace = JSON.parse(content);
|
|
755
|
+
} catch {
|
|
756
|
+
workspace = { folders: [], settings: {} };
|
|
757
|
+
}
|
|
758
|
+
} else {
|
|
759
|
+
workspace = { folders: [], settings: {} };
|
|
760
|
+
}
|
|
761
|
+
if (!workspace.settings) {
|
|
762
|
+
workspace.settings = {};
|
|
763
|
+
}
|
|
764
|
+
workspace.folders = workspace.folders.filter(
|
|
765
|
+
(f) => f.path === "." || !f.name?.startsWith("\u{1F4C1}") && !f.name?.startsWith("\u{1F4DA}") && !f.name?.startsWith("\u{1F4CE}") && !f.name?.startsWith("\u{1F4CB}")
|
|
766
|
+
);
|
|
767
|
+
const mainFolderIndex = workspace.folders.findIndex((f) => f.path === ".");
|
|
768
|
+
if (mainFolderIndex === -1) {
|
|
769
|
+
workspace.folders.unshift({
|
|
770
|
+
path: ".",
|
|
771
|
+
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
772
|
+
});
|
|
773
|
+
} else {
|
|
774
|
+
workspace.folders[mainFolderIndex] = {
|
|
775
|
+
path: ".",
|
|
776
|
+
name: `\u{1F3E0} ${workspaceName} (workspace)`
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
const referenceFolderPaths = [];
|
|
780
|
+
const isDetectedProjects = linkedProjects.length > 0 && typeof linkedProjects[0] === "object";
|
|
781
|
+
if (isDetectedProjects) {
|
|
782
|
+
const projects = linkedProjects;
|
|
783
|
+
for (const project of projects) {
|
|
784
|
+
const sourceLabel = project.source === "global" ? "global" : "local";
|
|
785
|
+
const folderPath = project.dataPath;
|
|
786
|
+
if (fs7.existsSync(folderPath)) {
|
|
787
|
+
referenceFolderPaths.push(folderPath);
|
|
788
|
+
workspace.folders.push({
|
|
789
|
+
path: folderPath,
|
|
790
|
+
name: `\u{1F4C1} ${project.name} [${sourceLabel}]`
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
} else {
|
|
795
|
+
const projectNames = linkedProjects;
|
|
796
|
+
const rrceHome = customGlobalPath || getRRCEHome();
|
|
797
|
+
for (const projectName of projectNames) {
|
|
798
|
+
const folderPath = path8.join(rrceHome, "workspaces", projectName);
|
|
799
|
+
if (fs7.existsSync(folderPath)) {
|
|
800
|
+
referenceFolderPaths.push(folderPath);
|
|
801
|
+
workspace.folders.push({
|
|
802
|
+
path: folderPath,
|
|
803
|
+
name: `\u{1F4C1} ${projectName} [global]`
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
if (referenceFolderPaths.length > 0) {
|
|
809
|
+
const readonlyPatterns = {};
|
|
810
|
+
for (const folderPath of referenceFolderPaths) {
|
|
811
|
+
readonlyPatterns[`${folderPath}/**`] = true;
|
|
812
|
+
}
|
|
813
|
+
const existingReadonly = workspace.settings["files.readonlyInclude"] || {};
|
|
814
|
+
const cleanedReadonly = {};
|
|
815
|
+
for (const [pattern, value] of Object.entries(existingReadonly)) {
|
|
816
|
+
if (!pattern.includes(".rrce-workflow") && !pattern.includes("rrce-workflow/workspaces")) {
|
|
817
|
+
cleanedReadonly[pattern] = value;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
workspace.settings["files.readonlyInclude"] = {
|
|
821
|
+
...cleanedReadonly,
|
|
822
|
+
...readonlyPatterns
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
fs7.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, 2));
|
|
826
|
+
}
|
|
827
|
+
var init_vscode = __esm({
|
|
828
|
+
"src/commands/wizard/vscode.ts"() {
|
|
829
|
+
"use strict";
|
|
830
|
+
init_paths();
|
|
831
|
+
init_detection();
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
// src/mcp/types.ts
|
|
836
|
+
var DEFAULT_MCP_CONFIG, DEFAULT_PERMISSIONS;
|
|
837
|
+
var init_types = __esm({
|
|
838
|
+
"src/mcp/types.ts"() {
|
|
839
|
+
"use strict";
|
|
840
|
+
DEFAULT_MCP_CONFIG = {
|
|
841
|
+
server: {
|
|
842
|
+
port: 3e3,
|
|
843
|
+
autoStart: false
|
|
844
|
+
},
|
|
845
|
+
projects: [],
|
|
846
|
+
defaults: {
|
|
847
|
+
includeNew: true,
|
|
848
|
+
permissions: {
|
|
849
|
+
knowledge: true,
|
|
850
|
+
tasks: true,
|
|
851
|
+
refs: true
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
DEFAULT_PERMISSIONS = {
|
|
856
|
+
knowledge: true,
|
|
857
|
+
tasks: true,
|
|
858
|
+
refs: true
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
// src/mcp/config-utils.ts
|
|
864
|
+
function findProjectConfig(config, identifier) {
|
|
865
|
+
return config.projects.find((p) => {
|
|
866
|
+
if (identifier.path && p.path) {
|
|
867
|
+
return p.path === identifier.path;
|
|
868
|
+
}
|
|
869
|
+
if (!identifier.path && !p.path) {
|
|
870
|
+
return p.name === identifier.name;
|
|
871
|
+
}
|
|
872
|
+
if (identifier.path && !p.path) {
|
|
873
|
+
return p.name === identifier.name;
|
|
874
|
+
}
|
|
875
|
+
return false;
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
var init_config_utils = __esm({
|
|
879
|
+
"src/mcp/config-utils.ts"() {
|
|
880
|
+
"use strict";
|
|
881
|
+
}
|
|
882
|
+
});
|
|
846
883
|
|
|
847
884
|
// src/mcp/config.ts
|
|
848
885
|
var config_exports = {};
|
|
@@ -859,6 +896,7 @@ __export(config_exports, {
|
|
|
859
896
|
});
|
|
860
897
|
import * as fs8 from "fs";
|
|
861
898
|
import * as path9 from "path";
|
|
899
|
+
import YAML from "yaml";
|
|
862
900
|
function getMCPConfigPath() {
|
|
863
901
|
const workspaceRoot = detectWorkspaceRoot();
|
|
864
902
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
@@ -908,175 +946,51 @@ function saveMCPConfig(config) {
|
|
|
908
946
|
fs8.writeFileSync(configPath, content);
|
|
909
947
|
}
|
|
910
948
|
function parseMCPConfig(content) {
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
inSemanticSearch = false;
|
|
925
|
-
continue;
|
|
926
|
-
}
|
|
927
|
-
if (line.match(/^defaults:/)) {
|
|
928
|
-
currentSection = "defaults";
|
|
929
|
-
currentProject = null;
|
|
930
|
-
inPermissions = false;
|
|
931
|
-
inSemanticSearch = false;
|
|
932
|
-
continue;
|
|
933
|
-
}
|
|
934
|
-
if (line.match(/^projects:/)) {
|
|
935
|
-
currentSection = "projects";
|
|
936
|
-
currentProject = null;
|
|
937
|
-
inPermissions = false;
|
|
938
|
-
inSemanticSearch = false;
|
|
939
|
-
continue;
|
|
940
|
-
}
|
|
941
|
-
if (currentSection === "server") {
|
|
942
|
-
const portMatch = trimmed.match(/^port:\s*(\d+)/);
|
|
943
|
-
if (portMatch?.[1]) config.server.port = parseInt(portMatch[1], 10);
|
|
944
|
-
const autoStartMatch = trimmed.match(/^autoStart:\s*(true|false)/);
|
|
945
|
-
if (autoStartMatch) config.server.autoStart = autoStartMatch[1] === "true";
|
|
946
|
-
}
|
|
947
|
-
if (currentSection === "defaults") {
|
|
948
|
-
const includeNewMatch = trimmed.match(/^includeNew:\s*(true|false)/);
|
|
949
|
-
if (includeNewMatch) config.defaults.includeNew = includeNewMatch[1] === "true";
|
|
950
|
-
if (trimmed === "permissions:") {
|
|
951
|
-
inPermissions = true;
|
|
952
|
-
continue;
|
|
953
|
-
}
|
|
954
|
-
if (inPermissions) {
|
|
955
|
-
const knowledgeMatch = trimmed.match(/^knowledge:\s*(true|false)/);
|
|
956
|
-
if (knowledgeMatch) config.defaults.permissions.knowledge = knowledgeMatch[1] === "true";
|
|
957
|
-
const tasksMatch = trimmed.match(/^tasks:\s*(true|false)/);
|
|
958
|
-
if (tasksMatch) config.defaults.permissions.tasks = tasksMatch[1] === "true";
|
|
959
|
-
const refsMatch = trimmed.match(/^refs:\s*(true|false)/);
|
|
960
|
-
if (refsMatch) config.defaults.permissions.refs = refsMatch[1] === "true";
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
if (currentSection === "projects") {
|
|
964
|
-
const projectNameMatch = line.match(/^\s+-\s+name:\s*["']?([^"'\n]+)["']?/);
|
|
965
|
-
if (projectNameMatch) {
|
|
966
|
-
if (currentProject && currentProject.name) {
|
|
967
|
-
config.projects.push(currentProject);
|
|
968
|
-
}
|
|
969
|
-
currentProject = {
|
|
970
|
-
name: projectNameMatch[1].trim(),
|
|
971
|
-
expose: true,
|
|
972
|
-
permissions: { ...DEFAULT_PERMISSIONS }
|
|
973
|
-
};
|
|
974
|
-
inPermissions = false;
|
|
975
|
-
continue;
|
|
976
|
-
}
|
|
977
|
-
if (currentProject) {
|
|
978
|
-
const pathMatch = trimmed.match(/^path:\s*["']?([^"'\n]+)["']?/);
|
|
979
|
-
if (pathMatch) {
|
|
980
|
-
currentProject.path = pathMatch[1].trim();
|
|
981
|
-
}
|
|
982
|
-
const exposeMatch = trimmed.match(/^expose:\s*(true|false)/);
|
|
983
|
-
if (exposeMatch) {
|
|
984
|
-
currentProject.expose = exposeMatch[1] === "true";
|
|
985
|
-
}
|
|
986
|
-
if (trimmed === "permissions:") {
|
|
987
|
-
inPermissions = true;
|
|
988
|
-
continue;
|
|
989
|
-
}
|
|
990
|
-
if (inPermissions) {
|
|
991
|
-
const knowledgeMatch = trimmed.match(/^knowledge:\s*(true|false)/);
|
|
992
|
-
if (knowledgeMatch) currentProject.permissions.knowledge = knowledgeMatch[1] === "true";
|
|
993
|
-
const tasksMatch = trimmed.match(/^tasks:\s*(true|false)/);
|
|
994
|
-
if (tasksMatch) currentProject.permissions.tasks = tasksMatch[1] === "true";
|
|
995
|
-
const refsMatch = trimmed.match(/^refs:\s*(true|false)/);
|
|
996
|
-
if (refsMatch) currentProject.permissions.refs = refsMatch[1] === "true";
|
|
997
|
-
}
|
|
998
|
-
if (trimmed === "semanticSearch:") {
|
|
999
|
-
inSemanticSearch = true;
|
|
1000
|
-
inPermissions = false;
|
|
1001
|
-
if (!currentProject.semanticSearch) {
|
|
1002
|
-
currentProject.semanticSearch = { enabled: false };
|
|
1003
|
-
}
|
|
1004
|
-
continue;
|
|
1005
|
-
}
|
|
1006
|
-
if (inSemanticSearch && currentProject.semanticSearch) {
|
|
1007
|
-
const enabledMatch = trimmed.match(/^enabled:\s*(true|false)/);
|
|
1008
|
-
if (enabledMatch) currentProject.semanticSearch.enabled = enabledMatch[1] === "true";
|
|
1009
|
-
const modelMatch = trimmed.match(/^model:\s*["']?([^"'\n]+)["']?/);
|
|
1010
|
-
if (modelMatch) currentProject.semanticSearch.model = modelMatch[1].trim();
|
|
949
|
+
try {
|
|
950
|
+
const parsed = YAML.parse(content);
|
|
951
|
+
const config = {
|
|
952
|
+
server: {
|
|
953
|
+
port: parsed?.server?.port ?? DEFAULT_MCP_CONFIG.server.port,
|
|
954
|
+
autoStart: parsed?.server?.autoStart ?? DEFAULT_MCP_CONFIG.server.autoStart
|
|
955
|
+
},
|
|
956
|
+
defaults: {
|
|
957
|
+
includeNew: parsed?.defaults?.includeNew ?? DEFAULT_MCP_CONFIG.defaults.includeNew,
|
|
958
|
+
permissions: {
|
|
959
|
+
knowledge: parsed?.defaults?.permissions?.knowledge ?? DEFAULT_PERMISSIONS.knowledge,
|
|
960
|
+
tasks: parsed?.defaults?.permissions?.tasks ?? DEFAULT_PERMISSIONS.tasks,
|
|
961
|
+
refs: parsed?.defaults?.permissions?.refs ?? DEFAULT_PERMISSIONS.refs
|
|
1011
962
|
}
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
963
|
+
},
|
|
964
|
+
projects: Array.isArray(parsed?.projects) ? parsed.projects.map((p) => ({
|
|
965
|
+
name: p.name || "",
|
|
966
|
+
path: p.path,
|
|
967
|
+
expose: p.expose ?? true,
|
|
968
|
+
permissions: {
|
|
969
|
+
knowledge: p.permissions?.knowledge ?? DEFAULT_PERMISSIONS.knowledge,
|
|
970
|
+
tasks: p.permissions?.tasks ?? DEFAULT_PERMISSIONS.tasks,
|
|
971
|
+
refs: p.permissions?.refs ?? DEFAULT_PERMISSIONS.refs
|
|
972
|
+
},
|
|
973
|
+
semanticSearch: p.semanticSearch
|
|
974
|
+
})) : []
|
|
975
|
+
};
|
|
976
|
+
return config;
|
|
977
|
+
} catch (err) {
|
|
978
|
+
return { ...DEFAULT_MCP_CONFIG };
|
|
1017
979
|
}
|
|
1018
|
-
return config;
|
|
1019
980
|
}
|
|
1020
981
|
function serializeMCPConfig(config) {
|
|
1021
|
-
|
|
982
|
+
const header = `# RRCE MCP Hub Configuration
|
|
1022
983
|
# Manages which projects are exposed via MCP
|
|
1023
984
|
|
|
1024
|
-
server:
|
|
1025
|
-
port: ${config.server.port}
|
|
1026
|
-
autoStart: ${config.server.autoStart}
|
|
1027
|
-
|
|
1028
|
-
defaults:
|
|
1029
|
-
includeNew: ${config.defaults.includeNew}
|
|
1030
|
-
permissions:
|
|
1031
|
-
knowledge: ${config.defaults.permissions.knowledge}
|
|
1032
|
-
tasks: ${config.defaults.permissions.tasks}
|
|
1033
|
-
refs: ${config.defaults.permissions.refs}
|
|
1034
|
-
|
|
1035
|
-
projects:
|
|
1036
|
-
`;
|
|
1037
|
-
if (config.projects.length === 0) {
|
|
1038
|
-
content += ' # No projects configured yet. Run "rrce-workflow mcp" to add projects.\n';
|
|
1039
|
-
} else {
|
|
1040
|
-
for (const project of config.projects) {
|
|
1041
|
-
content += ` - name: "${project.name}"
|
|
1042
|
-
`;
|
|
1043
|
-
if (project.path) {
|
|
1044
|
-
content += ` path: "${project.path}"
|
|
1045
985
|
`;
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
enabled: ${project.semanticSearch.enabled}
|
|
1052
|
-
`;
|
|
1053
|
-
if (project.semanticSearch.model) {
|
|
1054
|
-
content += ` model: "${project.semanticSearch.model}"
|
|
1055
|
-
`;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
content += ` permissions:
|
|
1059
|
-
knowledge: ${project.permissions.knowledge}
|
|
1060
|
-
tasks: ${project.permissions.tasks}
|
|
1061
|
-
refs: ${project.permissions.refs}
|
|
1062
|
-
`;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
return content;
|
|
986
|
+
return header + YAML.stringify(config, {
|
|
987
|
+
indent: 2,
|
|
988
|
+
lineWidth: 0
|
|
989
|
+
// No line wrapping
|
|
990
|
+
});
|
|
1066
991
|
}
|
|
1067
992
|
function setProjectConfig(config, name, expose, permissions, projectPath, semanticSearch) {
|
|
1068
|
-
|
|
1069
|
-
if (projectPath && p.path) {
|
|
1070
|
-
return p.path === projectPath;
|
|
1071
|
-
}
|
|
1072
|
-
if (!projectPath && !p.path) {
|
|
1073
|
-
return p.name === name;
|
|
1074
|
-
}
|
|
1075
|
-
if (projectPath && !p.path && p.name === name) {
|
|
1076
|
-
return true;
|
|
1077
|
-
}
|
|
1078
|
-
return false;
|
|
1079
|
-
});
|
|
993
|
+
const existing = findProjectConfig(config, { name, path: projectPath });
|
|
1080
994
|
if (existing) {
|
|
1081
995
|
existing.expose = expose;
|
|
1082
996
|
if (projectPath && !existing.path) {
|
|
@@ -1104,24 +1018,14 @@ function removeProjectConfig(config, name) {
|
|
|
1104
1018
|
return config;
|
|
1105
1019
|
}
|
|
1106
1020
|
function isProjectExposed(config, name, projectPath) {
|
|
1107
|
-
const project = config
|
|
1108
|
-
if (projectPath && p.path) return p.path === projectPath;
|
|
1109
|
-
if (!projectPath && !p.path) return p.name === name;
|
|
1110
|
-
if (projectPath && !p.path) return p.name === name;
|
|
1111
|
-
return false;
|
|
1112
|
-
});
|
|
1021
|
+
const project = findProjectConfig(config, { name, path: projectPath });
|
|
1113
1022
|
if (project) {
|
|
1114
1023
|
return project.expose;
|
|
1115
1024
|
}
|
|
1116
1025
|
return config.defaults.includeNew;
|
|
1117
1026
|
}
|
|
1118
1027
|
function getProjectPermissions(config, name, projectPath) {
|
|
1119
|
-
const project = config
|
|
1120
|
-
if (projectPath && p.path) return p.path === projectPath;
|
|
1121
|
-
if (!projectPath && !p.path) return p.name === name;
|
|
1122
|
-
if (projectPath && !p.path) return p.name === name;
|
|
1123
|
-
return false;
|
|
1124
|
-
});
|
|
1028
|
+
const project = findProjectConfig(config, { name, path: projectPath });
|
|
1125
1029
|
return project?.permissions ?? config.defaults.permissions;
|
|
1126
1030
|
}
|
|
1127
1031
|
function cleanStaleProjects(config) {
|
|
@@ -1146,23 +1050,192 @@ function cleanStaleProjects(config) {
|
|
|
1146
1050
|
if (removed.length > 0) {
|
|
1147
1051
|
config.projects = validProjects;
|
|
1148
1052
|
}
|
|
1149
|
-
return { config, removed };
|
|
1053
|
+
return { config, removed };
|
|
1054
|
+
}
|
|
1055
|
+
var init_config = __esm({
|
|
1056
|
+
"src/mcp/config.ts"() {
|
|
1057
|
+
"use strict";
|
|
1058
|
+
init_paths();
|
|
1059
|
+
init_types();
|
|
1060
|
+
init_config_utils();
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
|
|
1064
|
+
// src/commands/wizard/setup-actions.ts
|
|
1065
|
+
import * as fs9 from "fs";
|
|
1066
|
+
import * as path10 from "path";
|
|
1067
|
+
import pc4 from "picocolors";
|
|
1068
|
+
import { note as note2 } from "@clack/prompts";
|
|
1069
|
+
function createDirectoryStructure(dataPaths) {
|
|
1070
|
+
for (const dataPath of dataPaths) {
|
|
1071
|
+
ensureDir(dataPath);
|
|
1072
|
+
ensureDir(path10.join(dataPath, "knowledge"));
|
|
1073
|
+
ensureDir(path10.join(dataPath, "refs"));
|
|
1074
|
+
ensureDir(path10.join(dataPath, "tasks"));
|
|
1075
|
+
ensureDir(path10.join(dataPath, "templates"));
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
1079
|
+
const agentCoreDir = getAgentCoreDir();
|
|
1080
|
+
syncMetadataToAll(agentCoreDir, dataPaths);
|
|
1081
|
+
copyDirToAllStoragePaths(path10.join(agentCoreDir, "templates"), "templates", dataPaths);
|
|
1082
|
+
if (config.storageMode === "workspace") {
|
|
1083
|
+
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
1084
|
+
if (config.tools.includes("copilot")) {
|
|
1085
|
+
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
1086
|
+
ensureDir(copilotPath);
|
|
1087
|
+
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
1088
|
+
}
|
|
1089
|
+
if (config.tools.includes("antigravity")) {
|
|
1090
|
+
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
1091
|
+
ensureDir(antigravityPath);
|
|
1092
|
+
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
function createWorkspaceConfig(config, workspacePath, workspaceName) {
|
|
1097
|
+
if (config.storageMode !== "workspace") return;
|
|
1098
|
+
const configPath = path10.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
1099
|
+
ensureDir(path10.dirname(configPath));
|
|
1100
|
+
let content = `# RRCE-Workflow Configuration
|
|
1101
|
+
version: 1
|
|
1102
|
+
|
|
1103
|
+
storage:
|
|
1104
|
+
mode: ${config.storageMode}`;
|
|
1105
|
+
if (config.globalPath && config.globalPath !== getDefaultRRCEHome()) {
|
|
1106
|
+
content += `
|
|
1107
|
+
globalPath: "${config.globalPath}"`;
|
|
1108
|
+
}
|
|
1109
|
+
content += `
|
|
1110
|
+
|
|
1111
|
+
project:
|
|
1112
|
+
name: "${workspaceName}"
|
|
1113
|
+
|
|
1114
|
+
tools:
|
|
1115
|
+
copilot: ${config.tools.includes("copilot")}
|
|
1116
|
+
antigravity: ${config.tools.includes("antigravity")}
|
|
1117
|
+
`;
|
|
1118
|
+
if (config.linkedProjects.length > 0) {
|
|
1119
|
+
content += `
|
|
1120
|
+
linked_projects:
|
|
1121
|
+
`;
|
|
1122
|
+
config.linkedProjects.forEach((name) => {
|
|
1123
|
+
content += ` - ${name}
|
|
1124
|
+
`;
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
fs9.writeFileSync(configPath, content);
|
|
1128
|
+
}
|
|
1129
|
+
async function registerWithMCP(config, workspacePath, workspaceName) {
|
|
1130
|
+
if (!config.exposeToMCP) return;
|
|
1131
|
+
try {
|
|
1132
|
+
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
1133
|
+
const mcpConfig = loadMCPConfig3();
|
|
1134
|
+
if (config.storageMode === "workspace") {
|
|
1135
|
+
setProjectConfig2(
|
|
1136
|
+
mcpConfig,
|
|
1137
|
+
workspaceName,
|
|
1138
|
+
true,
|
|
1139
|
+
void 0,
|
|
1140
|
+
void 0,
|
|
1141
|
+
config.enableRAG ? { enabled: true } : void 0
|
|
1142
|
+
);
|
|
1143
|
+
} else {
|
|
1144
|
+
setProjectConfig2(
|
|
1145
|
+
mcpConfig,
|
|
1146
|
+
workspaceName,
|
|
1147
|
+
true,
|
|
1148
|
+
void 0,
|
|
1149
|
+
workspacePath,
|
|
1150
|
+
config.enableRAG ? { enabled: true } : void 0
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
saveMCPConfig2(mcpConfig);
|
|
1154
|
+
} catch (e) {
|
|
1155
|
+
note2(
|
|
1156
|
+
`${pc4.yellow("\u26A0")} Could not register project with MCP
|
|
1157
|
+
Error: ${e instanceof Error ? e.message : String(e)}
|
|
1158
|
+
|
|
1159
|
+
You can configure MCP later: ${pc4.cyan("npx rrce-workflow mcp")}`,
|
|
1160
|
+
"MCP Registration Warning"
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
1165
|
+
const globalPath = path10.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
|
|
1166
|
+
const workspacePath = path10.join(workspaceRoot, ".rrce-workflow");
|
|
1167
|
+
switch (mode) {
|
|
1168
|
+
case "global":
|
|
1169
|
+
return [globalPath];
|
|
1170
|
+
case "workspace":
|
|
1171
|
+
return [workspacePath];
|
|
1172
|
+
default:
|
|
1173
|
+
return [globalPath];
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
var init_setup_actions = __esm({
|
|
1177
|
+
"src/commands/wizard/setup-actions.ts"() {
|
|
1178
|
+
"use strict";
|
|
1179
|
+
init_paths();
|
|
1180
|
+
init_prompts();
|
|
1181
|
+
init_utils();
|
|
1182
|
+
init_vscode();
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
// src/commands/wizard/gitignore.ts
|
|
1187
|
+
var gitignore_exports = {};
|
|
1188
|
+
__export(gitignore_exports, {
|
|
1189
|
+
updateGitignore: () => updateGitignore
|
|
1190
|
+
});
|
|
1191
|
+
import * as fs10 from "fs";
|
|
1192
|
+
import * as path11 from "path";
|
|
1193
|
+
function updateGitignore(workspacePath, storageMode, tools) {
|
|
1194
|
+
const gitignorePath = path11.join(workspacePath, ".gitignore");
|
|
1195
|
+
const entries = [];
|
|
1196
|
+
if (storageMode === "workspace") {
|
|
1197
|
+
entries.push(".rrce-workflow/");
|
|
1198
|
+
}
|
|
1199
|
+
if (tools.includes("copilot")) {
|
|
1200
|
+
entries.push(".github/agents/");
|
|
1201
|
+
}
|
|
1202
|
+
if (tools.includes("antigravity")) {
|
|
1203
|
+
entries.push(".agent/workflows/");
|
|
1204
|
+
}
|
|
1205
|
+
entries.push("*.code-workspace");
|
|
1206
|
+
if (entries.length === 0) {
|
|
1207
|
+
return false;
|
|
1208
|
+
}
|
|
1209
|
+
let existingContent = "";
|
|
1210
|
+
if (fs10.existsSync(gitignorePath)) {
|
|
1211
|
+
existingContent = fs10.readFileSync(gitignorePath, "utf-8");
|
|
1212
|
+
}
|
|
1213
|
+
const sectionMarker = "# RRCE-Workflow Generated";
|
|
1214
|
+
if (existingContent.includes(sectionMarker)) {
|
|
1215
|
+
return false;
|
|
1216
|
+
}
|
|
1217
|
+
const newSection = `
|
|
1218
|
+
${sectionMarker}
|
|
1219
|
+
# Uncomment the following lines if you want to ignore rrce-workflow generated files:
|
|
1220
|
+
${entries.map((e) => `# ${e}`).join("\n")}
|
|
1221
|
+
`;
|
|
1222
|
+
const updatedContent = existingContent.trimEnd() + newSection;
|
|
1223
|
+
fs10.writeFileSync(gitignorePath, updatedContent);
|
|
1224
|
+
return true;
|
|
1150
1225
|
}
|
|
1151
|
-
var
|
|
1152
|
-
"src/
|
|
1226
|
+
var init_gitignore = __esm({
|
|
1227
|
+
"src/commands/wizard/gitignore.ts"() {
|
|
1153
1228
|
"use strict";
|
|
1154
|
-
init_paths();
|
|
1155
|
-
init_types();
|
|
1156
1229
|
}
|
|
1157
1230
|
});
|
|
1158
1231
|
|
|
1159
1232
|
// src/mcp/logger.ts
|
|
1160
|
-
import * as
|
|
1161
|
-
import * as
|
|
1233
|
+
import * as fs11 from "fs";
|
|
1234
|
+
import * as path12 from "path";
|
|
1162
1235
|
function getLogFilePath() {
|
|
1163
1236
|
const workspaceRoot = detectWorkspaceRoot();
|
|
1164
1237
|
const rrceHome = getEffectiveRRCEHome(workspaceRoot);
|
|
1165
|
-
return
|
|
1238
|
+
return path12.join(rrceHome, "mcp-server.log");
|
|
1166
1239
|
}
|
|
1167
1240
|
var Logger, logger;
|
|
1168
1241
|
var init_logger = __esm({
|
|
@@ -1193,11 +1266,11 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1193
1266
|
}
|
|
1194
1267
|
logMessage += "\n";
|
|
1195
1268
|
try {
|
|
1196
|
-
const dir =
|
|
1197
|
-
if (!
|
|
1198
|
-
|
|
1269
|
+
const dir = path12.dirname(this.logPath);
|
|
1270
|
+
if (!fs11.existsSync(dir)) {
|
|
1271
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
1199
1272
|
}
|
|
1200
|
-
|
|
1273
|
+
fs11.appendFileSync(this.logPath, logMessage);
|
|
1201
1274
|
} catch (e) {
|
|
1202
1275
|
console.error(`[Logger Failure] Could not write to ${this.logPath}`, e);
|
|
1203
1276
|
console.error(logMessage);
|
|
@@ -1221,8 +1294,8 @@ ${JSON.stringify(data, null, 2)}`;
|
|
|
1221
1294
|
});
|
|
1222
1295
|
|
|
1223
1296
|
// src/mcp/services/rag.ts
|
|
1224
|
-
import * as
|
|
1225
|
-
import * as
|
|
1297
|
+
import * as fs12 from "fs";
|
|
1298
|
+
import * as path13 from "path";
|
|
1226
1299
|
var INDEX_VERSION, DEFAULT_MODEL, RAGService;
|
|
1227
1300
|
var init_rag = __esm({
|
|
1228
1301
|
"src/mcp/services/rag.ts"() {
|
|
@@ -1263,9 +1336,9 @@ var init_rag = __esm({
|
|
|
1263
1336
|
*/
|
|
1264
1337
|
loadIndex() {
|
|
1265
1338
|
if (this.index) return;
|
|
1266
|
-
if (
|
|
1339
|
+
if (fs12.existsSync(this.indexPath)) {
|
|
1267
1340
|
try {
|
|
1268
|
-
const data =
|
|
1341
|
+
const data = fs12.readFileSync(this.indexPath, "utf-8");
|
|
1269
1342
|
this.index = JSON.parse(data);
|
|
1270
1343
|
logger.info(`RAG: Loaded index from ${this.indexPath} with ${this.index?.chunks.length} chunks.`);
|
|
1271
1344
|
} catch (error) {
|
|
@@ -1291,11 +1364,11 @@ var init_rag = __esm({
|
|
|
1291
1364
|
saveIndex() {
|
|
1292
1365
|
if (!this.index) return;
|
|
1293
1366
|
try {
|
|
1294
|
-
const dir =
|
|
1295
|
-
if (!
|
|
1296
|
-
|
|
1367
|
+
const dir = path13.dirname(this.indexPath);
|
|
1368
|
+
if (!fs12.existsSync(dir)) {
|
|
1369
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
1297
1370
|
}
|
|
1298
|
-
|
|
1371
|
+
fs12.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2));
|
|
1299
1372
|
logger.info(`RAG: Saved index to ${this.indexPath} with ${this.index.chunks.length} chunks.`);
|
|
1300
1373
|
} catch (error) {
|
|
1301
1374
|
logger.error(`RAG: Failed to save index to ${this.indexPath}`, error);
|
|
@@ -1304,10 +1377,10 @@ var init_rag = __esm({
|
|
|
1304
1377
|
/**
|
|
1305
1378
|
* Generate embedding for text
|
|
1306
1379
|
*/
|
|
1307
|
-
async generateEmbedding(
|
|
1380
|
+
async generateEmbedding(text2) {
|
|
1308
1381
|
const pipe = await this.getPipeline();
|
|
1309
1382
|
try {
|
|
1310
|
-
const output = await pipe(
|
|
1383
|
+
const output = await pipe(text2, { pooling: "mean", normalize: true });
|
|
1311
1384
|
return Array.from(output.data);
|
|
1312
1385
|
} catch (error) {
|
|
1313
1386
|
logger.error("RAG: Error generating embedding", error);
|
|
@@ -1411,8 +1484,8 @@ var init_rag = __esm({
|
|
|
1411
1484
|
});
|
|
1412
1485
|
|
|
1413
1486
|
// src/mcp/resources.ts
|
|
1414
|
-
import * as
|
|
1415
|
-
import * as
|
|
1487
|
+
import * as fs13 from "fs";
|
|
1488
|
+
import * as path14 from "path";
|
|
1416
1489
|
function getExposedProjects() {
|
|
1417
1490
|
const config = loadMCPConfig();
|
|
1418
1491
|
const allProjects = scanForProjects();
|
|
@@ -1420,12 +1493,12 @@ function getExposedProjects() {
|
|
|
1420
1493
|
const activeProject = detectActiveProject(globalProjects);
|
|
1421
1494
|
let linkedProjects = [];
|
|
1422
1495
|
if (activeProject) {
|
|
1423
|
-
const localConfigPath =
|
|
1496
|
+
const localConfigPath = path14.join(activeProject.dataPath, "config.yaml");
|
|
1424
1497
|
let cfgContent = null;
|
|
1425
|
-
if (
|
|
1426
|
-
cfgContent =
|
|
1427
|
-
} else if (
|
|
1428
|
-
cfgContent =
|
|
1498
|
+
if (fs13.existsSync(path14.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"))) {
|
|
1499
|
+
cfgContent = fs13.readFileSync(path14.join(activeProject.dataPath, ".rrce-workflow", "config.yaml"), "utf-8");
|
|
1500
|
+
} else if (fs13.existsSync(path14.join(activeProject.dataPath, ".rrce-workflow.yaml"))) {
|
|
1501
|
+
cfgContent = fs13.readFileSync(path14.join(activeProject.dataPath, ".rrce-workflow.yaml"), "utf-8");
|
|
1429
1502
|
}
|
|
1430
1503
|
if (cfgContent) {
|
|
1431
1504
|
if (cfgContent.includes("linked_projects:")) {
|
|
@@ -1485,11 +1558,11 @@ function getProjectContext(projectName) {
|
|
|
1485
1558
|
if (!project.knowledgePath) {
|
|
1486
1559
|
return null;
|
|
1487
1560
|
}
|
|
1488
|
-
const contextPath =
|
|
1489
|
-
if (!
|
|
1561
|
+
const contextPath = path14.join(project.knowledgePath, "project-context.md");
|
|
1562
|
+
if (!fs13.existsSync(contextPath)) {
|
|
1490
1563
|
return null;
|
|
1491
1564
|
}
|
|
1492
|
-
return
|
|
1565
|
+
return fs13.readFileSync(contextPath, "utf-8");
|
|
1493
1566
|
}
|
|
1494
1567
|
function getProjectTasks(projectName) {
|
|
1495
1568
|
const config = loadMCPConfig();
|
|
@@ -1502,18 +1575,18 @@ function getProjectTasks(projectName) {
|
|
|
1502
1575
|
if (!permissions.tasks) {
|
|
1503
1576
|
return [];
|
|
1504
1577
|
}
|
|
1505
|
-
if (!project.tasksPath || !
|
|
1578
|
+
if (!project.tasksPath || !fs13.existsSync(project.tasksPath)) {
|
|
1506
1579
|
return [];
|
|
1507
1580
|
}
|
|
1508
1581
|
const tasks = [];
|
|
1509
1582
|
try {
|
|
1510
|
-
const taskDirs =
|
|
1583
|
+
const taskDirs = fs13.readdirSync(project.tasksPath, { withFileTypes: true });
|
|
1511
1584
|
for (const dir of taskDirs) {
|
|
1512
1585
|
if (!dir.isDirectory()) continue;
|
|
1513
|
-
const metaPath =
|
|
1514
|
-
if (
|
|
1586
|
+
const metaPath = path14.join(project.tasksPath, dir.name, "meta.json");
|
|
1587
|
+
if (fs13.existsSync(metaPath)) {
|
|
1515
1588
|
try {
|
|
1516
|
-
const meta = JSON.parse(
|
|
1589
|
+
const meta = JSON.parse(fs13.readFileSync(metaPath, "utf-8"));
|
|
1517
1590
|
tasks.push(meta);
|
|
1518
1591
|
} catch {
|
|
1519
1592
|
}
|
|
@@ -1537,13 +1610,13 @@ async function searchKnowledge(query) {
|
|
|
1537
1610
|
const useRAG = projConfig?.semanticSearch?.enabled;
|
|
1538
1611
|
if (useRAG) {
|
|
1539
1612
|
try {
|
|
1540
|
-
const indexPath =
|
|
1613
|
+
const indexPath = path14.join(project.knowledgePath, "embeddings.json");
|
|
1541
1614
|
const rag = new RAGService(indexPath, projConfig?.semanticSearch?.model);
|
|
1542
1615
|
const ragResults = await rag.search(query, 5);
|
|
1543
1616
|
for (const r of ragResults) {
|
|
1544
1617
|
results.push({
|
|
1545
1618
|
project: project.name,
|
|
1546
|
-
file:
|
|
1619
|
+
file: path14.relative(project.knowledgePath, r.filePath),
|
|
1547
1620
|
matches: [r.content],
|
|
1548
1621
|
// The chunk content is the match
|
|
1549
1622
|
score: r.score
|
|
@@ -1554,11 +1627,11 @@ async function searchKnowledge(query) {
|
|
|
1554
1627
|
continue;
|
|
1555
1628
|
}
|
|
1556
1629
|
try {
|
|
1557
|
-
const files =
|
|
1630
|
+
const files = fs13.readdirSync(project.knowledgePath);
|
|
1558
1631
|
for (const file of files) {
|
|
1559
1632
|
if (!file.endsWith(".md")) continue;
|
|
1560
|
-
const filePath =
|
|
1561
|
-
const content =
|
|
1633
|
+
const filePath = path14.join(project.knowledgePath, file);
|
|
1634
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
1562
1635
|
const lines = content.split("\n");
|
|
1563
1636
|
const matches = [];
|
|
1564
1637
|
for (const line of lines) {
|
|
@@ -1593,18 +1666,18 @@ async function indexKnowledge(projectName, force = false) {
|
|
|
1593
1666
|
if (!projConfig?.semanticSearch?.enabled) {
|
|
1594
1667
|
return { success: false, message: "Semantic Search is not enabled for this project", filesIndexed: 0 };
|
|
1595
1668
|
}
|
|
1596
|
-
if (!project.knowledgePath || !
|
|
1669
|
+
if (!project.knowledgePath || !fs13.existsSync(project.knowledgePath)) {
|
|
1597
1670
|
return { success: false, message: "No knowledge directory found", filesIndexed: 0 };
|
|
1598
1671
|
}
|
|
1599
1672
|
try {
|
|
1600
|
-
const indexPath =
|
|
1673
|
+
const indexPath = path14.join(project.knowledgePath, "embeddings.json");
|
|
1601
1674
|
const rag = new RAGService(indexPath, projConfig.semanticSearch.model);
|
|
1602
|
-
const files =
|
|
1675
|
+
const files = fs13.readdirSync(project.knowledgePath).filter((f) => f.endsWith(".md"));
|
|
1603
1676
|
let count = 0;
|
|
1604
1677
|
for (const file of files) {
|
|
1605
|
-
const filePath =
|
|
1606
|
-
const content =
|
|
1607
|
-
await rag.indexFile(
|
|
1678
|
+
const filePath = path14.join(project.knowledgePath, file);
|
|
1679
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
1680
|
+
await rag.indexFile(path14.join(project.knowledgePath, file), content);
|
|
1608
1681
|
count++;
|
|
1609
1682
|
}
|
|
1610
1683
|
return { success: true, message: `Successfully indexed ${count} files`, filesIndexed: count };
|
|
@@ -2106,8 +2179,8 @@ var init_server = __esm({
|
|
|
2106
2179
|
});
|
|
2107
2180
|
|
|
2108
2181
|
// src/mcp/install.ts
|
|
2109
|
-
import * as
|
|
2110
|
-
import * as
|
|
2182
|
+
import * as fs14 from "fs";
|
|
2183
|
+
import * as path15 from "path";
|
|
2111
2184
|
import * as os from "os";
|
|
2112
2185
|
function checkInstallStatus(workspacePath) {
|
|
2113
2186
|
return {
|
|
@@ -2118,37 +2191,37 @@ function checkInstallStatus(workspacePath) {
|
|
|
2118
2191
|
};
|
|
2119
2192
|
}
|
|
2120
2193
|
function checkAntigravityConfig() {
|
|
2121
|
-
if (!
|
|
2194
|
+
if (!fs14.existsSync(ANTIGRAVITY_CONFIG)) return false;
|
|
2122
2195
|
try {
|
|
2123
|
-
const content = JSON.parse(
|
|
2196
|
+
const content = JSON.parse(fs14.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
2124
2197
|
return !!content.mcpServers?.["rrce"];
|
|
2125
2198
|
} catch {
|
|
2126
2199
|
return false;
|
|
2127
2200
|
}
|
|
2128
2201
|
}
|
|
2129
2202
|
function checkClaudeConfig() {
|
|
2130
|
-
if (!
|
|
2203
|
+
if (!fs14.existsSync(CLAUDE_CONFIG)) return false;
|
|
2131
2204
|
try {
|
|
2132
|
-
const content = JSON.parse(
|
|
2205
|
+
const content = JSON.parse(fs14.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
2133
2206
|
return !!content.mcpServers?.["rrce"];
|
|
2134
2207
|
} catch {
|
|
2135
2208
|
return false;
|
|
2136
2209
|
}
|
|
2137
2210
|
}
|
|
2138
2211
|
function checkVSCodeGlobalConfig() {
|
|
2139
|
-
if (!
|
|
2212
|
+
if (!fs14.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
|
|
2140
2213
|
try {
|
|
2141
|
-
const content = JSON.parse(
|
|
2214
|
+
const content = JSON.parse(fs14.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
2142
2215
|
return !!content["mcp.servers"]?.["rrce"];
|
|
2143
2216
|
} catch {
|
|
2144
2217
|
return false;
|
|
2145
2218
|
}
|
|
2146
2219
|
}
|
|
2147
2220
|
function checkVSCodeWorkspaceConfig(workspacePath) {
|
|
2148
|
-
const configPath =
|
|
2149
|
-
if (!
|
|
2221
|
+
const configPath = path15.join(workspacePath, ".vscode", "mcp.json");
|
|
2222
|
+
if (!fs14.existsSync(configPath)) return false;
|
|
2150
2223
|
try {
|
|
2151
|
-
const content = JSON.parse(
|
|
2224
|
+
const content = JSON.parse(fs14.readFileSync(configPath, "utf-8"));
|
|
2152
2225
|
return !!content.servers?.["rrce"];
|
|
2153
2226
|
} catch {
|
|
2154
2227
|
return false;
|
|
@@ -2173,14 +2246,14 @@ function installToConfig(target, workspacePath) {
|
|
|
2173
2246
|
}
|
|
2174
2247
|
}
|
|
2175
2248
|
function installToAntigravity() {
|
|
2176
|
-
const dir =
|
|
2177
|
-
if (!
|
|
2178
|
-
|
|
2249
|
+
const dir = path15.dirname(ANTIGRAVITY_CONFIG);
|
|
2250
|
+
if (!fs14.existsSync(dir)) {
|
|
2251
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
2179
2252
|
}
|
|
2180
2253
|
let config = { mcpServers: {} };
|
|
2181
|
-
if (
|
|
2254
|
+
if (fs14.existsSync(ANTIGRAVITY_CONFIG)) {
|
|
2182
2255
|
try {
|
|
2183
|
-
config = JSON.parse(
|
|
2256
|
+
config = JSON.parse(fs14.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
2184
2257
|
} catch {
|
|
2185
2258
|
}
|
|
2186
2259
|
}
|
|
@@ -2190,21 +2263,21 @@ function installToAntigravity() {
|
|
|
2190
2263
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2191
2264
|
};
|
|
2192
2265
|
try {
|
|
2193
|
-
|
|
2266
|
+
fs14.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
|
|
2194
2267
|
return true;
|
|
2195
2268
|
} catch {
|
|
2196
2269
|
return false;
|
|
2197
2270
|
}
|
|
2198
2271
|
}
|
|
2199
2272
|
function installToClaude() {
|
|
2200
|
-
const dir =
|
|
2201
|
-
if (!
|
|
2202
|
-
|
|
2273
|
+
const dir = path15.dirname(CLAUDE_CONFIG);
|
|
2274
|
+
if (!fs14.existsSync(dir)) {
|
|
2275
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
2203
2276
|
}
|
|
2204
2277
|
let config = { mcpServers: {} };
|
|
2205
|
-
if (
|
|
2278
|
+
if (fs14.existsSync(CLAUDE_CONFIG)) {
|
|
2206
2279
|
try {
|
|
2207
|
-
config = JSON.parse(
|
|
2280
|
+
config = JSON.parse(fs14.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
2208
2281
|
} catch {
|
|
2209
2282
|
}
|
|
2210
2283
|
}
|
|
@@ -2214,21 +2287,21 @@ function installToClaude() {
|
|
|
2214
2287
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2215
2288
|
};
|
|
2216
2289
|
try {
|
|
2217
|
-
|
|
2290
|
+
fs14.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
|
|
2218
2291
|
return true;
|
|
2219
2292
|
} catch {
|
|
2220
2293
|
return false;
|
|
2221
2294
|
}
|
|
2222
2295
|
}
|
|
2223
2296
|
function installToVSCodeGlobal() {
|
|
2224
|
-
const dir =
|
|
2225
|
-
if (!
|
|
2226
|
-
|
|
2297
|
+
const dir = path15.dirname(VSCODE_GLOBAL_CONFIG);
|
|
2298
|
+
if (!fs14.existsSync(dir)) {
|
|
2299
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
2227
2300
|
}
|
|
2228
2301
|
let settings = {};
|
|
2229
|
-
if (
|
|
2302
|
+
if (fs14.existsSync(VSCODE_GLOBAL_CONFIG)) {
|
|
2230
2303
|
try {
|
|
2231
|
-
settings = JSON.parse(
|
|
2304
|
+
settings = JSON.parse(fs14.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
2232
2305
|
} catch {
|
|
2233
2306
|
}
|
|
2234
2307
|
}
|
|
@@ -2238,22 +2311,22 @@ function installToVSCodeGlobal() {
|
|
|
2238
2311
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2239
2312
|
};
|
|
2240
2313
|
try {
|
|
2241
|
-
|
|
2314
|
+
fs14.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
|
|
2242
2315
|
return true;
|
|
2243
2316
|
} catch {
|
|
2244
2317
|
return false;
|
|
2245
2318
|
}
|
|
2246
2319
|
}
|
|
2247
2320
|
function installToVSCodeWorkspace(workspacePath) {
|
|
2248
|
-
const vscodeDir =
|
|
2249
|
-
const configPath =
|
|
2250
|
-
if (!
|
|
2251
|
-
|
|
2321
|
+
const vscodeDir = path15.join(workspacePath, ".vscode");
|
|
2322
|
+
const configPath = path15.join(vscodeDir, "mcp.json");
|
|
2323
|
+
if (!fs14.existsSync(vscodeDir)) {
|
|
2324
|
+
fs14.mkdirSync(vscodeDir, { recursive: true });
|
|
2252
2325
|
}
|
|
2253
2326
|
let config = { servers: {} };
|
|
2254
|
-
if (
|
|
2327
|
+
if (fs14.existsSync(configPath)) {
|
|
2255
2328
|
try {
|
|
2256
|
-
config = JSON.parse(
|
|
2329
|
+
config = JSON.parse(fs14.readFileSync(configPath, "utf-8"));
|
|
2257
2330
|
} catch {
|
|
2258
2331
|
}
|
|
2259
2332
|
}
|
|
@@ -2263,7 +2336,7 @@ function installToVSCodeWorkspace(workspacePath) {
|
|
|
2263
2336
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
2264
2337
|
};
|
|
2265
2338
|
try {
|
|
2266
|
-
|
|
2339
|
+
fs14.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
2267
2340
|
return true;
|
|
2268
2341
|
} catch {
|
|
2269
2342
|
return false;
|
|
@@ -2287,15 +2360,15 @@ var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG, VSCODE_GLOBAL_CONFIG;
|
|
|
2287
2360
|
var init_install = __esm({
|
|
2288
2361
|
"src/mcp/install.ts"() {
|
|
2289
2362
|
"use strict";
|
|
2290
|
-
ANTIGRAVITY_CONFIG =
|
|
2291
|
-
CLAUDE_CONFIG =
|
|
2292
|
-
VSCODE_GLOBAL_CONFIG =
|
|
2363
|
+
ANTIGRAVITY_CONFIG = path15.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
|
|
2364
|
+
CLAUDE_CONFIG = path15.join(os.homedir(), ".config/claude/claude_desktop_config.json");
|
|
2365
|
+
VSCODE_GLOBAL_CONFIG = path15.join(os.homedir(), ".config/Code/User/settings.json");
|
|
2293
2366
|
}
|
|
2294
2367
|
});
|
|
2295
2368
|
|
|
2296
2369
|
// src/mcp/commands/configure.ts
|
|
2297
|
-
import { spinner, note as
|
|
2298
|
-
import
|
|
2370
|
+
import { spinner, note as note3, multiselect as multiselect2, isCancel as isCancel3, confirm as confirm2 } from "@clack/prompts";
|
|
2371
|
+
import pc5 from "picocolors";
|
|
2299
2372
|
async function handleConfigure() {
|
|
2300
2373
|
const s = spinner();
|
|
2301
2374
|
s.start("Scanning for projects...");
|
|
@@ -2304,7 +2377,7 @@ async function handleConfigure() {
|
|
|
2304
2377
|
logger.info("Configure: Loaded config", { projects: config.projects, defaultMode: config.defaults.includeNew });
|
|
2305
2378
|
s.stop("Projects found");
|
|
2306
2379
|
if (projects.length === 0) {
|
|
2307
|
-
|
|
2380
|
+
note3('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
2308
2381
|
return;
|
|
2309
2382
|
}
|
|
2310
2383
|
const options = projects.map((project) => {
|
|
@@ -2315,7 +2388,7 @@ async function handleConfigure() {
|
|
|
2315
2388
|
return {
|
|
2316
2389
|
value: project.dataPath,
|
|
2317
2390
|
// Use precise data path as unique identifier
|
|
2318
|
-
label: `${project.name} ${
|
|
2391
|
+
label: `${project.name} ${pc5.dim(`(${project.source})`)}`,
|
|
2319
2392
|
hint: project.dataPath
|
|
2320
2393
|
};
|
|
2321
2394
|
});
|
|
@@ -2325,27 +2398,27 @@ async function handleConfigure() {
|
|
|
2325
2398
|
);
|
|
2326
2399
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
2327
2400
|
}).map((p) => p.dataPath);
|
|
2328
|
-
const selected = await
|
|
2401
|
+
const selected = await multiselect2({
|
|
2329
2402
|
message: "Select projects to expose via MCP:",
|
|
2330
2403
|
options,
|
|
2331
2404
|
initialValues: currentlyExposed,
|
|
2332
2405
|
required: false
|
|
2333
2406
|
});
|
|
2334
|
-
if (
|
|
2407
|
+
if (isCancel3(selected)) {
|
|
2335
2408
|
return;
|
|
2336
2409
|
}
|
|
2337
2410
|
const selectedPaths = selected;
|
|
2338
2411
|
logger.info("Configure: User selected projects by path", selectedPaths);
|
|
2339
2412
|
let enableSemanticSearch = false;
|
|
2340
2413
|
if (selectedPaths.length > 0) {
|
|
2341
|
-
const shouldEnable = await
|
|
2414
|
+
const shouldEnable = await confirm2({
|
|
2342
2415
|
message: "Enable Semantic Search (Local Mini RAG)?",
|
|
2343
2416
|
initialValue: false
|
|
2344
2417
|
});
|
|
2345
|
-
if (
|
|
2418
|
+
if (isCancel3(shouldEnable)) return;
|
|
2346
2419
|
enableSemanticSearch = shouldEnable;
|
|
2347
2420
|
if (enableSemanticSearch) {
|
|
2348
|
-
|
|
2421
|
+
note3(
|
|
2349
2422
|
`This enables "search_knowledge" tool for agents.
|
|
2350
2423
|
First use will download a ~100MB embedding model (all-MiniLM-L6-v2)
|
|
2351
2424
|
to your local device (one-time).`,
|
|
@@ -2364,8 +2437,8 @@ to your local device (one-time).`,
|
|
|
2364
2437
|
saveMCPConfig(config);
|
|
2365
2438
|
logger.info("Configure: Config saved", config);
|
|
2366
2439
|
const exposedCount = selectedPaths.length;
|
|
2367
|
-
|
|
2368
|
-
`${
|
|
2440
|
+
note3(
|
|
2441
|
+
`${pc5.green("\u2713")} Configuration saved!
|
|
2369
2442
|
|
|
2370
2443
|
Exposed projects: ${exposedCount}
|
|
2371
2444
|
Hidden projects: ${projects.length - exposedCount}`,
|
|
@@ -2374,13 +2447,13 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
2374
2447
|
}
|
|
2375
2448
|
async function handleConfigureGlobalPath() {
|
|
2376
2449
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
2377
|
-
const
|
|
2378
|
-
const
|
|
2379
|
-
|
|
2380
|
-
`MCP Hub requires a ${
|
|
2450
|
+
const fs21 = await import("fs");
|
|
2451
|
+
const path19 = await import("path");
|
|
2452
|
+
note3(
|
|
2453
|
+
`MCP Hub requires a ${pc5.bold("global storage path")} to store its configuration
|
|
2381
2454
|
and coordinate across projects.
|
|
2382
2455
|
|
|
2383
|
-
Your current setup uses ${
|
|
2456
|
+
Your current setup uses ${pc5.cyan("workspace")} mode, which stores data
|
|
2384
2457
|
locally in each project. MCP needs a central location.`,
|
|
2385
2458
|
"Global Path Required"
|
|
2386
2459
|
);
|
|
@@ -2389,22 +2462,22 @@ locally in each project. MCP needs a central location.`,
|
|
|
2389
2462
|
return false;
|
|
2390
2463
|
}
|
|
2391
2464
|
try {
|
|
2392
|
-
if (!
|
|
2393
|
-
|
|
2465
|
+
if (!fs21.existsSync(resolvedPath)) {
|
|
2466
|
+
fs21.mkdirSync(resolvedPath, { recursive: true });
|
|
2394
2467
|
}
|
|
2395
2468
|
const config = loadMCPConfig();
|
|
2396
2469
|
saveMCPConfig(config);
|
|
2397
|
-
|
|
2398
|
-
`${
|
|
2470
|
+
note3(
|
|
2471
|
+
`${pc5.green("\u2713")} Global path configured: ${pc5.cyan(resolvedPath)}
|
|
2399
2472
|
|
|
2400
2473
|
MCP config will be stored at:
|
|
2401
|
-
${
|
|
2474
|
+
${path19.join(resolvedPath, "mcp.yaml")}`,
|
|
2402
2475
|
"Configuration Saved"
|
|
2403
2476
|
);
|
|
2404
2477
|
return true;
|
|
2405
2478
|
} catch (error) {
|
|
2406
|
-
|
|
2407
|
-
`${
|
|
2479
|
+
note3(
|
|
2480
|
+
`${pc5.red("\u2717")} Failed to create directory: ${error instanceof Error ? error.message : String(error)}`,
|
|
2408
2481
|
"Error"
|
|
2409
2482
|
);
|
|
2410
2483
|
return false;
|
|
@@ -2420,33 +2493,33 @@ var init_configure = __esm({
|
|
|
2420
2493
|
});
|
|
2421
2494
|
|
|
2422
2495
|
// src/mcp/commands/install-wizard.ts
|
|
2423
|
-
import { multiselect as
|
|
2424
|
-
import
|
|
2496
|
+
import { multiselect as multiselect3, note as note4, isCancel as isCancel4 } from "@clack/prompts";
|
|
2497
|
+
import pc6 from "picocolors";
|
|
2425
2498
|
async function runInstallWizard(workspacePath) {
|
|
2426
2499
|
const status = checkInstallStatus(workspacePath);
|
|
2427
2500
|
const options = [
|
|
2428
2501
|
{
|
|
2429
2502
|
value: "antigravity",
|
|
2430
2503
|
label: "Antigravity IDE",
|
|
2431
|
-
hint: status.antigravity ?
|
|
2504
|
+
hint: status.antigravity ? pc6.green("\u2713 Installed") : pc6.dim("Not installed")
|
|
2432
2505
|
},
|
|
2433
2506
|
{
|
|
2434
2507
|
value: "vscode-global",
|
|
2435
2508
|
label: "VSCode (Global Settings)",
|
|
2436
|
-
hint: status.vscodeGlobal ?
|
|
2509
|
+
hint: status.vscodeGlobal ? pc6.green("\u2713 Installed") : pc6.dim("Not installed")
|
|
2437
2510
|
},
|
|
2438
2511
|
{
|
|
2439
2512
|
value: "vscode-workspace",
|
|
2440
2513
|
label: "VSCode (Workspace Config)",
|
|
2441
|
-
hint: status.vscodeWorkspace ?
|
|
2514
|
+
hint: status.vscodeWorkspace ? pc6.green("\u2713 Installed") : pc6.dim("Not installed")
|
|
2442
2515
|
},
|
|
2443
2516
|
{
|
|
2444
2517
|
value: "claude",
|
|
2445
2518
|
label: "Claude Desktop",
|
|
2446
|
-
hint: status.claude ?
|
|
2519
|
+
hint: status.claude ? pc6.green("\u2713 Installed") : pc6.dim("Not installed")
|
|
2447
2520
|
}
|
|
2448
2521
|
];
|
|
2449
|
-
const selected = await
|
|
2522
|
+
const selected = await multiselect3({
|
|
2450
2523
|
message: "Select where to install RRCE MCP Server:",
|
|
2451
2524
|
options,
|
|
2452
2525
|
initialValues: [
|
|
@@ -2457,16 +2530,16 @@ async function runInstallWizard(workspacePath) {
|
|
|
2457
2530
|
],
|
|
2458
2531
|
required: false
|
|
2459
2532
|
});
|
|
2460
|
-
if (
|
|
2533
|
+
if (isCancel4(selected)) return;
|
|
2461
2534
|
const targets = selected;
|
|
2462
2535
|
const results = [];
|
|
2463
2536
|
for (const target of targets) {
|
|
2464
2537
|
const success = installToConfig(target, workspacePath);
|
|
2465
2538
|
const label = getTargetLabel(target);
|
|
2466
|
-
results.push(`${label}: ${success ?
|
|
2539
|
+
results.push(`${label}: ${success ? pc6.green("\u2713 Success") : pc6.red("\u2717 Failed")}`);
|
|
2467
2540
|
}
|
|
2468
2541
|
if (results.length > 0) {
|
|
2469
|
-
|
|
2542
|
+
note4(results.join("\n"), "Installation Results");
|
|
2470
2543
|
}
|
|
2471
2544
|
}
|
|
2472
2545
|
var init_install_wizard = __esm({
|
|
@@ -2593,10 +2666,8 @@ var init_ProjectsView = __esm({
|
|
|
2593
2666
|
"use strict";
|
|
2594
2667
|
init_SimpleSelect();
|
|
2595
2668
|
init_config();
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
const [config, setConfig] = useState2(loadMCPConfig());
|
|
2599
|
-
const allProjects = scanForProjects();
|
|
2669
|
+
ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange }) => {
|
|
2670
|
+
const [config, setConfig] = useState2(initialConfig);
|
|
2600
2671
|
const projectItems = allProjects.map((p) => {
|
|
2601
2672
|
const projectConfig = config.projects.find(
|
|
2602
2673
|
(c) => c.path && c.path === p.path || !c.path && c.name === p.name
|
|
@@ -2873,9 +2944,9 @@ var App_exports = {};
|
|
|
2873
2944
|
__export(App_exports, {
|
|
2874
2945
|
App: () => App
|
|
2875
2946
|
});
|
|
2876
|
-
import { useState as useState4, useEffect as
|
|
2947
|
+
import { useState as useState4, useEffect as useEffect3, useMemo, useCallback } from "react";
|
|
2877
2948
|
import { Box as Box10, useInput as useInput3, useApp } from "ink";
|
|
2878
|
-
import
|
|
2949
|
+
import fs15 from "fs";
|
|
2879
2950
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2880
2951
|
var TABS, App;
|
|
2881
2952
|
var init_App = __esm({
|
|
@@ -2888,6 +2959,7 @@ var init_App = __esm({
|
|
|
2888
2959
|
init_StatusBoard();
|
|
2889
2960
|
init_TabBar();
|
|
2890
2961
|
init_config();
|
|
2962
|
+
init_config_utils();
|
|
2891
2963
|
init_detection();
|
|
2892
2964
|
init_logger();
|
|
2893
2965
|
init_server();
|
|
@@ -2908,15 +2980,21 @@ var init_App = __esm({
|
|
|
2908
2980
|
pid: process.pid,
|
|
2909
2981
|
running: false
|
|
2910
2982
|
});
|
|
2911
|
-
const [
|
|
2912
|
-
const
|
|
2913
|
-
const
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2983
|
+
const [config, setConfig] = useState4(() => loadMCPConfig());
|
|
2984
|
+
const [projects, setProjects] = useState4(() => scanForProjects());
|
|
2985
|
+
const refreshData = useCallback(() => {
|
|
2986
|
+
setConfig(loadMCPConfig());
|
|
2987
|
+
setProjects(scanForProjects());
|
|
2988
|
+
}, []);
|
|
2989
|
+
const exposedProjects = useMemo(
|
|
2990
|
+
() => projects.filter((p) => {
|
|
2991
|
+
const cfg = config.projects.find(
|
|
2992
|
+
(c) => c.path && c.path === p.path || !c.path && c.name === p.name
|
|
2993
|
+
);
|
|
2994
|
+
return cfg?.expose ?? config.defaults.includeNew;
|
|
2995
|
+
}),
|
|
2996
|
+
[projects, config]
|
|
2997
|
+
);
|
|
2920
2998
|
const workspacePath = detectWorkspaceRoot();
|
|
2921
2999
|
const installStatus = checkInstallStatus(workspacePath);
|
|
2922
3000
|
const installedCount = [
|
|
@@ -2925,7 +3003,7 @@ var init_App = __esm({
|
|
|
2925
3003
|
installStatus.vscodeGlobal,
|
|
2926
3004
|
installStatus.vscodeWorkspace
|
|
2927
3005
|
].filter(Boolean).length;
|
|
2928
|
-
|
|
3006
|
+
useEffect3(() => {
|
|
2929
3007
|
const start = async () => {
|
|
2930
3008
|
const status = getMCPServerStatus();
|
|
2931
3009
|
if (!status.running) {
|
|
@@ -2941,21 +3019,21 @@ var init_App = __esm({
|
|
|
2941
3019
|
};
|
|
2942
3020
|
start();
|
|
2943
3021
|
}, []);
|
|
2944
|
-
|
|
3022
|
+
useEffect3(() => {
|
|
2945
3023
|
const logPath = getLogFilePath();
|
|
2946
3024
|
let lastSize = 0;
|
|
2947
|
-
if (
|
|
2948
|
-
const stats =
|
|
3025
|
+
if (fs15.existsSync(logPath)) {
|
|
3026
|
+
const stats = fs15.statSync(logPath);
|
|
2949
3027
|
lastSize = stats.size;
|
|
2950
3028
|
}
|
|
2951
3029
|
const interval = setInterval(() => {
|
|
2952
|
-
if (
|
|
2953
|
-
const stats =
|
|
3030
|
+
if (fs15.existsSync(logPath)) {
|
|
3031
|
+
const stats = fs15.statSync(logPath);
|
|
2954
3032
|
if (stats.size > lastSize) {
|
|
2955
3033
|
const buffer = Buffer.alloc(stats.size - lastSize);
|
|
2956
|
-
const fd =
|
|
2957
|
-
|
|
2958
|
-
|
|
3034
|
+
const fd = fs15.openSync(logPath, "r");
|
|
3035
|
+
fs15.readSync(fd, buffer, 0, buffer.length, lastSize);
|
|
3036
|
+
fs15.closeSync(fd);
|
|
2959
3037
|
const newContent = buffer.toString("utf-8");
|
|
2960
3038
|
const newLines = newContent.split("\n").filter((l) => l.trim());
|
|
2961
3039
|
setLogs((prev) => {
|
|
@@ -2977,9 +3055,9 @@ var init_App = __esm({
|
|
|
2977
3055
|
});
|
|
2978
3056
|
const termHeight = process.stdout.rows || 24;
|
|
2979
3057
|
const contentHeight = termHeight - 8;
|
|
2980
|
-
const handleConfigChange = () => {
|
|
2981
|
-
|
|
2982
|
-
};
|
|
3058
|
+
const handleConfigChange = useCallback(() => {
|
|
3059
|
+
refreshData();
|
|
3060
|
+
}, [refreshData]);
|
|
2983
3061
|
return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", padding: 0, height: termHeight, children: [
|
|
2984
3062
|
/* @__PURE__ */ jsx10(TabBar, { tabs: TABS, activeTab, onChange: setActiveTab }),
|
|
2985
3063
|
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexGrow: 1, children: [
|
|
@@ -2994,7 +3072,7 @@ var init_App = __esm({
|
|
|
2994
3072
|
}
|
|
2995
3073
|
}
|
|
2996
3074
|
),
|
|
2997
|
-
activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { onConfigChange: handleConfigChange }),
|
|
3075
|
+
activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { config, projects, onConfigChange: handleConfigChange }),
|
|
2998
3076
|
activeTab === "install" && /* @__PURE__ */ jsx10(InstallView, {}),
|
|
2999
3077
|
activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight })
|
|
3000
3078
|
] }),
|
|
@@ -3013,7 +3091,7 @@ var init_App = __esm({
|
|
|
3013
3091
|
});
|
|
3014
3092
|
|
|
3015
3093
|
// src/mcp/commands/start.ts
|
|
3016
|
-
import { confirm as
|
|
3094
|
+
import { confirm as confirm3, isCancel as isCancel5, text } from "@clack/prompts";
|
|
3017
3095
|
async function handleStartServer() {
|
|
3018
3096
|
const React11 = await import("react");
|
|
3019
3097
|
const { render } = await import("ink");
|
|
@@ -3027,11 +3105,11 @@ async function handleStartServer() {
|
|
|
3027
3105
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
3028
3106
|
});
|
|
3029
3107
|
if (exposedProjects.length === 0) {
|
|
3030
|
-
const shouldConfig = await
|
|
3108
|
+
const shouldConfig = await confirm3({
|
|
3031
3109
|
message: "No projects are currently exposed. Configure now?",
|
|
3032
3110
|
initialValue: true
|
|
3033
3111
|
});
|
|
3034
|
-
if (shouldConfig && !
|
|
3112
|
+
if (shouldConfig && !isCancel5(shouldConfig)) {
|
|
3035
3113
|
await handleConfigure();
|
|
3036
3114
|
return handleStartServer();
|
|
3037
3115
|
}
|
|
@@ -3047,7 +3125,7 @@ async function handleStartServer() {
|
|
|
3047
3125
|
if (isNaN(Number(value))) return "Port must be a number";
|
|
3048
3126
|
}
|
|
3049
3127
|
});
|
|
3050
|
-
if (
|
|
3128
|
+
if (isCancel5(portInput)) return;
|
|
3051
3129
|
const newPort = parseInt(portInput, 10);
|
|
3052
3130
|
if (newPort !== config.server.port) {
|
|
3053
3131
|
config.server.port = newPort;
|
|
@@ -3079,8 +3157,8 @@ var init_start = __esm({
|
|
|
3079
3157
|
});
|
|
3080
3158
|
|
|
3081
3159
|
// src/mcp/commands/status.ts
|
|
3082
|
-
import { spinner as spinner2, note as
|
|
3083
|
-
import
|
|
3160
|
+
import { spinner as spinner2, note as note5 } from "@clack/prompts";
|
|
3161
|
+
import pc7 from "picocolors";
|
|
3084
3162
|
async function handleShowStatus() {
|
|
3085
3163
|
const s = spinner2();
|
|
3086
3164
|
s.start("Loading projects...");
|
|
@@ -3090,36 +3168,36 @@ async function handleShowStatus() {
|
|
|
3090
3168
|
const installStatus = checkInstallStatus(workspacePath);
|
|
3091
3169
|
s.stop("Projects loaded");
|
|
3092
3170
|
if (projects.length === 0) {
|
|
3093
|
-
|
|
3171
|
+
note5('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
3094
3172
|
return;
|
|
3095
3173
|
}
|
|
3096
3174
|
const lines = [
|
|
3097
|
-
`${
|
|
3175
|
+
`${pc7.bold("Installation Status")}`,
|
|
3098
3176
|
"",
|
|
3099
|
-
` Antigravity: ${installStatus.antigravity ?
|
|
3100
|
-
` VSCode (Global): ${installStatus.vscodeGlobal ?
|
|
3101
|
-
` VSCode (Workspace): ${installStatus.vscodeWorkspace ?
|
|
3102
|
-
` Claude Desktop: ${installStatus.claude ?
|
|
3177
|
+
` Antigravity: ${installStatus.antigravity ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3178
|
+
` VSCode (Global): ${installStatus.vscodeGlobal ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3179
|
+
` VSCode (Workspace): ${installStatus.vscodeWorkspace ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3180
|
+
` Claude Desktop: ${installStatus.claude ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3103
3181
|
"",
|
|
3104
|
-
`${
|
|
3182
|
+
`${pc7.bold("Project Status")}`,
|
|
3105
3183
|
""
|
|
3106
3184
|
];
|
|
3107
3185
|
for (const project of projects) {
|
|
3108
3186
|
const projectConfig = config.projects.find((p) => p.name === project.name);
|
|
3109
3187
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
3110
|
-
const status = isExposed ?
|
|
3111
|
-
const source =
|
|
3188
|
+
const status = isExposed ? pc7.green("\u2713 exposed") : pc7.dim("\u25CB hidden");
|
|
3189
|
+
const source = pc7.dim(`(${project.source})`);
|
|
3112
3190
|
lines.push(` ${status} ${project.name} ${source}`);
|
|
3113
3191
|
}
|
|
3114
3192
|
lines.push("");
|
|
3115
|
-
lines.push(
|
|
3193
|
+
lines.push(pc7.dim(`Config: ${getMCPConfigPath()}`));
|
|
3116
3194
|
const serverStatus = getMCPServerStatus();
|
|
3117
3195
|
if (serverStatus.running) {
|
|
3118
|
-
lines.push(
|
|
3196
|
+
lines.push(pc7.green(`Server: running on port ${serverStatus.port}`));
|
|
3119
3197
|
} else {
|
|
3120
|
-
lines.push(
|
|
3198
|
+
lines.push(pc7.dim("Server: not running"));
|
|
3121
3199
|
}
|
|
3122
|
-
|
|
3200
|
+
note5(lines.join("\n"), "MCP Hub Status");
|
|
3123
3201
|
}
|
|
3124
3202
|
var init_status = __esm({
|
|
3125
3203
|
"src/mcp/commands/status.ts"() {
|
|
@@ -3133,46 +3211,46 @@ var init_status = __esm({
|
|
|
3133
3211
|
});
|
|
3134
3212
|
|
|
3135
3213
|
// src/mcp/commands/help.ts
|
|
3136
|
-
import { note as
|
|
3137
|
-
import
|
|
3214
|
+
import { note as note6 } from "@clack/prompts";
|
|
3215
|
+
import pc8 from "picocolors";
|
|
3138
3216
|
function showHelp() {
|
|
3139
3217
|
const help = `
|
|
3140
|
-
${
|
|
3218
|
+
${pc8.bold("RRCE MCP Hub")} - Cross-project AI assistant server
|
|
3141
3219
|
|
|
3142
|
-
${
|
|
3220
|
+
${pc8.bold("ABOUT")}
|
|
3143
3221
|
MCP (Model Context Protocol) allows AI assistants like Claude to
|
|
3144
3222
|
access your project knowledge in real-time. The RRCE MCP Hub
|
|
3145
3223
|
provides a central server that exposes selected projects.
|
|
3146
3224
|
|
|
3147
|
-
${
|
|
3148
|
-
${
|
|
3149
|
-
${
|
|
3150
|
-
${
|
|
3151
|
-
${
|
|
3152
|
-
|
|
3153
|
-
${
|
|
3154
|
-
${
|
|
3155
|
-
${
|
|
3156
|
-
${
|
|
3157
|
-
${
|
|
3158
|
-
|
|
3159
|
-
${
|
|
3160
|
-
${
|
|
3161
|
-
${
|
|
3162
|
-
${
|
|
3163
|
-
${
|
|
3164
|
-
|
|
3165
|
-
${
|
|
3166
|
-
${
|
|
3167
|
-
${
|
|
3168
|
-
${
|
|
3169
|
-
|
|
3170
|
-
${
|
|
3171
|
-
${
|
|
3172
|
-
${
|
|
3173
|
-
${
|
|
3225
|
+
${pc8.bold("MENU OPTIONS")}
|
|
3226
|
+
${pc8.cyan("Start MCP server")} Start the server for AI access
|
|
3227
|
+
${pc8.cyan("Configure projects")} Choose which projects to expose
|
|
3228
|
+
${pc8.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
|
|
3229
|
+
${pc8.cyan("View status")} See which projects are exposed
|
|
3230
|
+
|
|
3231
|
+
${pc8.bold("DIRECT COMMANDS")}
|
|
3232
|
+
${pc8.dim("rrce-workflow mcp start")} Start server directly
|
|
3233
|
+
${pc8.dim("rrce-workflow mcp stop")} Stop server directly
|
|
3234
|
+
${pc8.dim("rrce-workflow mcp status")} Show status directly
|
|
3235
|
+
${pc8.dim("rrce-workflow mcp help")} Show this help
|
|
3236
|
+
|
|
3237
|
+
${pc8.bold("IDE INSTALLATION")}
|
|
3238
|
+
${pc8.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
|
|
3239
|
+
${pc8.cyan("VSCode Global")} ~/.config/Code/User/settings.json
|
|
3240
|
+
${pc8.cyan("VSCode Workspace")} .vscode/mcp.json
|
|
3241
|
+
${pc8.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
|
|
3242
|
+
|
|
3243
|
+
${pc8.bold("SERVER COMMANDS")} (while running)
|
|
3244
|
+
${pc8.cyan("q")} Stop and quit ${pc8.cyan("p")} Reconfigure projects
|
|
3245
|
+
${pc8.cyan("i")} Install to IDE ${pc8.cyan("r")} Reload config
|
|
3246
|
+
${pc8.cyan("c")} Clear logs ${pc8.cyan("?")} Show help
|
|
3247
|
+
|
|
3248
|
+
${pc8.bold("RESOURCES EXPOSED")}
|
|
3249
|
+
${pc8.cyan("rrce://projects")} List all exposed projects
|
|
3250
|
+
${pc8.cyan("rrce://projects/{name}/context")} Get project context
|
|
3251
|
+
${pc8.cyan("rrce://projects/{name}/tasks")} Get project tasks
|
|
3174
3252
|
`;
|
|
3175
|
-
|
|
3253
|
+
note6(help.trim(), "Help");
|
|
3176
3254
|
}
|
|
3177
3255
|
var init_help = __esm({
|
|
3178
3256
|
"src/mcp/commands/help.ts"() {
|
|
@@ -3188,8 +3266,8 @@ __export(mcp_exports, {
|
|
|
3188
3266
|
handleStartServer: () => handleStartServer,
|
|
3189
3267
|
runMCP: () => runMCP
|
|
3190
3268
|
});
|
|
3191
|
-
import { intro, outro, confirm as
|
|
3192
|
-
import
|
|
3269
|
+
import { intro, outro, confirm as confirm4, note as note7, isCancel as isCancel6 } from "@clack/prompts";
|
|
3270
|
+
import pc9 from "picocolors";
|
|
3193
3271
|
async function runMCP(subcommand2) {
|
|
3194
3272
|
if (subcommand2) {
|
|
3195
3273
|
switch (subcommand2) {
|
|
@@ -3221,36 +3299,36 @@ async function runMCP(subcommand2) {
|
|
|
3221
3299
|
const workspacePath = detectWorkspaceRoot();
|
|
3222
3300
|
const globalPathCheck = await ensureMCPGlobalPath();
|
|
3223
3301
|
if (!globalPathCheck.configured) {
|
|
3224
|
-
intro(
|
|
3302
|
+
intro(pc9.bgCyan(pc9.black(" MCP Setup ")));
|
|
3225
3303
|
const configured = await handleConfigureGlobalPath();
|
|
3226
3304
|
if (!configured) {
|
|
3227
|
-
outro(
|
|
3305
|
+
outro(pc9.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
3228
3306
|
return;
|
|
3229
3307
|
}
|
|
3230
3308
|
}
|
|
3231
3309
|
const installed = isInstalledAnywhere(workspacePath);
|
|
3232
3310
|
if (!installed) {
|
|
3233
|
-
intro(
|
|
3234
|
-
|
|
3235
|
-
`${
|
|
3311
|
+
intro(pc9.bgCyan(pc9.black(" Welcome to MCP Hub ")));
|
|
3312
|
+
note7(
|
|
3313
|
+
`${pc9.bold("Set up Model Context Protocol")}
|
|
3236
3314
|
Allow AI assistants to access your project context.`,
|
|
3237
3315
|
"Getting Started"
|
|
3238
3316
|
);
|
|
3239
|
-
const shouldInstall = await
|
|
3317
|
+
const shouldInstall = await confirm4({
|
|
3240
3318
|
message: "Install MCP server integrations now?",
|
|
3241
3319
|
initialValue: true
|
|
3242
3320
|
});
|
|
3243
|
-
if (shouldInstall && !
|
|
3321
|
+
if (shouldInstall && !isCancel6(shouldInstall)) {
|
|
3244
3322
|
await runInstallWizard(workspacePath);
|
|
3245
|
-
const shouldStart = await
|
|
3323
|
+
const shouldStart = await confirm4({
|
|
3246
3324
|
message: "Start the MCP Dashboard?",
|
|
3247
3325
|
initialValue: true
|
|
3248
3326
|
});
|
|
3249
|
-
if (shouldStart && !
|
|
3327
|
+
if (shouldStart && !isCancel6(shouldStart)) {
|
|
3250
3328
|
await handleStartServer();
|
|
3251
3329
|
}
|
|
3252
3330
|
} else {
|
|
3253
|
-
outro(
|
|
3331
|
+
outro(pc9.dim('Setup skipped. Run "npx rrce-workflow mcp" later to restart.'));
|
|
3254
3332
|
}
|
|
3255
3333
|
return;
|
|
3256
3334
|
}
|
|
@@ -3258,18 +3336,18 @@ Allow AI assistants to access your project context.`,
|
|
|
3258
3336
|
await handleStartServer();
|
|
3259
3337
|
} catch (err) {
|
|
3260
3338
|
console.error(err);
|
|
3261
|
-
outro(
|
|
3339
|
+
outro(pc9.red("Failed to launch MCP Dashboard"));
|
|
3262
3340
|
}
|
|
3263
3341
|
}
|
|
3264
3342
|
async function handleStopServer() {
|
|
3265
3343
|
const { stopMCPServer: stopMCPServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
3266
3344
|
const status = getMCPServerStatus();
|
|
3267
3345
|
if (!status.running) {
|
|
3268
|
-
console.log(
|
|
3346
|
+
console.log(pc9.dim("MCP server is already stopped."));
|
|
3269
3347
|
return;
|
|
3270
3348
|
}
|
|
3271
3349
|
stopMCPServer2();
|
|
3272
|
-
console.log(
|
|
3350
|
+
console.log(pc9.green("MCP server stopped."));
|
|
3273
3351
|
}
|
|
3274
3352
|
var init_mcp = __esm({
|
|
3275
3353
|
"src/mcp/index.ts"() {
|
|
@@ -3287,364 +3365,201 @@ var init_mcp = __esm({
|
|
|
3287
3365
|
});
|
|
3288
3366
|
|
|
3289
3367
|
// src/commands/wizard/setup-flow.ts
|
|
3290
|
-
import {
|
|
3291
|
-
import
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
required: false
|
|
3313
|
-
}),
|
|
3314
|
-
exposeToMCP: () => confirm4({
|
|
3315
|
-
message: "Expose this project to MCP (AI Agent) server?",
|
|
3316
|
-
initialValue: true
|
|
3317
|
-
}),
|
|
3318
|
-
linkedProjects: () => {
|
|
3319
|
-
if (existingProjects.length === 0) {
|
|
3320
|
-
return Promise.resolve([]);
|
|
3321
|
-
}
|
|
3322
|
-
return multiselect3({
|
|
3323
|
-
message: "Link knowledge from other projects?",
|
|
3324
|
-
options: existingProjects.map((project) => ({
|
|
3325
|
-
value: `${project.name}:${project.source}`,
|
|
3326
|
-
// Unique key
|
|
3327
|
-
label: `${project.name} ${pc8.dim(`(${project.source})`)}`,
|
|
3328
|
-
hint: pc8.dim(
|
|
3329
|
-
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
3330
|
-
)
|
|
3331
|
-
})),
|
|
3332
|
-
required: false
|
|
3333
|
-
});
|
|
3334
|
-
},
|
|
3335
|
-
addToGitignore: () => confirm4({
|
|
3336
|
-
message: "Add generated folders to .gitignore? (as comments - uncomment if needed)",
|
|
3337
|
-
initialValue: true
|
|
3338
|
-
}),
|
|
3339
|
-
confirm: () => confirm4({
|
|
3340
|
-
message: "Create configuration?",
|
|
3341
|
-
initialValue: true
|
|
3342
|
-
}),
|
|
3343
|
-
enableRAG: () => confirm4({
|
|
3344
|
-
message: "Enable Semantic Search (Local Mini RAG)?",
|
|
3345
|
-
initialValue: true
|
|
3346
|
-
}),
|
|
3347
|
-
enableRAGConfirm: ({ results }) => {
|
|
3348
|
-
if (results.enableRAG) {
|
|
3349
|
-
return confirm4({
|
|
3350
|
-
message: `${pc8.yellow("Warning:")} This will download a ~100MB model (Xenova/all-MiniLM-L6-v2) on first use. Proceed?`,
|
|
3351
|
-
initialValue: true
|
|
3352
|
-
});
|
|
3353
|
-
}
|
|
3354
|
-
return Promise.resolve(true);
|
|
3355
|
-
}
|
|
3356
|
-
},
|
|
3357
|
-
{
|
|
3358
|
-
onCancel: () => {
|
|
3359
|
-
cancel2("Setup process cancelled.");
|
|
3360
|
-
process.exit(0);
|
|
3361
|
-
}
|
|
3368
|
+
import { spinner as spinner3, note as note8, outro as outro2, cancel as cancel3, isCancel as isCancel7, confirm as confirm5, select as select3 } from "@clack/prompts";
|
|
3369
|
+
import pc10 from "picocolors";
|
|
3370
|
+
async function runExpressSetup(workspacePath, workspaceName, existingProjects, s) {
|
|
3371
|
+
const storageModeResult = await select3({
|
|
3372
|
+
message: "Where should workflow data be stored?",
|
|
3373
|
+
options: [
|
|
3374
|
+
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Recommended - cross-project access" },
|
|
3375
|
+
{ value: "workspace", label: "Workspace (.rrce-workflow/)", hint: "Self-contained" }
|
|
3376
|
+
],
|
|
3377
|
+
initialValue: "global"
|
|
3378
|
+
});
|
|
3379
|
+
if (isCancel7(storageModeResult)) {
|
|
3380
|
+
cancel3("Setup cancelled.");
|
|
3381
|
+
process.exit(0);
|
|
3382
|
+
}
|
|
3383
|
+
const storageMode = storageModeResult;
|
|
3384
|
+
let customGlobalPath;
|
|
3385
|
+
if (storageMode === "global") {
|
|
3386
|
+
customGlobalPath = await resolveGlobalPath();
|
|
3387
|
+
if (!customGlobalPath) {
|
|
3388
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
3389
|
+
process.exit(0);
|
|
3362
3390
|
}
|
|
3391
|
+
}
|
|
3392
|
+
note8(
|
|
3393
|
+
`${pc10.bold("Express Setup will configure:")}
|
|
3394
|
+
\u2022 Storage: ${storageMode === "global" ? "Global" : "Workspace"}
|
|
3395
|
+
\u2022 MCP Server: Enabled
|
|
3396
|
+
\u2022 Semantic Search (RAG): Enabled
|
|
3397
|
+
\u2022 Git ignore entries: Added (as comments)
|
|
3398
|
+
\u2022 AI Tools: All available`,
|
|
3399
|
+
"Configuration Preview"
|
|
3363
3400
|
);
|
|
3364
|
-
|
|
3365
|
-
|
|
3401
|
+
const confirmed = await confirm5({
|
|
3402
|
+
message: "Proceed with express setup?",
|
|
3403
|
+
initialValue: true
|
|
3404
|
+
});
|
|
3405
|
+
if (isCancel7(confirmed) || !confirmed) {
|
|
3406
|
+
cancel3("Setup cancelled.");
|
|
3407
|
+
process.exit(0);
|
|
3408
|
+
}
|
|
3409
|
+
const config = {
|
|
3410
|
+
storageMode,
|
|
3411
|
+
globalPath: customGlobalPath,
|
|
3412
|
+
tools: ["copilot", "antigravity"],
|
|
3413
|
+
linkedProjects: [],
|
|
3414
|
+
addToGitignore: true,
|
|
3415
|
+
exposeToMCP: true,
|
|
3416
|
+
enableRAG: true
|
|
3417
|
+
};
|
|
3418
|
+
await executeSetup(config, workspacePath, workspaceName, existingProjects, s);
|
|
3419
|
+
const startMCP = await confirm5({
|
|
3420
|
+
message: "Start MCP server now?",
|
|
3421
|
+
initialValue: true
|
|
3422
|
+
});
|
|
3423
|
+
if (startMCP && !isCancel7(startMCP)) {
|
|
3424
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
3425
|
+
await runMCP2();
|
|
3426
|
+
} else {
|
|
3427
|
+
outro2(pc10.green(`\u2713 Express setup complete! Run ${pc10.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
3431
|
+
const s = spinner3();
|
|
3432
|
+
const setupModeResult = await select3({
|
|
3433
|
+
message: "Setup mode:",
|
|
3434
|
+
options: [
|
|
3435
|
+
{ value: "express", label: "Express Setup", hint: "Quick start with recommended defaults (3 steps)" },
|
|
3436
|
+
{ value: "custom", label: "Custom Setup", hint: "Full configuration options" }
|
|
3437
|
+
],
|
|
3438
|
+
initialValue: "express"
|
|
3439
|
+
});
|
|
3440
|
+
if (isCancel7(setupModeResult)) {
|
|
3441
|
+
cancel3("Setup cancelled.");
|
|
3366
3442
|
process.exit(0);
|
|
3367
3443
|
}
|
|
3444
|
+
if (setupModeResult === "express") {
|
|
3445
|
+
return runExpressSetup(workspacePath, workspaceName, existingProjects, s);
|
|
3446
|
+
}
|
|
3447
|
+
const storageMode = await promptStorageMode();
|
|
3368
3448
|
let customGlobalPath;
|
|
3369
|
-
if (
|
|
3449
|
+
if (storageMode === "global") {
|
|
3370
3450
|
customGlobalPath = await resolveGlobalPath();
|
|
3371
3451
|
if (!customGlobalPath) {
|
|
3372
|
-
|
|
3373
|
-
process.exit(
|
|
3452
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
3453
|
+
process.exit(0);
|
|
3374
3454
|
}
|
|
3375
3455
|
}
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
});
|
|
3386
|
-
if (isCancel6(overwriteAction) || overwriteAction === "cancel") {
|
|
3387
|
-
cancel2("Setup cancelled.");
|
|
3388
|
-
process.exit(0);
|
|
3389
|
-
}
|
|
3390
|
-
}
|
|
3456
|
+
const tools = await promptTools();
|
|
3457
|
+
const exposeToMCP = await promptMCPExposure();
|
|
3458
|
+
const linkedProjects = await promptLinkedProjects(existingProjects);
|
|
3459
|
+
const addToGitignore = await promptGitignore();
|
|
3460
|
+
const enableRAG = await promptRAG();
|
|
3461
|
+
const confirmed = await promptConfirmation();
|
|
3462
|
+
if (!confirmed) {
|
|
3463
|
+
outro2("Setup cancelled by user.");
|
|
3464
|
+
process.exit(0);
|
|
3391
3465
|
}
|
|
3466
|
+
const config = {
|
|
3467
|
+
storageMode,
|
|
3468
|
+
globalPath: customGlobalPath,
|
|
3469
|
+
tools,
|
|
3470
|
+
linkedProjects,
|
|
3471
|
+
addToGitignore,
|
|
3472
|
+
exposeToMCP,
|
|
3473
|
+
enableRAG
|
|
3474
|
+
};
|
|
3475
|
+
await executeSetup(config, workspacePath, workspaceName, existingProjects, s);
|
|
3476
|
+
await handlePostSetup(config, workspacePath, workspaceName, linkedProjects);
|
|
3477
|
+
}
|
|
3478
|
+
async function executeSetup(config, workspacePath, workspaceName, allProjects, s) {
|
|
3392
3479
|
s.start("Generating configuration");
|
|
3393
3480
|
try {
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3481
|
+
const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
3482
|
+
createDirectoryStructure(dataPaths);
|
|
3483
|
+
installAgentPrompts(config, workspacePath, dataPaths);
|
|
3484
|
+
createWorkspaceConfig(config, workspacePath, workspaceName);
|
|
3485
|
+
if (config.addToGitignore) {
|
|
3486
|
+
const { updateGitignore: updateGitignore2 } = await Promise.resolve().then(() => (init_gitignore(), gitignore_exports));
|
|
3487
|
+
updateGitignore2(workspacePath, config.storageMode, config.tools);
|
|
3488
|
+
}
|
|
3489
|
+
if (config.tools.includes("copilot") || config.linkedProjects.length > 0) {
|
|
3490
|
+
const selectedProjects = allProjects.filter(
|
|
3491
|
+
(p) => config.linkedProjects.includes(`${p.name}:${p.source}`)
|
|
3492
|
+
);
|
|
3493
|
+
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, config.globalPath);
|
|
3494
|
+
}
|
|
3495
|
+
await registerWithMCP(config, workspacePath, workspaceName);
|
|
3403
3496
|
s.stop("Configuration generated");
|
|
3404
|
-
const
|
|
3405
|
-
config.storageMode,
|
|
3406
|
-
workspaceName,
|
|
3407
|
-
workspacePath,
|
|
3408
|
-
customGlobalPath
|
|
3409
|
-
);
|
|
3497
|
+
const dataSummary = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
3410
3498
|
const summary = [
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
dataPaths.forEach((p) => summary.push(` - ${p}`));
|
|
3419
|
-
}
|
|
3420
|
-
const selectedTools = config.tools;
|
|
3421
|
-
if (selectedTools.length > 0) {
|
|
3422
|
-
summary.push(`Tools: ${selectedTools.join(", ")}`);
|
|
3423
|
-
}
|
|
3424
|
-
const linkedProjects = config.linkedProjects;
|
|
3425
|
-
if (linkedProjects.length > 0) {
|
|
3426
|
-
summary.push(`Linked projects: ${linkedProjects.join(", ")}`);
|
|
3427
|
-
summary.push(`Workspace file: ${pc8.cyan(`${workspaceName}.code-workspace`)}`);
|
|
3428
|
-
}
|
|
3429
|
-
note7(summary.join("\n"), "Setup Summary");
|
|
3430
|
-
if (config.exposeToMCP) {
|
|
3431
|
-
note7(`${pc8.green("\u2713")} Project exposed to MCP Hub`, "MCP Configuration");
|
|
3432
|
-
if (linkedProjects.length > 0) {
|
|
3433
|
-
outro2(pc8.green(`\u2713 Setup complete! Open ${pc8.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
3434
|
-
} else {
|
|
3435
|
-
outro2(pc8.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
3436
|
-
}
|
|
3437
|
-
} else {
|
|
3438
|
-
const shouldConfigureMCP = await confirm4({
|
|
3439
|
-
message: "Would you like to configure the MCP server now?",
|
|
3440
|
-
initialValue: true
|
|
3441
|
-
});
|
|
3442
|
-
if (shouldConfigureMCP && !isCancel6(shouldConfigureMCP)) {
|
|
3443
|
-
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
3444
|
-
await runMCP2();
|
|
3445
|
-
} else {
|
|
3446
|
-
if (linkedProjects.length > 0) {
|
|
3447
|
-
outro2(pc8.green(`\u2713 Setup complete! Open ${pc8.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
|
|
3448
|
-
} else {
|
|
3449
|
-
outro2(pc8.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
3450
|
-
}
|
|
3451
|
-
}
|
|
3452
|
-
}
|
|
3499
|
+
`${pc10.green("\u2713")} Data stored at: ${pc10.dim(dataSummary[0])}`,
|
|
3500
|
+
config.tools.length > 0 ? `${pc10.green("\u2713")} Tools: ${config.tools.join(", ")}` : null,
|
|
3501
|
+
config.exposeToMCP ? `${pc10.green("\u2713")} MCP server configured` : null,
|
|
3502
|
+
config.enableRAG ? `${pc10.green("\u2713")} Semantic Search enabled` : null,
|
|
3503
|
+
config.linkedProjects.length > 0 ? `${pc10.green("\u2713")} Linked ${config.linkedProjects.length} project(s)` : null
|
|
3504
|
+
].filter(Boolean);
|
|
3505
|
+
note8(summary.join("\n"), "Setup Complete");
|
|
3453
3506
|
} catch (error) {
|
|
3454
3507
|
s.stop("Error occurred");
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
}
|
|
3458
|
-
}
|
|
3459
|
-
async function generateConfiguration(config, workspacePath, workspaceName, allProjects = []) {
|
|
3460
|
-
const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
3461
|
-
for (const dataPath of dataPaths) {
|
|
3462
|
-
ensureDir(dataPath);
|
|
3463
|
-
ensureDir(path14.join(dataPath, "knowledge"));
|
|
3464
|
-
ensureDir(path14.join(dataPath, "refs"));
|
|
3465
|
-
ensureDir(path14.join(dataPath, "tasks"));
|
|
3466
|
-
ensureDir(path14.join(dataPath, "templates"));
|
|
3467
|
-
}
|
|
3468
|
-
const agentCoreDir = getAgentCoreDir();
|
|
3469
|
-
syncMetadataToAll(agentCoreDir, dataPaths);
|
|
3470
|
-
copyDirToAllStoragePaths(path14.join(agentCoreDir, "templates"), "templates", dataPaths);
|
|
3471
|
-
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
3472
|
-
if (config.storageMode === "workspace") {
|
|
3473
|
-
if (config.tools.includes("copilot")) {
|
|
3474
|
-
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
3475
|
-
ensureDir(copilotPath);
|
|
3476
|
-
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
3477
|
-
}
|
|
3478
|
-
if (config.tools.includes("antigravity")) {
|
|
3479
|
-
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
3480
|
-
ensureDir(antigravityPath);
|
|
3481
|
-
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
3482
|
-
}
|
|
3483
|
-
}
|
|
3484
|
-
if (config.storageMode === "workspace") {
|
|
3485
|
-
const workspaceConfigPath = path14.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
3486
|
-
ensureDir(path14.dirname(workspaceConfigPath));
|
|
3487
|
-
let configContent = `# RRCE-Workflow Configuration
|
|
3488
|
-
version: 1
|
|
3489
|
-
|
|
3490
|
-
storage:
|
|
3491
|
-
mode: ${config.storageMode}`;
|
|
3492
|
-
if (config.globalPath && config.globalPath !== getDefaultRRCEHome()) {
|
|
3493
|
-
configContent += `
|
|
3494
|
-
globalPath: "${config.globalPath}"`;
|
|
3495
|
-
}
|
|
3496
|
-
configContent += `
|
|
3497
|
-
|
|
3498
|
-
project:
|
|
3499
|
-
name: "${workspaceName}"
|
|
3508
|
+
cancel3(
|
|
3509
|
+
`Setup failed: ${error instanceof Error ? error.message : String(error)}
|
|
3500
3510
|
|
|
3501
|
-
|
|
3502
|
-
copilot: ${config.tools.includes("copilot")}
|
|
3503
|
-
antigravity: ${config.tools.includes("antigravity")}
|
|
3504
|
-
`;
|
|
3505
|
-
if (config.linkedProjects.length > 0) {
|
|
3506
|
-
configContent += `
|
|
3507
|
-
linked_projects:
|
|
3508
|
-
`;
|
|
3509
|
-
config.linkedProjects.forEach((name) => {
|
|
3510
|
-
configContent += ` - ${name}
|
|
3511
|
-
`;
|
|
3512
|
-
});
|
|
3513
|
-
}
|
|
3514
|
-
fs14.writeFileSync(workspaceConfigPath, configContent);
|
|
3515
|
-
}
|
|
3516
|
-
if (config.addToGitignore) {
|
|
3517
|
-
updateGitignore(workspacePath, config.storageMode, config.tools);
|
|
3518
|
-
}
|
|
3519
|
-
if (config.tools.includes("copilot") || config.linkedProjects.length > 0) {
|
|
3520
|
-
const selectedProjects = allProjects.filter(
|
|
3521
|
-
(p) => config.linkedProjects.includes(`${p.name}:${p.source}`)
|
|
3511
|
+
${pc10.dim("Tip: You can re-run the wizard to try again.")}`
|
|
3522
3512
|
);
|
|
3523
|
-
|
|
3513
|
+
process.exit(1);
|
|
3524
3514
|
}
|
|
3515
|
+
}
|
|
3516
|
+
async function handlePostSetup(config, workspacePath, workspaceName, linkedProjects) {
|
|
3525
3517
|
if (config.exposeToMCP) {
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
void 0,
|
|
3537
|
-
// permissions
|
|
3538
|
-
void 0,
|
|
3539
|
-
// path
|
|
3540
|
-
config.enableRAG ? { enabled: true } : void 0
|
|
3541
|
-
// semanticSearch
|
|
3542
|
-
);
|
|
3543
|
-
saveMCPConfig2(mcpConfig);
|
|
3544
|
-
saveMCPConfig2(mcpConfig);
|
|
3518
|
+
const shouldConfigureMCP = await confirm5({
|
|
3519
|
+
message: "Would you like to start the MCP server now?",
|
|
3520
|
+
initialValue: true
|
|
3521
|
+
});
|
|
3522
|
+
if (shouldConfigureMCP && !isCancel7(shouldConfigureMCP)) {
|
|
3523
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
3524
|
+
await runMCP2();
|
|
3525
|
+
} else {
|
|
3526
|
+
if (linkedProjects.length > 0) {
|
|
3527
|
+
outro2(pc10.green(`\u2713 Setup complete! Open ${pc10.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
3545
3528
|
} else {
|
|
3546
|
-
|
|
3547
|
-
mcpConfig,
|
|
3548
|
-
currentProjectName,
|
|
3549
|
-
true,
|
|
3550
|
-
void 0,
|
|
3551
|
-
// permissions
|
|
3552
|
-
workspacePath,
|
|
3553
|
-
// <--- IMPORTANT: Register absolute path so config scanner finds it
|
|
3554
|
-
config.enableRAG ? { enabled: true } : void 0
|
|
3555
|
-
// semanticSearch
|
|
3556
|
-
);
|
|
3557
|
-
saveMCPConfig2(mcpConfig);
|
|
3558
|
-
}
|
|
3559
|
-
} catch (e) {
|
|
3560
|
-
console.error("Failed to update MCP config:", e);
|
|
3561
|
-
}
|
|
3562
|
-
}
|
|
3563
|
-
}
|
|
3564
|
-
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
3565
|
-
const globalPath = path14.join(customGlobalPath || getDefaultRRCEHome(), "workspaces", workspaceName);
|
|
3566
|
-
const workspacePath = path14.join(workspaceRoot, ".rrce-workflow");
|
|
3567
|
-
switch (mode) {
|
|
3568
|
-
case "global":
|
|
3569
|
-
return [globalPath];
|
|
3570
|
-
case "workspace":
|
|
3571
|
-
return [workspacePath];
|
|
3572
|
-
default:
|
|
3573
|
-
return [globalPath];
|
|
3574
|
-
}
|
|
3575
|
-
}
|
|
3576
|
-
function updateGitignore(workspacePath, storageMode, tools) {
|
|
3577
|
-
const gitignorePath = path14.join(workspacePath, ".gitignore");
|
|
3578
|
-
const entries = [];
|
|
3579
|
-
if (storageMode === "workspace") {
|
|
3580
|
-
entries.push(".rrce-workflow/");
|
|
3581
|
-
}
|
|
3582
|
-
if (tools.includes("copilot")) {
|
|
3583
|
-
entries.push(".github/agents/");
|
|
3584
|
-
}
|
|
3585
|
-
if (tools.includes("antigravity")) {
|
|
3586
|
-
entries.push(".agent/");
|
|
3587
|
-
}
|
|
3588
|
-
if (entries.length === 0) {
|
|
3589
|
-
return false;
|
|
3590
|
-
}
|
|
3591
|
-
try {
|
|
3592
|
-
let content = "";
|
|
3593
|
-
if (fs14.existsSync(gitignorePath)) {
|
|
3594
|
-
content = fs14.readFileSync(gitignorePath, "utf-8");
|
|
3595
|
-
}
|
|
3596
|
-
const lines = content.split("\n").map((line) => line.trim());
|
|
3597
|
-
const newEntries = [];
|
|
3598
|
-
for (const entry of entries) {
|
|
3599
|
-
const entryWithoutSlash = entry.replace(/\/$/, "");
|
|
3600
|
-
const commentedEntry = `# ${entry}`;
|
|
3601
|
-
const commentedEntryNoSlash = `# ${entryWithoutSlash}`;
|
|
3602
|
-
if (!lines.some(
|
|
3603
|
-
(line) => line === entry || line === entryWithoutSlash || line === commentedEntry || line === commentedEntryNoSlash
|
|
3604
|
-
)) {
|
|
3605
|
-
newEntries.push(entry);
|
|
3529
|
+
outro2(pc10.green(`\u2713 Setup complete! Run ${pc10.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
3606
3530
|
}
|
|
3607
3531
|
}
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
newContent += "\n";
|
|
3614
|
-
}
|
|
3615
|
-
if (newContent === "" || !content.includes("# rrce-workflow")) {
|
|
3616
|
-
newContent += "\n# rrce-workflow generated folders (uncomment to ignore)\n";
|
|
3532
|
+
} else {
|
|
3533
|
+
if (linkedProjects.length > 0) {
|
|
3534
|
+
outro2(pc10.green(`\u2713 Setup complete! Open ${pc10.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
3535
|
+
} else {
|
|
3536
|
+
outro2(pc10.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
3617
3537
|
}
|
|
3618
|
-
newContent += newEntries.map((e) => `# ${e}`).join("\n") + "\n";
|
|
3619
|
-
fs14.writeFileSync(gitignorePath, newContent);
|
|
3620
|
-
return true;
|
|
3621
|
-
} catch {
|
|
3622
|
-
return false;
|
|
3623
3538
|
}
|
|
3624
3539
|
}
|
|
3625
3540
|
var init_setup_flow = __esm({
|
|
3626
3541
|
"src/commands/wizard/setup-flow.ts"() {
|
|
3627
3542
|
"use strict";
|
|
3628
|
-
init_paths();
|
|
3629
|
-
init_prompts();
|
|
3630
|
-
init_utils();
|
|
3631
|
-
init_vscode();
|
|
3632
3543
|
init_detection();
|
|
3633
3544
|
init_tui_utils();
|
|
3545
|
+
init_setup_prompts();
|
|
3546
|
+
init_setup_actions();
|
|
3547
|
+
init_gitignore();
|
|
3548
|
+
init_vscode();
|
|
3634
3549
|
}
|
|
3635
3550
|
});
|
|
3636
3551
|
|
|
3637
3552
|
// src/commands/wizard/link-flow.ts
|
|
3638
|
-
import { multiselect as multiselect4, spinner as spinner4, note as
|
|
3639
|
-
import
|
|
3640
|
-
import * as
|
|
3553
|
+
import { multiselect as multiselect4, spinner as spinner4, note as note9, outro as outro3, cancel as cancel4, isCancel as isCancel8, confirm as confirm6 } from "@clack/prompts";
|
|
3554
|
+
import pc11 from "picocolors";
|
|
3555
|
+
import * as fs16 from "fs";
|
|
3641
3556
|
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
3642
3557
|
const projects = scanForProjects({
|
|
3643
3558
|
excludeWorkspace: workspaceName,
|
|
3644
3559
|
workspacePath
|
|
3645
3560
|
});
|
|
3646
3561
|
if (projects.length === 0) {
|
|
3647
|
-
outro3(
|
|
3562
|
+
outro3(pc11.yellow("No other projects found. Try setting up another project first."));
|
|
3648
3563
|
return;
|
|
3649
3564
|
}
|
|
3650
3565
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
@@ -3653,15 +3568,15 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
3653
3568
|
options: projects.map((project) => ({
|
|
3654
3569
|
value: `${project.name}:${project.source}`,
|
|
3655
3570
|
// Unique key
|
|
3656
|
-
label: `${project.name} ${
|
|
3657
|
-
hint:
|
|
3571
|
+
label: `${project.name} ${pc11.dim(`(${project.source})`)}`,
|
|
3572
|
+
hint: pc11.dim(
|
|
3658
3573
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
3659
3574
|
)
|
|
3660
3575
|
})),
|
|
3661
3576
|
required: true
|
|
3662
3577
|
});
|
|
3663
|
-
if (
|
|
3664
|
-
|
|
3578
|
+
if (isCancel8(linkedProjects)) {
|
|
3579
|
+
cancel4("Cancelled.");
|
|
3665
3580
|
process.exit(0);
|
|
3666
3581
|
}
|
|
3667
3582
|
const selectedKeys = linkedProjects;
|
|
@@ -3675,7 +3590,7 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
3675
3590
|
const s = spinner4();
|
|
3676
3591
|
s.start("Linking projects");
|
|
3677
3592
|
const configFilePath = getConfigPath(workspacePath);
|
|
3678
|
-
let configContent =
|
|
3593
|
+
let configContent = fs16.readFileSync(configFilePath, "utf-8");
|
|
3679
3594
|
if (configContent.includes("linked_projects:")) {
|
|
3680
3595
|
const lines = configContent.split("\n");
|
|
3681
3596
|
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
@@ -3702,23 +3617,23 @@ linked_projects:
|
|
|
3702
3617
|
`;
|
|
3703
3618
|
});
|
|
3704
3619
|
}
|
|
3705
|
-
|
|
3620
|
+
fs16.writeFileSync(configFilePath, configContent);
|
|
3706
3621
|
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
3707
3622
|
s.stop("Projects linked");
|
|
3708
3623
|
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
3709
3624
|
const summary = [
|
|
3710
3625
|
`Linked projects:`,
|
|
3711
|
-
...selectedProjects.map((p) => ` \u2713 ${p.name} ${
|
|
3626
|
+
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc11.dim(`(${p.source})`)}`),
|
|
3712
3627
|
``,
|
|
3713
|
-
`Workspace file: ${
|
|
3628
|
+
`Workspace file: ${pc11.cyan(workspaceFile)}`
|
|
3714
3629
|
];
|
|
3715
|
-
|
|
3716
|
-
outro3(
|
|
3717
|
-
const shouldExpose = await
|
|
3630
|
+
note9(summary.join("\n"), "Link Summary");
|
|
3631
|
+
outro3(pc11.green(`\u2713 Projects linked! Open ${pc11.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
3632
|
+
const shouldExpose = await confirm6({
|
|
3718
3633
|
message: "Also expose these linked projects to the MCP server (for Agent access)?",
|
|
3719
3634
|
initialValue: true
|
|
3720
3635
|
});
|
|
3721
|
-
if (shouldExpose && !
|
|
3636
|
+
if (shouldExpose && !isCancel8(shouldExpose)) {
|
|
3722
3637
|
try {
|
|
3723
3638
|
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3724
3639
|
const mcpConfig = loadMCPConfig3();
|
|
@@ -3726,9 +3641,9 @@ linked_projects:
|
|
|
3726
3641
|
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
3727
3642
|
}
|
|
3728
3643
|
saveMCPConfig2(mcpConfig);
|
|
3729
|
-
|
|
3644
|
+
note9("Projects have been added to the global MCP configuration.", "MCP Updated");
|
|
3730
3645
|
} catch (err) {
|
|
3731
|
-
|
|
3646
|
+
note9(`Failed to update MCP config: ${err}`, "MCP Update Failed");
|
|
3732
3647
|
}
|
|
3733
3648
|
}
|
|
3734
3649
|
}
|
|
@@ -3742,34 +3657,34 @@ var init_link_flow = __esm({
|
|
|
3742
3657
|
});
|
|
3743
3658
|
|
|
3744
3659
|
// src/commands/wizard/sync-flow.ts
|
|
3745
|
-
import { confirm as
|
|
3746
|
-
import
|
|
3747
|
-
import * as
|
|
3748
|
-
import * as
|
|
3660
|
+
import { confirm as confirm7, spinner as spinner5, note as note10, outro as outro4, cancel as cancel5, isCancel as isCancel9 } from "@clack/prompts";
|
|
3661
|
+
import pc12 from "picocolors";
|
|
3662
|
+
import * as fs17 from "fs";
|
|
3663
|
+
import * as path16 from "path";
|
|
3749
3664
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
3750
3665
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
3751
3666
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
3752
|
-
const globalPath =
|
|
3667
|
+
const globalPath = path16.join(customGlobalPath, "workspaces", workspaceName);
|
|
3753
3668
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
3754
3669
|
const existingDirs = subdirs.filter(
|
|
3755
|
-
(dir) =>
|
|
3670
|
+
(dir) => fs17.existsSync(path16.join(localPath, dir))
|
|
3756
3671
|
);
|
|
3757
3672
|
if (existingDirs.length === 0) {
|
|
3758
|
-
outro4(
|
|
3673
|
+
outro4(pc12.yellow("No data found in workspace storage to sync."));
|
|
3759
3674
|
return;
|
|
3760
3675
|
}
|
|
3761
|
-
|
|
3676
|
+
note10(
|
|
3762
3677
|
`The following will be copied to global storage:
|
|
3763
3678
|
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
3764
3679
|
|
|
3765
|
-
Destination: ${
|
|
3680
|
+
Destination: ${pc12.cyan(globalPath)}`,
|
|
3766
3681
|
"Sync Preview"
|
|
3767
3682
|
);
|
|
3768
|
-
const shouldSync = await
|
|
3683
|
+
const shouldSync = await confirm7({
|
|
3769
3684
|
message: "Proceed with sync to global storage?",
|
|
3770
3685
|
initialValue: true
|
|
3771
3686
|
});
|
|
3772
|
-
if (
|
|
3687
|
+
if (isCancel9(shouldSync) || !shouldSync) {
|
|
3773
3688
|
outro4("Sync cancelled.");
|
|
3774
3689
|
return;
|
|
3775
3690
|
}
|
|
@@ -3778,8 +3693,8 @@ Destination: ${pc10.cyan(globalPath)}`,
|
|
|
3778
3693
|
try {
|
|
3779
3694
|
ensureDir(globalPath);
|
|
3780
3695
|
for (const dir of existingDirs) {
|
|
3781
|
-
const srcDir =
|
|
3782
|
-
const destDir =
|
|
3696
|
+
const srcDir = path16.join(localPath, dir);
|
|
3697
|
+
const destDir = path16.join(globalPath, dir);
|
|
3783
3698
|
ensureDir(destDir);
|
|
3784
3699
|
copyDirRecursive(srcDir, destDir);
|
|
3785
3700
|
}
|
|
@@ -3788,15 +3703,15 @@ Destination: ${pc10.cyan(globalPath)}`,
|
|
|
3788
3703
|
`Synced directories:`,
|
|
3789
3704
|
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
3790
3705
|
``,
|
|
3791
|
-
`Global path: ${
|
|
3706
|
+
`Global path: ${pc12.cyan(globalPath)}`,
|
|
3792
3707
|
``,
|
|
3793
3708
|
`Other projects can now link this knowledge!`
|
|
3794
3709
|
];
|
|
3795
|
-
|
|
3796
|
-
outro4(
|
|
3710
|
+
note10(summary.join("\n"), "Sync Summary");
|
|
3711
|
+
outro4(pc12.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
3797
3712
|
} catch (error) {
|
|
3798
3713
|
s.stop("Error occurred");
|
|
3799
|
-
|
|
3714
|
+
cancel5(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
3800
3715
|
process.exit(1);
|
|
3801
3716
|
}
|
|
3802
3717
|
}
|
|
@@ -3809,10 +3724,10 @@ var init_sync_flow = __esm({
|
|
|
3809
3724
|
});
|
|
3810
3725
|
|
|
3811
3726
|
// src/commands/wizard/update-flow.ts
|
|
3812
|
-
import { confirm as
|
|
3813
|
-
import
|
|
3814
|
-
import * as
|
|
3815
|
-
import * as
|
|
3727
|
+
import { confirm as confirm8, spinner as spinner6, note as note11, outro as outro5, cancel as cancel6, isCancel as isCancel10 } from "@clack/prompts";
|
|
3728
|
+
import pc13 from "picocolors";
|
|
3729
|
+
import * as fs18 from "fs";
|
|
3730
|
+
import * as path17 from "path";
|
|
3816
3731
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
3817
3732
|
const s = spinner6();
|
|
3818
3733
|
s.start("Checking for updates");
|
|
@@ -3823,7 +3738,7 @@ async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
|
3823
3738
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
3824
3739
|
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
3825
3740
|
s.stop("Updates found");
|
|
3826
|
-
|
|
3741
|
+
note11(
|
|
3827
3742
|
`The following will be updated from the package:
|
|
3828
3743
|
\u2022 prompts/ (${prompts.length} agent prompts)
|
|
3829
3744
|
\u2022 templates/ (output templates)
|
|
@@ -3832,20 +3747,20 @@ Target locations:
|
|
|
3832
3747
|
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
3833
3748
|
"Update Preview"
|
|
3834
3749
|
);
|
|
3835
|
-
const shouldUpdate = await
|
|
3750
|
+
const shouldUpdate = await confirm8({
|
|
3836
3751
|
message: "Proceed with update?",
|
|
3837
3752
|
initialValue: true
|
|
3838
3753
|
});
|
|
3839
|
-
if (
|
|
3754
|
+
if (isCancel10(shouldUpdate) || !shouldUpdate) {
|
|
3840
3755
|
outro5("Update cancelled.");
|
|
3841
3756
|
return;
|
|
3842
3757
|
}
|
|
3843
3758
|
s.start("Updating from package");
|
|
3844
3759
|
for (const dataPath of dataPaths) {
|
|
3845
|
-
copyDirToAllStoragePaths(
|
|
3760
|
+
copyDirToAllStoragePaths(path17.join(agentCoreDir, "templates"), "templates", [dataPath]);
|
|
3846
3761
|
}
|
|
3847
3762
|
const configFilePath = getConfigPath(workspacePath);
|
|
3848
|
-
const configContent =
|
|
3763
|
+
const configContent = fs18.readFileSync(configFilePath, "utf-8");
|
|
3849
3764
|
if (configContent.includes("copilot: true")) {
|
|
3850
3765
|
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
3851
3766
|
ensureDir(copilotPath);
|
|
@@ -3864,17 +3779,17 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
3864
3779
|
``,
|
|
3865
3780
|
`Your configuration and knowledge files were preserved.`
|
|
3866
3781
|
];
|
|
3867
|
-
|
|
3868
|
-
outro5(
|
|
3782
|
+
note11(summary.join("\n"), "Update Summary");
|
|
3783
|
+
outro5(pc13.green("\u2713 Successfully updated from package!"));
|
|
3869
3784
|
} catch (error) {
|
|
3870
3785
|
s.stop("Error occurred");
|
|
3871
|
-
|
|
3786
|
+
cancel6(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
3872
3787
|
process.exit(1);
|
|
3873
3788
|
}
|
|
3874
3789
|
}
|
|
3875
3790
|
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
3876
|
-
const globalPath =
|
|
3877
|
-
const workspacePath =
|
|
3791
|
+
const globalPath = path17.join(customGlobalPath, "workspaces", workspaceName);
|
|
3792
|
+
const workspacePath = path17.join(workspaceRoot, ".rrce-workflow");
|
|
3878
3793
|
switch (mode) {
|
|
3879
3794
|
case "global":
|
|
3880
3795
|
return [globalPath];
|
|
@@ -3894,13 +3809,13 @@ var init_update_flow = __esm({
|
|
|
3894
3809
|
});
|
|
3895
3810
|
|
|
3896
3811
|
// src/commands/wizard/delete-flow.ts
|
|
3897
|
-
import { multiselect as multiselect5, confirm as
|
|
3898
|
-
import
|
|
3899
|
-
import * as
|
|
3812
|
+
import { multiselect as multiselect5, confirm as confirm9, spinner as spinner7, note as note12, cancel as cancel7, isCancel as isCancel11 } from "@clack/prompts";
|
|
3813
|
+
import pc14 from "picocolors";
|
|
3814
|
+
import * as fs19 from "fs";
|
|
3900
3815
|
async function runDeleteGlobalProjectFlow(availableProjects) {
|
|
3901
3816
|
const globalProjects = availableProjects.filter((p) => p.source === "global");
|
|
3902
3817
|
if (globalProjects.length === 0) {
|
|
3903
|
-
|
|
3818
|
+
note12("No globally stored projects found to delete.", "Info");
|
|
3904
3819
|
return;
|
|
3905
3820
|
}
|
|
3906
3821
|
const selectedProjects = await multiselect5({
|
|
@@ -3912,22 +3827,22 @@ async function runDeleteGlobalProjectFlow(availableProjects) {
|
|
|
3912
3827
|
})),
|
|
3913
3828
|
required: false
|
|
3914
3829
|
});
|
|
3915
|
-
if (
|
|
3916
|
-
|
|
3830
|
+
if (isCancel11(selectedProjects)) {
|
|
3831
|
+
cancel7("Deletion cancelled.");
|
|
3917
3832
|
return;
|
|
3918
3833
|
}
|
|
3919
3834
|
const projectsToDelete = selectedProjects;
|
|
3920
3835
|
if (projectsToDelete.length === 0) {
|
|
3921
|
-
|
|
3836
|
+
note12("No projects selected.", "Cancelled");
|
|
3922
3837
|
return;
|
|
3923
3838
|
}
|
|
3924
|
-
const confirmed = await
|
|
3925
|
-
message: `${
|
|
3839
|
+
const confirmed = await confirm9({
|
|
3840
|
+
message: `${pc14.red("WARNING:")} This will PERMANENTLY DELETE the knowledge/config for ${projectsToDelete.length} detected global projects.
|
|
3926
3841
|
Are you sure?`,
|
|
3927
3842
|
initialValue: false
|
|
3928
3843
|
});
|
|
3929
|
-
if (!confirmed ||
|
|
3930
|
-
|
|
3844
|
+
if (!confirmed || isCancel11(confirmed)) {
|
|
3845
|
+
cancel7("Deletion cancelled.");
|
|
3931
3846
|
return;
|
|
3932
3847
|
}
|
|
3933
3848
|
const s = spinner7();
|
|
@@ -3938,8 +3853,8 @@ Are you sure?`,
|
|
|
3938
3853
|
for (const projectName of projectsToDelete) {
|
|
3939
3854
|
const project = globalProjects.find((p) => p.name === projectName);
|
|
3940
3855
|
if (!project) continue;
|
|
3941
|
-
if (
|
|
3942
|
-
|
|
3856
|
+
if (fs19.existsSync(project.dataPath)) {
|
|
3857
|
+
fs19.rmSync(project.dataPath, { recursive: true, force: true });
|
|
3943
3858
|
}
|
|
3944
3859
|
const newConfig = removeProjectConfig(mcpConfig, projectName);
|
|
3945
3860
|
configChanged = true;
|
|
@@ -3951,7 +3866,7 @@ Are you sure?`,
|
|
|
3951
3866
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
3952
3867
|
} catch (error) {
|
|
3953
3868
|
s.stop("Error occurred during deletion");
|
|
3954
|
-
|
|
3869
|
+
note12(`Failed to delete some projects: ${error}`, "Error");
|
|
3955
3870
|
}
|
|
3956
3871
|
}
|
|
3957
3872
|
var init_delete_flow = __esm({
|
|
@@ -3967,11 +3882,11 @@ var wizard_exports = {};
|
|
|
3967
3882
|
__export(wizard_exports, {
|
|
3968
3883
|
runWizard: () => runWizard
|
|
3969
3884
|
});
|
|
3970
|
-
import { intro as intro2, select as
|
|
3971
|
-
import
|
|
3972
|
-
import * as
|
|
3885
|
+
import { intro as intro2, select as select5, spinner as spinner8, note as note13, outro as outro7, isCancel as isCancel12 } from "@clack/prompts";
|
|
3886
|
+
import pc15 from "picocolors";
|
|
3887
|
+
import * as fs20 from "fs";
|
|
3973
3888
|
async function runWizard() {
|
|
3974
|
-
intro2(
|
|
3889
|
+
intro2(pc15.cyan(pc15.inverse(" RRCE-Workflow Setup ")));
|
|
3975
3890
|
const s = spinner8();
|
|
3976
3891
|
s.start("Detecting environment");
|
|
3977
3892
|
const workspacePath = detectWorkspaceRoot();
|
|
@@ -3987,9 +3902,9 @@ async function runWizard() {
|
|
|
3987
3902
|
}
|
|
3988
3903
|
await new Promise((r) => setTimeout(r, 800));
|
|
3989
3904
|
s.stop("Environment detected");
|
|
3990
|
-
|
|
3991
|
-
`Git User: ${
|
|
3992
|
-
Workspace: ${
|
|
3905
|
+
note13(
|
|
3906
|
+
`Git User: ${pc15.bold(gitUser || "(not found)")}
|
|
3907
|
+
Workspace: ${pc15.bold(workspaceName)}`,
|
|
3993
3908
|
"Context"
|
|
3994
3909
|
);
|
|
3995
3910
|
const detectedProjects = scanForProjects({
|
|
@@ -3997,11 +3912,11 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
3997
3912
|
workspacePath
|
|
3998
3913
|
});
|
|
3999
3914
|
const configFilePath = getConfigPath(workspacePath);
|
|
4000
|
-
let isAlreadyConfigured =
|
|
3915
|
+
let isAlreadyConfigured = fs20.existsSync(configFilePath);
|
|
4001
3916
|
let currentStorageMode = null;
|
|
4002
3917
|
if (isAlreadyConfigured) {
|
|
4003
3918
|
try {
|
|
4004
|
-
const configContent =
|
|
3919
|
+
const configContent = fs20.readFileSync(configFilePath, "utf-8");
|
|
4005
3920
|
const modeMatch = configContent.match(/mode:\s*(global|workspace)/);
|
|
4006
3921
|
currentStorageMode = modeMatch?.[1] ?? null;
|
|
4007
3922
|
} catch {
|
|
@@ -4018,7 +3933,7 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
4018
3933
|
}
|
|
4019
3934
|
}
|
|
4020
3935
|
const localDataPath = getLocalWorkspacePath(workspacePath);
|
|
4021
|
-
const hasLocalData =
|
|
3936
|
+
const hasLocalData = fs20.existsSync(localDataPath);
|
|
4022
3937
|
if (isAlreadyConfigured) {
|
|
4023
3938
|
const menuOptions = [];
|
|
4024
3939
|
menuOptions.push({
|
|
@@ -4050,11 +3965,11 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
4050
3965
|
menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
|
|
4051
3966
|
menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
|
|
4052
3967
|
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
4053
|
-
const action = await
|
|
3968
|
+
const action = await select5({
|
|
4054
3969
|
message: "This workspace is already configured. What would you like to do?",
|
|
4055
3970
|
options: menuOptions
|
|
4056
3971
|
});
|
|
4057
|
-
if (
|
|
3972
|
+
if (isCancel12(action) || action === "exit") {
|
|
4058
3973
|
outro7("Exited.");
|
|
4059
3974
|
process.exit(0);
|
|
4060
3975
|
}
|
|
@@ -4104,18 +4019,18 @@ init_wizard();
|
|
|
4104
4019
|
|
|
4105
4020
|
// src/commands/selector.ts
|
|
4106
4021
|
init_prompts();
|
|
4107
|
-
import { intro as intro3, select as
|
|
4108
|
-
import
|
|
4109
|
-
import * as
|
|
4022
|
+
import { intro as intro3, select as select6, note as note14, cancel as cancel9, isCancel as isCancel13, outro as outro8 } from "@clack/prompts";
|
|
4023
|
+
import pc16 from "picocolors";
|
|
4024
|
+
import * as path18 from "path";
|
|
4110
4025
|
async function runSelector() {
|
|
4111
|
-
const workspaceName =
|
|
4112
|
-
intro3(
|
|
4026
|
+
const workspaceName = path18.basename(process.cwd());
|
|
4027
|
+
intro3(pc16.cyan(pc16.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
4113
4028
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
4114
4029
|
if (prompts.length === 0) {
|
|
4115
|
-
|
|
4030
|
+
cancel9("No agents found. Run `rrce-workflow` to set up.");
|
|
4116
4031
|
process.exit(0);
|
|
4117
4032
|
}
|
|
4118
|
-
const selection = await
|
|
4033
|
+
const selection = await select6({
|
|
4119
4034
|
message: "Select an agent:",
|
|
4120
4035
|
options: [
|
|
4121
4036
|
{
|
|
@@ -4135,8 +4050,8 @@ async function runSelector() {
|
|
|
4135
4050
|
}))
|
|
4136
4051
|
]
|
|
4137
4052
|
});
|
|
4138
|
-
if (
|
|
4139
|
-
|
|
4053
|
+
if (isCancel13(selection)) {
|
|
4054
|
+
cancel9("Selection cancelled.");
|
|
4140
4055
|
process.exit(0);
|
|
4141
4056
|
}
|
|
4142
4057
|
if (selection === "mcp") {
|
|
@@ -4150,9 +4065,9 @@ async function runSelector() {
|
|
|
4150
4065
|
return;
|
|
4151
4066
|
}
|
|
4152
4067
|
const prompt = selection;
|
|
4153
|
-
|
|
4068
|
+
note14(
|
|
4154
4069
|
`Use this agent in your IDE by invoking:
|
|
4155
|
-
${
|
|
4070
|
+
${pc16.bold(pc16.cyan(`@${prompt.frontmatter.name}`))}`,
|
|
4156
4071
|
"Agent Selected"
|
|
4157
4072
|
);
|
|
4158
4073
|
outro8("Done");
|