rrce-workflow 0.2.49 → 0.2.50
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 +1021 -1112
- 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
|
-
`;
|
|
1046
|
-
}
|
|
1047
|
-
content += ` expose: ${project.expose}
|
|
1048
985
|
`;
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
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) {
|
|
@@ -1143,26 +1047,195 @@ function cleanStaleProjects(config) {
|
|
|
1143
1047
|
removed.push(project.name);
|
|
1144
1048
|
}
|
|
1145
1049
|
}
|
|
1146
|
-
if (removed.length > 0) {
|
|
1147
|
-
config.projects = validProjects;
|
|
1050
|
+
if (removed.length > 0) {
|
|
1051
|
+
config.projects = validProjects;
|
|
1052
|
+
}
|
|
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/");
|
|
1148
1204
|
}
|
|
1149
|
-
|
|
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, 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();
|
|
@@ -2925,7 +2997,7 @@ var init_App = __esm({
|
|
|
2925
2997
|
installStatus.vscodeGlobal,
|
|
2926
2998
|
installStatus.vscodeWorkspace
|
|
2927
2999
|
].filter(Boolean).length;
|
|
2928
|
-
|
|
3000
|
+
useEffect3(() => {
|
|
2929
3001
|
const start = async () => {
|
|
2930
3002
|
const status = getMCPServerStatus();
|
|
2931
3003
|
if (!status.running) {
|
|
@@ -2941,21 +3013,21 @@ var init_App = __esm({
|
|
|
2941
3013
|
};
|
|
2942
3014
|
start();
|
|
2943
3015
|
}, []);
|
|
2944
|
-
|
|
3016
|
+
useEffect3(() => {
|
|
2945
3017
|
const logPath = getLogFilePath();
|
|
2946
3018
|
let lastSize = 0;
|
|
2947
|
-
if (
|
|
2948
|
-
const stats =
|
|
3019
|
+
if (fs15.existsSync(logPath)) {
|
|
3020
|
+
const stats = fs15.statSync(logPath);
|
|
2949
3021
|
lastSize = stats.size;
|
|
2950
3022
|
}
|
|
2951
3023
|
const interval = setInterval(() => {
|
|
2952
|
-
if (
|
|
2953
|
-
const stats =
|
|
3024
|
+
if (fs15.existsSync(logPath)) {
|
|
3025
|
+
const stats = fs15.statSync(logPath);
|
|
2954
3026
|
if (stats.size > lastSize) {
|
|
2955
3027
|
const buffer = Buffer.alloc(stats.size - lastSize);
|
|
2956
|
-
const fd =
|
|
2957
|
-
|
|
2958
|
-
|
|
3028
|
+
const fd = fs15.openSync(logPath, "r");
|
|
3029
|
+
fs15.readSync(fd, buffer, 0, buffer.length, lastSize);
|
|
3030
|
+
fs15.closeSync(fd);
|
|
2959
3031
|
const newContent = buffer.toString("utf-8");
|
|
2960
3032
|
const newLines = newContent.split("\n").filter((l) => l.trim());
|
|
2961
3033
|
setLogs((prev) => {
|
|
@@ -2977,9 +3049,9 @@ var init_App = __esm({
|
|
|
2977
3049
|
});
|
|
2978
3050
|
const termHeight = process.stdout.rows || 24;
|
|
2979
3051
|
const contentHeight = termHeight - 8;
|
|
2980
|
-
const handleConfigChange = () => {
|
|
2981
|
-
|
|
2982
|
-
};
|
|
3052
|
+
const handleConfigChange = useCallback(() => {
|
|
3053
|
+
refreshData();
|
|
3054
|
+
}, [refreshData]);
|
|
2983
3055
|
return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", padding: 0, height: termHeight, children: [
|
|
2984
3056
|
/* @__PURE__ */ jsx10(TabBar, { tabs: TABS, activeTab, onChange: setActiveTab }),
|
|
2985
3057
|
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexGrow: 1, children: [
|
|
@@ -2994,7 +3066,7 @@ var init_App = __esm({
|
|
|
2994
3066
|
}
|
|
2995
3067
|
}
|
|
2996
3068
|
),
|
|
2997
|
-
activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { onConfigChange: handleConfigChange }),
|
|
3069
|
+
activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { config, projects, onConfigChange: handleConfigChange }),
|
|
2998
3070
|
activeTab === "install" && /* @__PURE__ */ jsx10(InstallView, {}),
|
|
2999
3071
|
activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight })
|
|
3000
3072
|
] }),
|
|
@@ -3013,7 +3085,7 @@ var init_App = __esm({
|
|
|
3013
3085
|
});
|
|
3014
3086
|
|
|
3015
3087
|
// src/mcp/commands/start.ts
|
|
3016
|
-
import { confirm as
|
|
3088
|
+
import { confirm as confirm3, isCancel as isCancel5, text } from "@clack/prompts";
|
|
3017
3089
|
async function handleStartServer() {
|
|
3018
3090
|
const React11 = await import("react");
|
|
3019
3091
|
const { render } = await import("ink");
|
|
@@ -3027,11 +3099,11 @@ async function handleStartServer() {
|
|
|
3027
3099
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
3028
3100
|
});
|
|
3029
3101
|
if (exposedProjects.length === 0) {
|
|
3030
|
-
const shouldConfig = await
|
|
3102
|
+
const shouldConfig = await confirm3({
|
|
3031
3103
|
message: "No projects are currently exposed. Configure now?",
|
|
3032
3104
|
initialValue: true
|
|
3033
3105
|
});
|
|
3034
|
-
if (shouldConfig && !
|
|
3106
|
+
if (shouldConfig && !isCancel5(shouldConfig)) {
|
|
3035
3107
|
await handleConfigure();
|
|
3036
3108
|
return handleStartServer();
|
|
3037
3109
|
}
|
|
@@ -3047,7 +3119,7 @@ async function handleStartServer() {
|
|
|
3047
3119
|
if (isNaN(Number(value))) return "Port must be a number";
|
|
3048
3120
|
}
|
|
3049
3121
|
});
|
|
3050
|
-
if (
|
|
3122
|
+
if (isCancel5(portInput)) return;
|
|
3051
3123
|
const newPort = parseInt(portInput, 10);
|
|
3052
3124
|
if (newPort !== config.server.port) {
|
|
3053
3125
|
config.server.port = newPort;
|
|
@@ -3079,8 +3151,8 @@ var init_start = __esm({
|
|
|
3079
3151
|
});
|
|
3080
3152
|
|
|
3081
3153
|
// src/mcp/commands/status.ts
|
|
3082
|
-
import { spinner as spinner2, note as
|
|
3083
|
-
import
|
|
3154
|
+
import { spinner as spinner2, note as note5 } from "@clack/prompts";
|
|
3155
|
+
import pc7 from "picocolors";
|
|
3084
3156
|
async function handleShowStatus() {
|
|
3085
3157
|
const s = spinner2();
|
|
3086
3158
|
s.start("Loading projects...");
|
|
@@ -3090,36 +3162,36 @@ async function handleShowStatus() {
|
|
|
3090
3162
|
const installStatus = checkInstallStatus(workspacePath);
|
|
3091
3163
|
s.stop("Projects loaded");
|
|
3092
3164
|
if (projects.length === 0) {
|
|
3093
|
-
|
|
3165
|
+
note5('No RRCE projects detected. Run "rrce-workflow" in a project to set it up.', "No Projects");
|
|
3094
3166
|
return;
|
|
3095
3167
|
}
|
|
3096
3168
|
const lines = [
|
|
3097
|
-
`${
|
|
3169
|
+
`${pc7.bold("Installation Status")}`,
|
|
3098
3170
|
"",
|
|
3099
|
-
` Antigravity: ${installStatus.antigravity ?
|
|
3100
|
-
` VSCode (Global): ${installStatus.vscodeGlobal ?
|
|
3101
|
-
` VSCode (Workspace): ${installStatus.vscodeWorkspace ?
|
|
3102
|
-
` Claude Desktop: ${installStatus.claude ?
|
|
3171
|
+
` Antigravity: ${installStatus.antigravity ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3172
|
+
` VSCode (Global): ${installStatus.vscodeGlobal ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3173
|
+
` VSCode (Workspace): ${installStatus.vscodeWorkspace ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3174
|
+
` Claude Desktop: ${installStatus.claude ? pc7.green("\u2713 Installed") : pc7.dim("Not installed")}`,
|
|
3103
3175
|
"",
|
|
3104
|
-
`${
|
|
3176
|
+
`${pc7.bold("Project Status")}`,
|
|
3105
3177
|
""
|
|
3106
3178
|
];
|
|
3107
3179
|
for (const project of projects) {
|
|
3108
3180
|
const projectConfig = config.projects.find((p) => p.name === project.name);
|
|
3109
3181
|
const isExposed = projectConfig?.expose ?? config.defaults.includeNew;
|
|
3110
|
-
const status = isExposed ?
|
|
3111
|
-
const source =
|
|
3182
|
+
const status = isExposed ? pc7.green("\u2713 exposed") : pc7.dim("\u25CB hidden");
|
|
3183
|
+
const source = pc7.dim(`(${project.source})`);
|
|
3112
3184
|
lines.push(` ${status} ${project.name} ${source}`);
|
|
3113
3185
|
}
|
|
3114
3186
|
lines.push("");
|
|
3115
|
-
lines.push(
|
|
3187
|
+
lines.push(pc7.dim(`Config: ${getMCPConfigPath()}`));
|
|
3116
3188
|
const serverStatus = getMCPServerStatus();
|
|
3117
3189
|
if (serverStatus.running) {
|
|
3118
|
-
lines.push(
|
|
3190
|
+
lines.push(pc7.green(`Server: running on port ${serverStatus.port}`));
|
|
3119
3191
|
} else {
|
|
3120
|
-
lines.push(
|
|
3192
|
+
lines.push(pc7.dim("Server: not running"));
|
|
3121
3193
|
}
|
|
3122
|
-
|
|
3194
|
+
note5(lines.join("\n"), "MCP Hub Status");
|
|
3123
3195
|
}
|
|
3124
3196
|
var init_status = __esm({
|
|
3125
3197
|
"src/mcp/commands/status.ts"() {
|
|
@@ -3133,46 +3205,46 @@ var init_status = __esm({
|
|
|
3133
3205
|
});
|
|
3134
3206
|
|
|
3135
3207
|
// src/mcp/commands/help.ts
|
|
3136
|
-
import { note as
|
|
3137
|
-
import
|
|
3208
|
+
import { note as note6 } from "@clack/prompts";
|
|
3209
|
+
import pc8 from "picocolors";
|
|
3138
3210
|
function showHelp() {
|
|
3139
3211
|
const help = `
|
|
3140
|
-
${
|
|
3212
|
+
${pc8.bold("RRCE MCP Hub")} - Cross-project AI assistant server
|
|
3141
3213
|
|
|
3142
|
-
${
|
|
3214
|
+
${pc8.bold("ABOUT")}
|
|
3143
3215
|
MCP (Model Context Protocol) allows AI assistants like Claude to
|
|
3144
3216
|
access your project knowledge in real-time. The RRCE MCP Hub
|
|
3145
3217
|
provides a central server that exposes selected projects.
|
|
3146
3218
|
|
|
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
|
-
${
|
|
3219
|
+
${pc8.bold("MENU OPTIONS")}
|
|
3220
|
+
${pc8.cyan("Start MCP server")} Start the server for AI access
|
|
3221
|
+
${pc8.cyan("Configure projects")} Choose which projects to expose
|
|
3222
|
+
${pc8.cyan("Install to IDE")} Add to Antigravity, VSCode, or Claude
|
|
3223
|
+
${pc8.cyan("View status")} See which projects are exposed
|
|
3224
|
+
|
|
3225
|
+
${pc8.bold("DIRECT COMMANDS")}
|
|
3226
|
+
${pc8.dim("rrce-workflow mcp start")} Start server directly
|
|
3227
|
+
${pc8.dim("rrce-workflow mcp stop")} Stop server directly
|
|
3228
|
+
${pc8.dim("rrce-workflow mcp status")} Show status directly
|
|
3229
|
+
${pc8.dim("rrce-workflow mcp help")} Show this help
|
|
3230
|
+
|
|
3231
|
+
${pc8.bold("IDE INSTALLATION")}
|
|
3232
|
+
${pc8.cyan("Antigravity")} ~/.gemini/antigravity/mcp_config.json
|
|
3233
|
+
${pc8.cyan("VSCode Global")} ~/.config/Code/User/settings.json
|
|
3234
|
+
${pc8.cyan("VSCode Workspace")} .vscode/mcp.json
|
|
3235
|
+
${pc8.cyan("Claude Desktop")} ~/.config/claude/claude_desktop_config.json
|
|
3236
|
+
|
|
3237
|
+
${pc8.bold("SERVER COMMANDS")} (while running)
|
|
3238
|
+
${pc8.cyan("q")} Stop and quit ${pc8.cyan("p")} Reconfigure projects
|
|
3239
|
+
${pc8.cyan("i")} Install to IDE ${pc8.cyan("r")} Reload config
|
|
3240
|
+
${pc8.cyan("c")} Clear logs ${pc8.cyan("?")} Show help
|
|
3241
|
+
|
|
3242
|
+
${pc8.bold("RESOURCES EXPOSED")}
|
|
3243
|
+
${pc8.cyan("rrce://projects")} List all exposed projects
|
|
3244
|
+
${pc8.cyan("rrce://projects/{name}/context")} Get project context
|
|
3245
|
+
${pc8.cyan("rrce://projects/{name}/tasks")} Get project tasks
|
|
3174
3246
|
`;
|
|
3175
|
-
|
|
3247
|
+
note6(help.trim(), "Help");
|
|
3176
3248
|
}
|
|
3177
3249
|
var init_help = __esm({
|
|
3178
3250
|
"src/mcp/commands/help.ts"() {
|
|
@@ -3188,8 +3260,8 @@ __export(mcp_exports, {
|
|
|
3188
3260
|
handleStartServer: () => handleStartServer,
|
|
3189
3261
|
runMCP: () => runMCP
|
|
3190
3262
|
});
|
|
3191
|
-
import { intro, outro, confirm as
|
|
3192
|
-
import
|
|
3263
|
+
import { intro, outro, confirm as confirm4, note as note7, isCancel as isCancel6 } from "@clack/prompts";
|
|
3264
|
+
import pc9 from "picocolors";
|
|
3193
3265
|
async function runMCP(subcommand2) {
|
|
3194
3266
|
if (subcommand2) {
|
|
3195
3267
|
switch (subcommand2) {
|
|
@@ -3221,36 +3293,36 @@ async function runMCP(subcommand2) {
|
|
|
3221
3293
|
const workspacePath = detectWorkspaceRoot();
|
|
3222
3294
|
const globalPathCheck = await ensureMCPGlobalPath();
|
|
3223
3295
|
if (!globalPathCheck.configured) {
|
|
3224
|
-
intro(
|
|
3296
|
+
intro(pc9.bgCyan(pc9.black(" MCP Setup ")));
|
|
3225
3297
|
const configured = await handleConfigureGlobalPath();
|
|
3226
3298
|
if (!configured) {
|
|
3227
|
-
outro(
|
|
3299
|
+
outro(pc9.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
3228
3300
|
return;
|
|
3229
3301
|
}
|
|
3230
3302
|
}
|
|
3231
3303
|
const installed = isInstalledAnywhere(workspacePath);
|
|
3232
3304
|
if (!installed) {
|
|
3233
|
-
intro(
|
|
3234
|
-
|
|
3235
|
-
`${
|
|
3305
|
+
intro(pc9.bgCyan(pc9.black(" Welcome to MCP Hub ")));
|
|
3306
|
+
note7(
|
|
3307
|
+
`${pc9.bold("Set up Model Context Protocol")}
|
|
3236
3308
|
Allow AI assistants to access your project context.`,
|
|
3237
3309
|
"Getting Started"
|
|
3238
3310
|
);
|
|
3239
|
-
const shouldInstall = await
|
|
3311
|
+
const shouldInstall = await confirm4({
|
|
3240
3312
|
message: "Install MCP server integrations now?",
|
|
3241
3313
|
initialValue: true
|
|
3242
3314
|
});
|
|
3243
|
-
if (shouldInstall && !
|
|
3315
|
+
if (shouldInstall && !isCancel6(shouldInstall)) {
|
|
3244
3316
|
await runInstallWizard(workspacePath);
|
|
3245
|
-
const shouldStart = await
|
|
3317
|
+
const shouldStart = await confirm4({
|
|
3246
3318
|
message: "Start the MCP Dashboard?",
|
|
3247
3319
|
initialValue: true
|
|
3248
3320
|
});
|
|
3249
|
-
if (shouldStart && !
|
|
3321
|
+
if (shouldStart && !isCancel6(shouldStart)) {
|
|
3250
3322
|
await handleStartServer();
|
|
3251
3323
|
}
|
|
3252
3324
|
} else {
|
|
3253
|
-
outro(
|
|
3325
|
+
outro(pc9.dim('Setup skipped. Run "npx rrce-workflow mcp" later to restart.'));
|
|
3254
3326
|
}
|
|
3255
3327
|
return;
|
|
3256
3328
|
}
|
|
@@ -3258,18 +3330,18 @@ Allow AI assistants to access your project context.`,
|
|
|
3258
3330
|
await handleStartServer();
|
|
3259
3331
|
} catch (err) {
|
|
3260
3332
|
console.error(err);
|
|
3261
|
-
outro(
|
|
3333
|
+
outro(pc9.red("Failed to launch MCP Dashboard"));
|
|
3262
3334
|
}
|
|
3263
3335
|
}
|
|
3264
3336
|
async function handleStopServer() {
|
|
3265
3337
|
const { stopMCPServer: stopMCPServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
3266
3338
|
const status = getMCPServerStatus();
|
|
3267
3339
|
if (!status.running) {
|
|
3268
|
-
console.log(
|
|
3340
|
+
console.log(pc9.dim("MCP server is already stopped."));
|
|
3269
3341
|
return;
|
|
3270
3342
|
}
|
|
3271
3343
|
stopMCPServer2();
|
|
3272
|
-
console.log(
|
|
3344
|
+
console.log(pc9.green("MCP server stopped."));
|
|
3273
3345
|
}
|
|
3274
3346
|
var init_mcp = __esm({
|
|
3275
3347
|
"src/mcp/index.ts"() {
|
|
@@ -3287,364 +3359,201 @@ var init_mcp = __esm({
|
|
|
3287
3359
|
});
|
|
3288
3360
|
|
|
3289
3361
|
// 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
|
-
}
|
|
3362
|
+
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";
|
|
3363
|
+
import pc10 from "picocolors";
|
|
3364
|
+
async function runExpressSetup(workspacePath, workspaceName, existingProjects, s) {
|
|
3365
|
+
const storageModeResult = await select3({
|
|
3366
|
+
message: "Where should workflow data be stored?",
|
|
3367
|
+
options: [
|
|
3368
|
+
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Recommended - cross-project access" },
|
|
3369
|
+
{ value: "workspace", label: "Workspace (.rrce-workflow/)", hint: "Self-contained" }
|
|
3370
|
+
],
|
|
3371
|
+
initialValue: "global"
|
|
3372
|
+
});
|
|
3373
|
+
if (isCancel7(storageModeResult)) {
|
|
3374
|
+
cancel3("Setup cancelled.");
|
|
3375
|
+
process.exit(0);
|
|
3376
|
+
}
|
|
3377
|
+
const storageMode = storageModeResult;
|
|
3378
|
+
let customGlobalPath;
|
|
3379
|
+
if (storageMode === "global") {
|
|
3380
|
+
customGlobalPath = await resolveGlobalPath();
|
|
3381
|
+
if (!customGlobalPath) {
|
|
3382
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
3383
|
+
process.exit(0);
|
|
3362
3384
|
}
|
|
3385
|
+
}
|
|
3386
|
+
note8(
|
|
3387
|
+
`${pc10.bold("Express Setup will configure:")}
|
|
3388
|
+
\u2022 Storage: ${storageMode === "global" ? "Global" : "Workspace"}
|
|
3389
|
+
\u2022 MCP Server: Enabled
|
|
3390
|
+
\u2022 Semantic Search (RAG): Enabled
|
|
3391
|
+
\u2022 Git ignore entries: Added (as comments)
|
|
3392
|
+
\u2022 AI Tools: All available`,
|
|
3393
|
+
"Configuration Preview"
|
|
3363
3394
|
);
|
|
3364
|
-
|
|
3365
|
-
|
|
3395
|
+
const confirmed = await confirm5({
|
|
3396
|
+
message: "Proceed with express setup?",
|
|
3397
|
+
initialValue: true
|
|
3398
|
+
});
|
|
3399
|
+
if (isCancel7(confirmed) || !confirmed) {
|
|
3400
|
+
cancel3("Setup cancelled.");
|
|
3401
|
+
process.exit(0);
|
|
3402
|
+
}
|
|
3403
|
+
const config = {
|
|
3404
|
+
storageMode,
|
|
3405
|
+
globalPath: customGlobalPath,
|
|
3406
|
+
tools: ["copilot", "antigravity"],
|
|
3407
|
+
linkedProjects: [],
|
|
3408
|
+
addToGitignore: true,
|
|
3409
|
+
exposeToMCP: true,
|
|
3410
|
+
enableRAG: true
|
|
3411
|
+
};
|
|
3412
|
+
await executeSetup(config, workspacePath, workspaceName, existingProjects, s);
|
|
3413
|
+
const startMCP = await confirm5({
|
|
3414
|
+
message: "Start MCP server now?",
|
|
3415
|
+
initialValue: true
|
|
3416
|
+
});
|
|
3417
|
+
if (startMCP && !isCancel7(startMCP)) {
|
|
3418
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
3419
|
+
await runMCP2();
|
|
3420
|
+
} else {
|
|
3421
|
+
outro2(pc10.green(`\u2713 Express setup complete! Run ${pc10.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
3425
|
+
const s = spinner3();
|
|
3426
|
+
const setupModeResult = await select3({
|
|
3427
|
+
message: "Setup mode:",
|
|
3428
|
+
options: [
|
|
3429
|
+
{ value: "express", label: "Express Setup", hint: "Quick start with recommended defaults (3 steps)" },
|
|
3430
|
+
{ value: "custom", label: "Custom Setup", hint: "Full configuration options" }
|
|
3431
|
+
],
|
|
3432
|
+
initialValue: "express"
|
|
3433
|
+
});
|
|
3434
|
+
if (isCancel7(setupModeResult)) {
|
|
3435
|
+
cancel3("Setup cancelled.");
|
|
3366
3436
|
process.exit(0);
|
|
3367
3437
|
}
|
|
3438
|
+
if (setupModeResult === "express") {
|
|
3439
|
+
return runExpressSetup(workspacePath, workspaceName, existingProjects, s);
|
|
3440
|
+
}
|
|
3441
|
+
const storageMode = await promptStorageMode();
|
|
3368
3442
|
let customGlobalPath;
|
|
3369
|
-
if (
|
|
3443
|
+
if (storageMode === "global") {
|
|
3370
3444
|
customGlobalPath = await resolveGlobalPath();
|
|
3371
3445
|
if (!customGlobalPath) {
|
|
3372
|
-
|
|
3373
|
-
process.exit(
|
|
3446
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
3447
|
+
process.exit(0);
|
|
3374
3448
|
}
|
|
3375
3449
|
}
|
|
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
|
-
}
|
|
3450
|
+
const tools = await promptTools();
|
|
3451
|
+
const exposeToMCP = await promptMCPExposure();
|
|
3452
|
+
const linkedProjects = await promptLinkedProjects(existingProjects);
|
|
3453
|
+
const addToGitignore = await promptGitignore();
|
|
3454
|
+
const enableRAG = await promptRAG();
|
|
3455
|
+
const confirmed = await promptConfirmation();
|
|
3456
|
+
if (!confirmed) {
|
|
3457
|
+
outro2("Setup cancelled by user.");
|
|
3458
|
+
process.exit(0);
|
|
3391
3459
|
}
|
|
3460
|
+
const config = {
|
|
3461
|
+
storageMode,
|
|
3462
|
+
globalPath: customGlobalPath,
|
|
3463
|
+
tools,
|
|
3464
|
+
linkedProjects,
|
|
3465
|
+
addToGitignore,
|
|
3466
|
+
exposeToMCP,
|
|
3467
|
+
enableRAG
|
|
3468
|
+
};
|
|
3469
|
+
await executeSetup(config, workspacePath, workspaceName, existingProjects, s);
|
|
3470
|
+
await handlePostSetup(config, workspacePath, workspaceName, linkedProjects);
|
|
3471
|
+
}
|
|
3472
|
+
async function executeSetup(config, workspacePath, workspaceName, allProjects, s) {
|
|
3392
3473
|
s.start("Generating configuration");
|
|
3393
3474
|
try {
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3475
|
+
const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
3476
|
+
createDirectoryStructure(dataPaths);
|
|
3477
|
+
installAgentPrompts(config, workspacePath, dataPaths);
|
|
3478
|
+
createWorkspaceConfig(config, workspacePath, workspaceName);
|
|
3479
|
+
if (config.addToGitignore) {
|
|
3480
|
+
const { updateGitignore: updateGitignore2 } = await Promise.resolve().then(() => (init_gitignore(), gitignore_exports));
|
|
3481
|
+
updateGitignore2(workspacePath, config.storageMode, config.tools);
|
|
3482
|
+
}
|
|
3483
|
+
if (config.tools.includes("copilot") || config.linkedProjects.length > 0) {
|
|
3484
|
+
const selectedProjects = allProjects.filter(
|
|
3485
|
+
(p) => config.linkedProjects.includes(`${p.name}:${p.source}`)
|
|
3486
|
+
);
|
|
3487
|
+
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, config.globalPath);
|
|
3488
|
+
}
|
|
3489
|
+
await registerWithMCP(config, workspacePath, workspaceName);
|
|
3403
3490
|
s.stop("Configuration generated");
|
|
3404
|
-
const
|
|
3405
|
-
config.storageMode,
|
|
3406
|
-
workspaceName,
|
|
3407
|
-
workspacePath,
|
|
3408
|
-
customGlobalPath
|
|
3409
|
-
);
|
|
3491
|
+
const dataSummary = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
3410
3492
|
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
|
-
}
|
|
3493
|
+
`${pc10.green("\u2713")} Data stored at: ${pc10.dim(dataSummary[0])}`,
|
|
3494
|
+
config.tools.length > 0 ? `${pc10.green("\u2713")} Tools: ${config.tools.join(", ")}` : null,
|
|
3495
|
+
config.exposeToMCP ? `${pc10.green("\u2713")} MCP server configured` : null,
|
|
3496
|
+
config.enableRAG ? `${pc10.green("\u2713")} Semantic Search enabled` : null,
|
|
3497
|
+
config.linkedProjects.length > 0 ? `${pc10.green("\u2713")} Linked ${config.linkedProjects.length} project(s)` : null
|
|
3498
|
+
].filter(Boolean);
|
|
3499
|
+
note8(summary.join("\n"), "Setup Complete");
|
|
3453
3500
|
} catch (error) {
|
|
3454
3501
|
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}"
|
|
3502
|
+
cancel3(
|
|
3503
|
+
`Setup failed: ${error instanceof Error ? error.message : String(error)}
|
|
3500
3504
|
|
|
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}`)
|
|
3505
|
+
${pc10.dim("Tip: You can re-run the wizard to try again.")}`
|
|
3522
3506
|
);
|
|
3523
|
-
|
|
3507
|
+
process.exit(1);
|
|
3524
3508
|
}
|
|
3509
|
+
}
|
|
3510
|
+
async function handlePostSetup(config, workspacePath, workspaceName, linkedProjects) {
|
|
3525
3511
|
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);
|
|
3512
|
+
const shouldConfigureMCP = await confirm5({
|
|
3513
|
+
message: "Would you like to start the MCP server now?",
|
|
3514
|
+
initialValue: true
|
|
3515
|
+
});
|
|
3516
|
+
if (shouldConfigureMCP && !isCancel7(shouldConfigureMCP)) {
|
|
3517
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
3518
|
+
await runMCP2();
|
|
3519
|
+
} else {
|
|
3520
|
+
if (linkedProjects.length > 0) {
|
|
3521
|
+
outro2(pc10.green(`\u2713 Setup complete! Open ${pc10.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
3545
3522
|
} 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);
|
|
3523
|
+
outro2(pc10.green(`\u2713 Setup complete! Run ${pc10.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
3606
3524
|
}
|
|
3607
3525
|
}
|
|
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";
|
|
3526
|
+
} else {
|
|
3527
|
+
if (linkedProjects.length > 0) {
|
|
3528
|
+
outro2(pc10.green(`\u2713 Setup complete! Open ${pc10.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
3529
|
+
} else {
|
|
3530
|
+
outro2(pc10.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
3617
3531
|
}
|
|
3618
|
-
newContent += newEntries.map((e) => `# ${e}`).join("\n") + "\n";
|
|
3619
|
-
fs14.writeFileSync(gitignorePath, newContent);
|
|
3620
|
-
return true;
|
|
3621
|
-
} catch {
|
|
3622
|
-
return false;
|
|
3623
3532
|
}
|
|
3624
3533
|
}
|
|
3625
3534
|
var init_setup_flow = __esm({
|
|
3626
3535
|
"src/commands/wizard/setup-flow.ts"() {
|
|
3627
3536
|
"use strict";
|
|
3628
|
-
init_paths();
|
|
3629
|
-
init_prompts();
|
|
3630
|
-
init_utils();
|
|
3631
|
-
init_vscode();
|
|
3632
3537
|
init_detection();
|
|
3633
3538
|
init_tui_utils();
|
|
3539
|
+
init_setup_prompts();
|
|
3540
|
+
init_setup_actions();
|
|
3541
|
+
init_gitignore();
|
|
3542
|
+
init_vscode();
|
|
3634
3543
|
}
|
|
3635
3544
|
});
|
|
3636
3545
|
|
|
3637
3546
|
// src/commands/wizard/link-flow.ts
|
|
3638
|
-
import { multiselect as multiselect4, spinner as spinner4, note as
|
|
3639
|
-
import
|
|
3640
|
-
import * as
|
|
3547
|
+
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";
|
|
3548
|
+
import pc11 from "picocolors";
|
|
3549
|
+
import * as fs16 from "fs";
|
|
3641
3550
|
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
3642
3551
|
const projects = scanForProjects({
|
|
3643
3552
|
excludeWorkspace: workspaceName,
|
|
3644
3553
|
workspacePath
|
|
3645
3554
|
});
|
|
3646
3555
|
if (projects.length === 0) {
|
|
3647
|
-
outro3(
|
|
3556
|
+
outro3(pc11.yellow("No other projects found. Try setting up another project first."));
|
|
3648
3557
|
return;
|
|
3649
3558
|
}
|
|
3650
3559
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
@@ -3653,15 +3562,15 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
3653
3562
|
options: projects.map((project) => ({
|
|
3654
3563
|
value: `${project.name}:${project.source}`,
|
|
3655
3564
|
// Unique key
|
|
3656
|
-
label: `${project.name} ${
|
|
3657
|
-
hint:
|
|
3565
|
+
label: `${project.name} ${pc11.dim(`(${project.source})`)}`,
|
|
3566
|
+
hint: pc11.dim(
|
|
3658
3567
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
3659
3568
|
)
|
|
3660
3569
|
})),
|
|
3661
3570
|
required: true
|
|
3662
3571
|
});
|
|
3663
|
-
if (
|
|
3664
|
-
|
|
3572
|
+
if (isCancel8(linkedProjects)) {
|
|
3573
|
+
cancel4("Cancelled.");
|
|
3665
3574
|
process.exit(0);
|
|
3666
3575
|
}
|
|
3667
3576
|
const selectedKeys = linkedProjects;
|
|
@@ -3675,7 +3584,7 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
3675
3584
|
const s = spinner4();
|
|
3676
3585
|
s.start("Linking projects");
|
|
3677
3586
|
const configFilePath = getConfigPath(workspacePath);
|
|
3678
|
-
let configContent =
|
|
3587
|
+
let configContent = fs16.readFileSync(configFilePath, "utf-8");
|
|
3679
3588
|
if (configContent.includes("linked_projects:")) {
|
|
3680
3589
|
const lines = configContent.split("\n");
|
|
3681
3590
|
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
@@ -3702,23 +3611,23 @@ linked_projects:
|
|
|
3702
3611
|
`;
|
|
3703
3612
|
});
|
|
3704
3613
|
}
|
|
3705
|
-
|
|
3614
|
+
fs16.writeFileSync(configFilePath, configContent);
|
|
3706
3615
|
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
3707
3616
|
s.stop("Projects linked");
|
|
3708
3617
|
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
3709
3618
|
const summary = [
|
|
3710
3619
|
`Linked projects:`,
|
|
3711
|
-
...selectedProjects.map((p) => ` \u2713 ${p.name} ${
|
|
3620
|
+
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc11.dim(`(${p.source})`)}`),
|
|
3712
3621
|
``,
|
|
3713
|
-
`Workspace file: ${
|
|
3622
|
+
`Workspace file: ${pc11.cyan(workspaceFile)}`
|
|
3714
3623
|
];
|
|
3715
|
-
|
|
3716
|
-
outro3(
|
|
3717
|
-
const shouldExpose = await
|
|
3624
|
+
note9(summary.join("\n"), "Link Summary");
|
|
3625
|
+
outro3(pc11.green(`\u2713 Projects linked! Open ${pc11.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
3626
|
+
const shouldExpose = await confirm6({
|
|
3718
3627
|
message: "Also expose these linked projects to the MCP server (for Agent access)?",
|
|
3719
3628
|
initialValue: true
|
|
3720
3629
|
});
|
|
3721
|
-
if (shouldExpose && !
|
|
3630
|
+
if (shouldExpose && !isCancel8(shouldExpose)) {
|
|
3722
3631
|
try {
|
|
3723
3632
|
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3724
3633
|
const mcpConfig = loadMCPConfig3();
|
|
@@ -3726,9 +3635,9 @@ linked_projects:
|
|
|
3726
3635
|
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
3727
3636
|
}
|
|
3728
3637
|
saveMCPConfig2(mcpConfig);
|
|
3729
|
-
|
|
3638
|
+
note9("Projects have been added to the global MCP configuration.", "MCP Updated");
|
|
3730
3639
|
} catch (err) {
|
|
3731
|
-
|
|
3640
|
+
note9(`Failed to update MCP config: ${err}`, "MCP Update Failed");
|
|
3732
3641
|
}
|
|
3733
3642
|
}
|
|
3734
3643
|
}
|
|
@@ -3742,34 +3651,34 @@ var init_link_flow = __esm({
|
|
|
3742
3651
|
});
|
|
3743
3652
|
|
|
3744
3653
|
// src/commands/wizard/sync-flow.ts
|
|
3745
|
-
import { confirm as
|
|
3746
|
-
import
|
|
3747
|
-
import * as
|
|
3748
|
-
import * as
|
|
3654
|
+
import { confirm as confirm7, spinner as spinner5, note as note10, outro as outro4, cancel as cancel5, isCancel as isCancel9 } from "@clack/prompts";
|
|
3655
|
+
import pc12 from "picocolors";
|
|
3656
|
+
import * as fs17 from "fs";
|
|
3657
|
+
import * as path16 from "path";
|
|
3749
3658
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
3750
3659
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
3751
3660
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
3752
|
-
const globalPath =
|
|
3661
|
+
const globalPath = path16.join(customGlobalPath, "workspaces", workspaceName);
|
|
3753
3662
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
3754
3663
|
const existingDirs = subdirs.filter(
|
|
3755
|
-
(dir) =>
|
|
3664
|
+
(dir) => fs17.existsSync(path16.join(localPath, dir))
|
|
3756
3665
|
);
|
|
3757
3666
|
if (existingDirs.length === 0) {
|
|
3758
|
-
outro4(
|
|
3667
|
+
outro4(pc12.yellow("No data found in workspace storage to sync."));
|
|
3759
3668
|
return;
|
|
3760
3669
|
}
|
|
3761
|
-
|
|
3670
|
+
note10(
|
|
3762
3671
|
`The following will be copied to global storage:
|
|
3763
3672
|
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
3764
3673
|
|
|
3765
|
-
Destination: ${
|
|
3674
|
+
Destination: ${pc12.cyan(globalPath)}`,
|
|
3766
3675
|
"Sync Preview"
|
|
3767
3676
|
);
|
|
3768
|
-
const shouldSync = await
|
|
3677
|
+
const shouldSync = await confirm7({
|
|
3769
3678
|
message: "Proceed with sync to global storage?",
|
|
3770
3679
|
initialValue: true
|
|
3771
3680
|
});
|
|
3772
|
-
if (
|
|
3681
|
+
if (isCancel9(shouldSync) || !shouldSync) {
|
|
3773
3682
|
outro4("Sync cancelled.");
|
|
3774
3683
|
return;
|
|
3775
3684
|
}
|
|
@@ -3778,8 +3687,8 @@ Destination: ${pc10.cyan(globalPath)}`,
|
|
|
3778
3687
|
try {
|
|
3779
3688
|
ensureDir(globalPath);
|
|
3780
3689
|
for (const dir of existingDirs) {
|
|
3781
|
-
const srcDir =
|
|
3782
|
-
const destDir =
|
|
3690
|
+
const srcDir = path16.join(localPath, dir);
|
|
3691
|
+
const destDir = path16.join(globalPath, dir);
|
|
3783
3692
|
ensureDir(destDir);
|
|
3784
3693
|
copyDirRecursive(srcDir, destDir);
|
|
3785
3694
|
}
|
|
@@ -3788,15 +3697,15 @@ Destination: ${pc10.cyan(globalPath)}`,
|
|
|
3788
3697
|
`Synced directories:`,
|
|
3789
3698
|
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
3790
3699
|
``,
|
|
3791
|
-
`Global path: ${
|
|
3700
|
+
`Global path: ${pc12.cyan(globalPath)}`,
|
|
3792
3701
|
``,
|
|
3793
3702
|
`Other projects can now link this knowledge!`
|
|
3794
3703
|
];
|
|
3795
|
-
|
|
3796
|
-
outro4(
|
|
3704
|
+
note10(summary.join("\n"), "Sync Summary");
|
|
3705
|
+
outro4(pc12.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
3797
3706
|
} catch (error) {
|
|
3798
3707
|
s.stop("Error occurred");
|
|
3799
|
-
|
|
3708
|
+
cancel5(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
3800
3709
|
process.exit(1);
|
|
3801
3710
|
}
|
|
3802
3711
|
}
|
|
@@ -3809,10 +3718,10 @@ var init_sync_flow = __esm({
|
|
|
3809
3718
|
});
|
|
3810
3719
|
|
|
3811
3720
|
// src/commands/wizard/update-flow.ts
|
|
3812
|
-
import { confirm as
|
|
3813
|
-
import
|
|
3814
|
-
import * as
|
|
3815
|
-
import * as
|
|
3721
|
+
import { confirm as confirm8, spinner as spinner6, note as note11, outro as outro5, cancel as cancel6, isCancel as isCancel10 } from "@clack/prompts";
|
|
3722
|
+
import pc13 from "picocolors";
|
|
3723
|
+
import * as fs18 from "fs";
|
|
3724
|
+
import * as path17 from "path";
|
|
3816
3725
|
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
3817
3726
|
const s = spinner6();
|
|
3818
3727
|
s.start("Checking for updates");
|
|
@@ -3823,7 +3732,7 @@ async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
|
3823
3732
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
3824
3733
|
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
3825
3734
|
s.stop("Updates found");
|
|
3826
|
-
|
|
3735
|
+
note11(
|
|
3827
3736
|
`The following will be updated from the package:
|
|
3828
3737
|
\u2022 prompts/ (${prompts.length} agent prompts)
|
|
3829
3738
|
\u2022 templates/ (output templates)
|
|
@@ -3832,20 +3741,20 @@ Target locations:
|
|
|
3832
3741
|
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
3833
3742
|
"Update Preview"
|
|
3834
3743
|
);
|
|
3835
|
-
const shouldUpdate = await
|
|
3744
|
+
const shouldUpdate = await confirm8({
|
|
3836
3745
|
message: "Proceed with update?",
|
|
3837
3746
|
initialValue: true
|
|
3838
3747
|
});
|
|
3839
|
-
if (
|
|
3748
|
+
if (isCancel10(shouldUpdate) || !shouldUpdate) {
|
|
3840
3749
|
outro5("Update cancelled.");
|
|
3841
3750
|
return;
|
|
3842
3751
|
}
|
|
3843
3752
|
s.start("Updating from package");
|
|
3844
3753
|
for (const dataPath of dataPaths) {
|
|
3845
|
-
copyDirToAllStoragePaths(
|
|
3754
|
+
copyDirToAllStoragePaths(path17.join(agentCoreDir, "templates"), "templates", [dataPath]);
|
|
3846
3755
|
}
|
|
3847
3756
|
const configFilePath = getConfigPath(workspacePath);
|
|
3848
|
-
const configContent =
|
|
3757
|
+
const configContent = fs18.readFileSync(configFilePath, "utf-8");
|
|
3849
3758
|
if (configContent.includes("copilot: true")) {
|
|
3850
3759
|
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
3851
3760
|
ensureDir(copilotPath);
|
|
@@ -3864,17 +3773,17 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
|
3864
3773
|
``,
|
|
3865
3774
|
`Your configuration and knowledge files were preserved.`
|
|
3866
3775
|
];
|
|
3867
|
-
|
|
3868
|
-
outro5(
|
|
3776
|
+
note11(summary.join("\n"), "Update Summary");
|
|
3777
|
+
outro5(pc13.green("\u2713 Successfully updated from package!"));
|
|
3869
3778
|
} catch (error) {
|
|
3870
3779
|
s.stop("Error occurred");
|
|
3871
|
-
|
|
3780
|
+
cancel6(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
3872
3781
|
process.exit(1);
|
|
3873
3782
|
}
|
|
3874
3783
|
}
|
|
3875
3784
|
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
3876
|
-
const globalPath =
|
|
3877
|
-
const workspacePath =
|
|
3785
|
+
const globalPath = path17.join(customGlobalPath, "workspaces", workspaceName);
|
|
3786
|
+
const workspacePath = path17.join(workspaceRoot, ".rrce-workflow");
|
|
3878
3787
|
switch (mode) {
|
|
3879
3788
|
case "global":
|
|
3880
3789
|
return [globalPath];
|
|
@@ -3894,13 +3803,13 @@ var init_update_flow = __esm({
|
|
|
3894
3803
|
});
|
|
3895
3804
|
|
|
3896
3805
|
// src/commands/wizard/delete-flow.ts
|
|
3897
|
-
import { multiselect as multiselect5, confirm as
|
|
3898
|
-
import
|
|
3899
|
-
import * as
|
|
3806
|
+
import { multiselect as multiselect5, confirm as confirm9, spinner as spinner7, note as note12, cancel as cancel7, isCancel as isCancel11 } from "@clack/prompts";
|
|
3807
|
+
import pc14 from "picocolors";
|
|
3808
|
+
import * as fs19 from "fs";
|
|
3900
3809
|
async function runDeleteGlobalProjectFlow(availableProjects) {
|
|
3901
3810
|
const globalProjects = availableProjects.filter((p) => p.source === "global");
|
|
3902
3811
|
if (globalProjects.length === 0) {
|
|
3903
|
-
|
|
3812
|
+
note12("No globally stored projects found to delete.", "Info");
|
|
3904
3813
|
return;
|
|
3905
3814
|
}
|
|
3906
3815
|
const selectedProjects = await multiselect5({
|
|
@@ -3912,22 +3821,22 @@ async function runDeleteGlobalProjectFlow(availableProjects) {
|
|
|
3912
3821
|
})),
|
|
3913
3822
|
required: false
|
|
3914
3823
|
});
|
|
3915
|
-
if (
|
|
3916
|
-
|
|
3824
|
+
if (isCancel11(selectedProjects)) {
|
|
3825
|
+
cancel7("Deletion cancelled.");
|
|
3917
3826
|
return;
|
|
3918
3827
|
}
|
|
3919
3828
|
const projectsToDelete = selectedProjects;
|
|
3920
3829
|
if (projectsToDelete.length === 0) {
|
|
3921
|
-
|
|
3830
|
+
note12("No projects selected.", "Cancelled");
|
|
3922
3831
|
return;
|
|
3923
3832
|
}
|
|
3924
|
-
const confirmed = await
|
|
3925
|
-
message: `${
|
|
3833
|
+
const confirmed = await confirm9({
|
|
3834
|
+
message: `${pc14.red("WARNING:")} This will PERMANENTLY DELETE the knowledge/config for ${projectsToDelete.length} detected global projects.
|
|
3926
3835
|
Are you sure?`,
|
|
3927
3836
|
initialValue: false
|
|
3928
3837
|
});
|
|
3929
|
-
if (!confirmed ||
|
|
3930
|
-
|
|
3838
|
+
if (!confirmed || isCancel11(confirmed)) {
|
|
3839
|
+
cancel7("Deletion cancelled.");
|
|
3931
3840
|
return;
|
|
3932
3841
|
}
|
|
3933
3842
|
const s = spinner7();
|
|
@@ -3938,8 +3847,8 @@ Are you sure?`,
|
|
|
3938
3847
|
for (const projectName of projectsToDelete) {
|
|
3939
3848
|
const project = globalProjects.find((p) => p.name === projectName);
|
|
3940
3849
|
if (!project) continue;
|
|
3941
|
-
if (
|
|
3942
|
-
|
|
3850
|
+
if (fs19.existsSync(project.dataPath)) {
|
|
3851
|
+
fs19.rmSync(project.dataPath, { recursive: true, force: true });
|
|
3943
3852
|
}
|
|
3944
3853
|
const newConfig = removeProjectConfig(mcpConfig, projectName);
|
|
3945
3854
|
configChanged = true;
|
|
@@ -3951,7 +3860,7 @@ Are you sure?`,
|
|
|
3951
3860
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
3952
3861
|
} catch (error) {
|
|
3953
3862
|
s.stop("Error occurred during deletion");
|
|
3954
|
-
|
|
3863
|
+
note12(`Failed to delete some projects: ${error}`, "Error");
|
|
3955
3864
|
}
|
|
3956
3865
|
}
|
|
3957
3866
|
var init_delete_flow = __esm({
|
|
@@ -3967,11 +3876,11 @@ var wizard_exports = {};
|
|
|
3967
3876
|
__export(wizard_exports, {
|
|
3968
3877
|
runWizard: () => runWizard
|
|
3969
3878
|
});
|
|
3970
|
-
import { intro as intro2, select as
|
|
3971
|
-
import
|
|
3972
|
-
import * as
|
|
3879
|
+
import { intro as intro2, select as select5, spinner as spinner8, note as note13, outro as outro7, isCancel as isCancel12 } from "@clack/prompts";
|
|
3880
|
+
import pc15 from "picocolors";
|
|
3881
|
+
import * as fs20 from "fs";
|
|
3973
3882
|
async function runWizard() {
|
|
3974
|
-
intro2(
|
|
3883
|
+
intro2(pc15.cyan(pc15.inverse(" RRCE-Workflow Setup ")));
|
|
3975
3884
|
const s = spinner8();
|
|
3976
3885
|
s.start("Detecting environment");
|
|
3977
3886
|
const workspacePath = detectWorkspaceRoot();
|
|
@@ -3987,9 +3896,9 @@ async function runWizard() {
|
|
|
3987
3896
|
}
|
|
3988
3897
|
await new Promise((r) => setTimeout(r, 800));
|
|
3989
3898
|
s.stop("Environment detected");
|
|
3990
|
-
|
|
3991
|
-
`Git User: ${
|
|
3992
|
-
Workspace: ${
|
|
3899
|
+
note13(
|
|
3900
|
+
`Git User: ${pc15.bold(gitUser || "(not found)")}
|
|
3901
|
+
Workspace: ${pc15.bold(workspaceName)}`,
|
|
3993
3902
|
"Context"
|
|
3994
3903
|
);
|
|
3995
3904
|
const detectedProjects = scanForProjects({
|
|
@@ -3997,11 +3906,11 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
3997
3906
|
workspacePath
|
|
3998
3907
|
});
|
|
3999
3908
|
const configFilePath = getConfigPath(workspacePath);
|
|
4000
|
-
let isAlreadyConfigured =
|
|
3909
|
+
let isAlreadyConfigured = fs20.existsSync(configFilePath);
|
|
4001
3910
|
let currentStorageMode = null;
|
|
4002
3911
|
if (isAlreadyConfigured) {
|
|
4003
3912
|
try {
|
|
4004
|
-
const configContent =
|
|
3913
|
+
const configContent = fs20.readFileSync(configFilePath, "utf-8");
|
|
4005
3914
|
const modeMatch = configContent.match(/mode:\s*(global|workspace)/);
|
|
4006
3915
|
currentStorageMode = modeMatch?.[1] ?? null;
|
|
4007
3916
|
} catch {
|
|
@@ -4018,7 +3927,7 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
4018
3927
|
}
|
|
4019
3928
|
}
|
|
4020
3929
|
const localDataPath = getLocalWorkspacePath(workspacePath);
|
|
4021
|
-
const hasLocalData =
|
|
3930
|
+
const hasLocalData = fs20.existsSync(localDataPath);
|
|
4022
3931
|
if (isAlreadyConfigured) {
|
|
4023
3932
|
const menuOptions = [];
|
|
4024
3933
|
menuOptions.push({
|
|
@@ -4050,11 +3959,11 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
4050
3959
|
menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
|
|
4051
3960
|
menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
|
|
4052
3961
|
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
4053
|
-
const action = await
|
|
3962
|
+
const action = await select5({
|
|
4054
3963
|
message: "This workspace is already configured. What would you like to do?",
|
|
4055
3964
|
options: menuOptions
|
|
4056
3965
|
});
|
|
4057
|
-
if (
|
|
3966
|
+
if (isCancel12(action) || action === "exit") {
|
|
4058
3967
|
outro7("Exited.");
|
|
4059
3968
|
process.exit(0);
|
|
4060
3969
|
}
|
|
@@ -4104,18 +4013,18 @@ init_wizard();
|
|
|
4104
4013
|
|
|
4105
4014
|
// src/commands/selector.ts
|
|
4106
4015
|
init_prompts();
|
|
4107
|
-
import { intro as intro3, select as
|
|
4108
|
-
import
|
|
4109
|
-
import * as
|
|
4016
|
+
import { intro as intro3, select as select6, note as note14, cancel as cancel9, isCancel as isCancel13, outro as outro8 } from "@clack/prompts";
|
|
4017
|
+
import pc16 from "picocolors";
|
|
4018
|
+
import * as path18 from "path";
|
|
4110
4019
|
async function runSelector() {
|
|
4111
|
-
const workspaceName =
|
|
4112
|
-
intro3(
|
|
4020
|
+
const workspaceName = path18.basename(process.cwd());
|
|
4021
|
+
intro3(pc16.cyan(pc16.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
4113
4022
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
4114
4023
|
if (prompts.length === 0) {
|
|
4115
|
-
|
|
4024
|
+
cancel9("No agents found. Run `rrce-workflow` to set up.");
|
|
4116
4025
|
process.exit(0);
|
|
4117
4026
|
}
|
|
4118
|
-
const selection = await
|
|
4027
|
+
const selection = await select6({
|
|
4119
4028
|
message: "Select an agent:",
|
|
4120
4029
|
options: [
|
|
4121
4030
|
{
|
|
@@ -4135,8 +4044,8 @@ async function runSelector() {
|
|
|
4135
4044
|
}))
|
|
4136
4045
|
]
|
|
4137
4046
|
});
|
|
4138
|
-
if (
|
|
4139
|
-
|
|
4047
|
+
if (isCancel13(selection)) {
|
|
4048
|
+
cancel9("Selection cancelled.");
|
|
4140
4049
|
process.exit(0);
|
|
4141
4050
|
}
|
|
4142
4051
|
if (selection === "mcp") {
|
|
@@ -4150,9 +4059,9 @@ async function runSelector() {
|
|
|
4150
4059
|
return;
|
|
4151
4060
|
}
|
|
4152
4061
|
const prompt = selection;
|
|
4153
|
-
|
|
4062
|
+
note14(
|
|
4154
4063
|
`Use this agent in your IDE by invoking:
|
|
4155
|
-
${
|
|
4064
|
+
${pc16.bold(pc16.cyan(`@${prompt.frontmatter.name}`))}`,
|
|
4156
4065
|
"Agent Selected"
|
|
4157
4066
|
);
|
|
4158
4067
|
outro8("Done");
|