rrce-workflow 0.3.0 → 0.3.1
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 +655 -588
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1099,6 +1099,149 @@ var init_prompts = __esm({
|
|
|
1099
1099
|
}
|
|
1100
1100
|
});
|
|
1101
1101
|
|
|
1102
|
+
// src/commands/wizard/utils.ts
|
|
1103
|
+
import * as fs7 from "fs";
|
|
1104
|
+
import * as path8 from "path";
|
|
1105
|
+
import * as os2 from "os";
|
|
1106
|
+
import { stringify } from "yaml";
|
|
1107
|
+
function getOpenCodeConfigPath() {
|
|
1108
|
+
return path8.join(os2.homedir(), ".config", "opencode", "opencode.json");
|
|
1109
|
+
}
|
|
1110
|
+
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
1111
|
+
for (const prompt of prompts) {
|
|
1112
|
+
const baseName = path8.basename(prompt.filePath, ".md");
|
|
1113
|
+
const targetName = baseName + extension;
|
|
1114
|
+
const targetPath = path8.join(targetDir, targetName);
|
|
1115
|
+
const content = fs7.readFileSync(prompt.filePath, "utf-8");
|
|
1116
|
+
fs7.writeFileSync(targetPath, content);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
function updateOpenCodeConfig(newAgents) {
|
|
1120
|
+
const opencodePath = path8.join(os2.homedir(), ".config", "opencode", "opencode.json");
|
|
1121
|
+
if (!fs7.existsSync(opencodePath)) {
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
try {
|
|
1125
|
+
const config = JSON.parse(fs7.readFileSync(opencodePath, "utf8"));
|
|
1126
|
+
if (!config.agents) {
|
|
1127
|
+
config.agents = {};
|
|
1128
|
+
}
|
|
1129
|
+
const existingAgentKeys = Object.keys(config.agents);
|
|
1130
|
+
const rrceKeys = existingAgentKeys.filter((key) => key.startsWith("rrce_"));
|
|
1131
|
+
for (const key of rrceKeys) {
|
|
1132
|
+
if (!newAgents[key]) {
|
|
1133
|
+
delete config.agents[key];
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
for (const [key, value] of Object.entries(newAgents)) {
|
|
1137
|
+
if (key.startsWith("rrce_")) {
|
|
1138
|
+
config.agents[key] = value;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
fs7.writeFileSync(opencodePath, JSON.stringify(config, null, 2));
|
|
1142
|
+
} catch (e) {
|
|
1143
|
+
console.error("Failed to update OpenCode config:", e);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
function convertToOpenCodeAgent(prompt, useFileReference = false, promptFilePath) {
|
|
1147
|
+
const { frontmatter, content } = prompt;
|
|
1148
|
+
const tools = {};
|
|
1149
|
+
const hostTools = ["read", "write", "edit", "bash", "grep", "glob", "webfetch", "terminalLastCommand", "task"];
|
|
1150
|
+
if (frontmatter.tools) {
|
|
1151
|
+
for (const tool of frontmatter.tools) {
|
|
1152
|
+
if (hostTools.includes(tool)) {
|
|
1153
|
+
tools[tool] = true;
|
|
1154
|
+
} else {
|
|
1155
|
+
tools[`rrce_${tool}`] = true;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
tools["webfetch"] = true;
|
|
1160
|
+
const mode = frontmatter.mode || "subagent";
|
|
1161
|
+
const invocationHint = mode === "primary" ? "" : " (Invoke via @rrce_*)";
|
|
1162
|
+
return {
|
|
1163
|
+
description: `${frontmatter.description}${invocationHint}`,
|
|
1164
|
+
mode,
|
|
1165
|
+
prompt: useFileReference && promptFilePath ? `{file:${promptFilePath}}` : content,
|
|
1166
|
+
tools
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
function copyDirRecursive(src, dest) {
|
|
1170
|
+
const entries = fs7.readdirSync(src, { withFileTypes: true });
|
|
1171
|
+
for (const entry of entries) {
|
|
1172
|
+
const srcPath = path8.join(src, entry.name);
|
|
1173
|
+
const destPath = path8.join(dest, entry.name);
|
|
1174
|
+
if (entry.isDirectory()) {
|
|
1175
|
+
ensureDir(destPath);
|
|
1176
|
+
copyDirRecursive(srcPath, destPath);
|
|
1177
|
+
} else {
|
|
1178
|
+
fs7.copyFileSync(srcPath, destPath);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
function clearDirectory(dirPath) {
|
|
1183
|
+
if (!fs7.existsSync(dirPath)) return;
|
|
1184
|
+
const entries = fs7.readdirSync(dirPath, { withFileTypes: true });
|
|
1185
|
+
for (const entry of entries) {
|
|
1186
|
+
if (entry.isFile()) {
|
|
1187
|
+
fs7.unlinkSync(path8.join(dirPath, entry.name));
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
function surgicalUpdateOpenCodeAgents(prompts, mode, dataPath) {
|
|
1192
|
+
if (mode === "global") {
|
|
1193
|
+
try {
|
|
1194
|
+
const openCodeConfig = getOpenCodeConfigPath();
|
|
1195
|
+
const promptsDir = path8.join(path8.dirname(openCodeConfig), "prompts");
|
|
1196
|
+
ensureDir(promptsDir);
|
|
1197
|
+
const newAgents = {};
|
|
1198
|
+
for (const prompt of prompts) {
|
|
1199
|
+
const baseName = path8.basename(prompt.filePath, ".md");
|
|
1200
|
+
const agentId = `rrce_${baseName}`;
|
|
1201
|
+
const promptFileName = `rrce-${baseName}.md`;
|
|
1202
|
+
const promptFilePath = path8.join(promptsDir, promptFileName);
|
|
1203
|
+
fs7.writeFileSync(promptFilePath, prompt.content);
|
|
1204
|
+
const agentConfig = convertToOpenCodeAgent(prompt, true, `./prompts/${promptFileName}`);
|
|
1205
|
+
newAgents[agentId] = agentConfig;
|
|
1206
|
+
}
|
|
1207
|
+
updateOpenCodeConfig(newAgents);
|
|
1208
|
+
if (fs7.existsSync(openCodeConfig)) {
|
|
1209
|
+
const config = JSON.parse(fs7.readFileSync(openCodeConfig, "utf8"));
|
|
1210
|
+
if (!config.agents) config.agents = {};
|
|
1211
|
+
if (!config.agents.plan) config.agents.plan = {};
|
|
1212
|
+
config.agents.plan.disable = true;
|
|
1213
|
+
fs7.writeFileSync(openCodeConfig, JSON.stringify(config, null, 2));
|
|
1214
|
+
}
|
|
1215
|
+
} catch (e) {
|
|
1216
|
+
console.error("Failed to update global OpenCode config with agents:", e);
|
|
1217
|
+
throw e;
|
|
1218
|
+
}
|
|
1219
|
+
} else {
|
|
1220
|
+
const opencodeBaseDir = path8.join(dataPath, ".opencode", "agent");
|
|
1221
|
+
ensureDir(opencodeBaseDir);
|
|
1222
|
+
clearDirectory(opencodeBaseDir);
|
|
1223
|
+
for (const prompt of prompts) {
|
|
1224
|
+
const baseName = path8.basename(prompt.filePath, ".md");
|
|
1225
|
+
const agentId = `rrce_${baseName}`;
|
|
1226
|
+
const agentConfig = convertToOpenCodeAgent(prompt);
|
|
1227
|
+
const content = `---
|
|
1228
|
+
${stringify({
|
|
1229
|
+
description: agentConfig.description,
|
|
1230
|
+
mode: agentConfig.mode,
|
|
1231
|
+
tools: agentConfig.tools
|
|
1232
|
+
})}---
|
|
1233
|
+
${agentConfig.prompt}`;
|
|
1234
|
+
fs7.writeFileSync(path8.join(opencodeBaseDir, `${agentId}.md`), content);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
var init_utils = __esm({
|
|
1239
|
+
"src/commands/wizard/utils.ts"() {
|
|
1240
|
+
"use strict";
|
|
1241
|
+
init_paths();
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
|
|
1102
1245
|
// src/mcp/types.ts
|
|
1103
1246
|
var DEFAULT_MCP_CONFIG, DEFAULT_PERMISSIONS;
|
|
1104
1247
|
var init_types = __esm({
|
|
@@ -5364,131 +5507,356 @@ var init_mcp = __esm({
|
|
|
5364
5507
|
}
|
|
5365
5508
|
});
|
|
5366
5509
|
|
|
5367
|
-
// src/commands/wizard/
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
import
|
|
5374
|
-
|
|
5510
|
+
// src/commands/wizard/update-flow.ts
|
|
5511
|
+
var update_flow_exports = {};
|
|
5512
|
+
__export(update_flow_exports, {
|
|
5513
|
+
runUpdateFlow: () => runUpdateFlow
|
|
5514
|
+
});
|
|
5515
|
+
import { confirm as confirm5, spinner as spinner2, note as note6, outro as outro2, cancel as cancel2, isCancel as isCancel7 } from "@clack/prompts";
|
|
5516
|
+
import pc8 from "picocolors";
|
|
5517
|
+
import * as fs21 from "fs";
|
|
5518
|
+
import * as path22 from "path";
|
|
5519
|
+
import { stringify as stringify2, parse } from "yaml";
|
|
5520
|
+
function backupFile(filePath) {
|
|
5521
|
+
if (!fs21.existsSync(filePath)) return null;
|
|
5522
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T")[0] + "-" + Date.now();
|
|
5523
|
+
const backupPath = `${filePath}.${timestamp}.bak`;
|
|
5375
5524
|
try {
|
|
5376
|
-
|
|
5377
|
-
return
|
|
5378
|
-
} catch {
|
|
5525
|
+
fs21.copyFileSync(filePath, backupPath);
|
|
5526
|
+
return backupPath;
|
|
5527
|
+
} catch (e) {
|
|
5528
|
+
console.error(`Failed to backup ${filePath}:`, e);
|
|
5379
5529
|
return null;
|
|
5380
5530
|
}
|
|
5381
5531
|
}
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
init_detection();
|
|
5391
|
-
init_tui_utils();
|
|
5392
|
-
init_install();
|
|
5393
|
-
|
|
5394
|
-
// src/commands/wizard/setup-prompts.ts
|
|
5395
|
-
init_install();
|
|
5396
|
-
import { select as select2, multiselect, confirm, isCancel as isCancel2, cancel } from "@clack/prompts";
|
|
5397
|
-
import pc3 from "picocolors";
|
|
5398
|
-
async function promptStorageMode() {
|
|
5399
|
-
const result = await select2({
|
|
5400
|
-
message: "Where should workflow data be stored?",
|
|
5401
|
-
options: [
|
|
5402
|
-
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
|
|
5403
|
-
{ value: "workspace", label: "Workspace (.rrce-workflow/)", hint: "Self-contained, version with repo" }
|
|
5404
|
-
],
|
|
5405
|
-
initialValue: "global"
|
|
5406
|
-
});
|
|
5407
|
-
if (isCancel2(result)) {
|
|
5408
|
-
cancel("Setup cancelled.");
|
|
5409
|
-
process.exit(0);
|
|
5410
|
-
}
|
|
5411
|
-
return result;
|
|
5412
|
-
}
|
|
5413
|
-
async function promptTools() {
|
|
5414
|
-
const options = [];
|
|
5415
|
-
if (isOpenCodeInstalled()) {
|
|
5416
|
-
options.push({ value: "opencode", label: "OpenCode" });
|
|
5417
|
-
}
|
|
5418
|
-
if (isVSCodeInstalled()) {
|
|
5419
|
-
options.push({ value: "copilot", label: "GitHub Copilot", hint: "VSCode" });
|
|
5420
|
-
}
|
|
5421
|
-
if (isAntigravityInstalled()) {
|
|
5422
|
-
options.push({ value: "antigravity", label: "Antigravity IDE" });
|
|
5423
|
-
}
|
|
5424
|
-
if (options.length === 0) {
|
|
5425
|
-
options.push({ value: "none", label: "No supported IDEs detected", hint: "Skip" });
|
|
5426
|
-
}
|
|
5427
|
-
const result = await multiselect({
|
|
5428
|
-
message: "Which AI tools do you use?",
|
|
5429
|
-
options,
|
|
5430
|
-
required: false
|
|
5431
|
-
});
|
|
5432
|
-
if (isCancel2(result)) {
|
|
5433
|
-
cancel("Setup cancelled.");
|
|
5434
|
-
process.exit(0);
|
|
5435
|
-
}
|
|
5436
|
-
return result.filter((t) => t !== "none");
|
|
5437
|
-
}
|
|
5438
|
-
async function promptMCPExposure() {
|
|
5439
|
-
const result = await confirm({
|
|
5440
|
-
message: "Expose this project to MCP (AI Agent) server?",
|
|
5441
|
-
initialValue: true
|
|
5442
|
-
});
|
|
5443
|
-
if (isCancel2(result)) {
|
|
5444
|
-
cancel("Setup cancelled.");
|
|
5445
|
-
process.exit(0);
|
|
5446
|
-
}
|
|
5447
|
-
return result;
|
|
5448
|
-
}
|
|
5449
|
-
async function promptLinkedProjects(existingProjects) {
|
|
5450
|
-
if (existingProjects.length === 0) {
|
|
5451
|
-
return [];
|
|
5452
|
-
}
|
|
5453
|
-
const result = await multiselect({
|
|
5454
|
-
message: "Link knowledge from other projects?",
|
|
5455
|
-
options: existingProjects.map((project) => ({
|
|
5456
|
-
value: `${project.name}:${project.source}`,
|
|
5457
|
-
label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
|
|
5458
|
-
hint: pc3.dim(
|
|
5459
|
-
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
5460
|
-
)
|
|
5461
|
-
})),
|
|
5462
|
-
required: false
|
|
5463
|
-
});
|
|
5464
|
-
if (isCancel2(result)) {
|
|
5465
|
-
cancel("Setup cancelled.");
|
|
5466
|
-
process.exit(0);
|
|
5467
|
-
}
|
|
5468
|
-
return result;
|
|
5469
|
-
}
|
|
5470
|
-
async function promptGitignore() {
|
|
5471
|
-
const result = await confirm({
|
|
5472
|
-
message: "Add generated folders to .gitignore?",
|
|
5473
|
-
initialValue: true
|
|
5474
|
-
});
|
|
5475
|
-
if (isCancel2(result)) {
|
|
5476
|
-
cancel("Setup cancelled.");
|
|
5477
|
-
process.exit(0);
|
|
5532
|
+
function getPackageVersion2() {
|
|
5533
|
+
try {
|
|
5534
|
+
const agentCoreDir = getAgentCoreDir();
|
|
5535
|
+
const packageJsonPath = path22.join(path22.dirname(agentCoreDir), "package.json");
|
|
5536
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
5537
|
+
return JSON.parse(fs21.readFileSync(packageJsonPath, "utf8")).version;
|
|
5538
|
+
}
|
|
5539
|
+
} catch (e) {
|
|
5478
5540
|
}
|
|
5479
|
-
return
|
|
5541
|
+
return "0.0.0";
|
|
5480
5542
|
}
|
|
5481
|
-
async function
|
|
5482
|
-
const
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5543
|
+
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
5544
|
+
const s = spinner2();
|
|
5545
|
+
s.start("Checking for updates");
|
|
5546
|
+
try {
|
|
5547
|
+
const agentCoreDir = getAgentCoreDir();
|
|
5548
|
+
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
5549
|
+
const runningVersion = getPackageVersion2();
|
|
5550
|
+
const mode = currentStorageMode || "global";
|
|
5551
|
+
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
5552
|
+
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
5553
|
+
const configFilePath = getConfigPath(workspacePath);
|
|
5554
|
+
let currentSyncedVersion;
|
|
5555
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5556
|
+
try {
|
|
5557
|
+
const content = fs21.readFileSync(configFilePath, "utf-8");
|
|
5558
|
+
const config = parse(content);
|
|
5559
|
+
currentSyncedVersion = config.last_synced_version;
|
|
5560
|
+
} catch (e) {
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
const driftReport = DriftService.checkDrift(dataPaths[0], currentSyncedVersion, runningVersion);
|
|
5564
|
+
s.stop("Updates found");
|
|
5565
|
+
if (driftReport.type === "version") {
|
|
5566
|
+
note6(`New version available: ${pc8.green(runningVersion)} (Current synced: ${pc8.dim(currentSyncedVersion || "None")})`, "Update Available");
|
|
5567
|
+
}
|
|
5568
|
+
if (driftReport.modifiedFiles.length > 0) {
|
|
5569
|
+
note6(
|
|
5570
|
+
pc8.yellow(`The following files have been modified and will be backed up before updating:
|
|
5571
|
+
`) + driftReport.modifiedFiles.map((f) => ` \u2022 ${f}`).join("\n"),
|
|
5572
|
+
"Modifications Detected"
|
|
5573
|
+
);
|
|
5574
|
+
}
|
|
5575
|
+
const updateTargets = [
|
|
5576
|
+
` \u2022 prompts/ (${prompts.length} agent prompts)`,
|
|
5577
|
+
` \u2022 templates/ (output templates)`,
|
|
5578
|
+
` \u2022 docs/ (documentation)`
|
|
5579
|
+
];
|
|
5580
|
+
const ideTargets = [];
|
|
5581
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5582
|
+
const configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
5583
|
+
if (configContent.includes("opencode: true")) ideTargets.push("OpenCode agents");
|
|
5584
|
+
if (configContent.includes("copilot: true")) ideTargets.push("GitHub Copilot");
|
|
5585
|
+
if (configContent.includes("antigravity: true")) ideTargets.push("Antigravity");
|
|
5586
|
+
}
|
|
5587
|
+
if (ideTargets.length > 0) {
|
|
5588
|
+
updateTargets.push(` \u2022 IDE integrations: ${ideTargets.join(", ")}`);
|
|
5589
|
+
}
|
|
5590
|
+
note6(
|
|
5591
|
+
`The following will be updated from the package:
|
|
5592
|
+
${updateTargets.join("\n")}
|
|
5593
|
+
|
|
5594
|
+
Target locations:
|
|
5595
|
+
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
5596
|
+
"Update Preview"
|
|
5597
|
+
);
|
|
5598
|
+
const shouldUpdate = await confirm5({
|
|
5599
|
+
message: "Proceed with update?",
|
|
5600
|
+
initialValue: true
|
|
5601
|
+
});
|
|
5602
|
+
if (isCancel7(shouldUpdate) || !shouldUpdate) {
|
|
5603
|
+
outro2("Update cancelled.");
|
|
5604
|
+
return;
|
|
5605
|
+
}
|
|
5606
|
+
s.start("Updating from package");
|
|
5607
|
+
for (const dataPath of dataPaths) {
|
|
5608
|
+
const dirs = ["templates", "prompts", "docs"];
|
|
5609
|
+
const updatedFiles = [];
|
|
5610
|
+
for (const dir of dirs) {
|
|
5611
|
+
const srcDir = path22.join(agentCoreDir, dir);
|
|
5612
|
+
if (!fs21.existsSync(srcDir)) continue;
|
|
5613
|
+
const syncFiles = (src, rel) => {
|
|
5614
|
+
const entries = fs21.readdirSync(src, { withFileTypes: true });
|
|
5615
|
+
for (const entry of entries) {
|
|
5616
|
+
const entrySrc = path22.join(src, entry.name);
|
|
5617
|
+
const entryRel = path22.join(rel, entry.name);
|
|
5618
|
+
const entryDest = path22.join(dataPath, entryRel);
|
|
5619
|
+
if (entry.isDirectory()) {
|
|
5620
|
+
ensureDir(entryDest);
|
|
5621
|
+
syncFiles(entrySrc, entryRel);
|
|
5622
|
+
} else {
|
|
5623
|
+
if (driftReport.modifiedFiles.includes(entryRel)) {
|
|
5624
|
+
backupFile(entryDest);
|
|
5625
|
+
}
|
|
5626
|
+
fs21.copyFileSync(entrySrc, entryDest);
|
|
5627
|
+
updatedFiles.push(entryRel);
|
|
5628
|
+
}
|
|
5629
|
+
}
|
|
5630
|
+
};
|
|
5631
|
+
syncFiles(srcDir, dir);
|
|
5632
|
+
}
|
|
5633
|
+
const manifest = DriftService.generateManifest(dataPath, updatedFiles);
|
|
5634
|
+
DriftService.saveManifest(dataPath, manifest);
|
|
5635
|
+
}
|
|
5636
|
+
const rrceHome = customGlobalPath || getDefaultRRCEHome2();
|
|
5637
|
+
ensureDir(path22.join(rrceHome, "templates"));
|
|
5638
|
+
ensureDir(path22.join(rrceHome, "docs"));
|
|
5639
|
+
copyDirRecursive(path22.join(agentCoreDir, "templates"), path22.join(rrceHome, "templates"));
|
|
5640
|
+
copyDirRecursive(path22.join(agentCoreDir, "docs"), path22.join(rrceHome, "docs"));
|
|
5641
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5642
|
+
const configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
5643
|
+
if (configContent.includes("copilot: true")) {
|
|
5644
|
+
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
5645
|
+
ensureDir(copilotPath);
|
|
5646
|
+
clearDirectory(copilotPath);
|
|
5647
|
+
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
5648
|
+
}
|
|
5649
|
+
if (configContent.includes("antigravity: true")) {
|
|
5650
|
+
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
5651
|
+
ensureDir(antigravityPath);
|
|
5652
|
+
clearDirectory(antigravityPath);
|
|
5653
|
+
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
5654
|
+
}
|
|
5655
|
+
if (configContent.includes("opencode: true")) {
|
|
5656
|
+
const primaryDataPath = dataPaths[0];
|
|
5657
|
+
if (primaryDataPath) {
|
|
5658
|
+
surgicalUpdateOpenCodeAgents(prompts, mode, primaryDataPath);
|
|
5659
|
+
}
|
|
5660
|
+
}
|
|
5661
|
+
try {
|
|
5662
|
+
const yaml = parse(configContent);
|
|
5663
|
+
yaml.last_synced_version = runningVersion;
|
|
5664
|
+
fs21.writeFileSync(configFilePath, stringify2(yaml));
|
|
5665
|
+
} catch (e) {
|
|
5666
|
+
console.error("Failed to update config.yaml version:", e);
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
5669
|
+
const mcpPath = path22.join(rrceHome, "mcp.yaml");
|
|
5670
|
+
if (fs21.existsSync(mcpPath)) {
|
|
5671
|
+
try {
|
|
5672
|
+
const content = fs21.readFileSync(mcpPath, "utf-8");
|
|
5673
|
+
const yaml = parse(content);
|
|
5674
|
+
if (yaml.projects) {
|
|
5675
|
+
const project = yaml.projects.find((p) => p.name === workspaceName);
|
|
5676
|
+
if (project) {
|
|
5677
|
+
project.last_synced_version = runningVersion;
|
|
5678
|
+
fs21.writeFileSync(mcpPath, stringify2(yaml));
|
|
5679
|
+
}
|
|
5680
|
+
}
|
|
5681
|
+
} catch (e) {
|
|
5682
|
+
console.error("Failed to update mcp.yaml version:", e);
|
|
5683
|
+
}
|
|
5684
|
+
}
|
|
5685
|
+
s.stop("Update complete");
|
|
5686
|
+
const summary = [
|
|
5687
|
+
`Updated:`,
|
|
5688
|
+
` \u2713 ${prompts.length} agent prompts`,
|
|
5689
|
+
` \u2713 Output templates`,
|
|
5690
|
+
` \u2713 Documentation`
|
|
5691
|
+
];
|
|
5692
|
+
if (ideTargets.length > 0) {
|
|
5693
|
+
summary.push(` \u2713 IDE integrations: ${ideTargets.join(", ")}`);
|
|
5694
|
+
}
|
|
5695
|
+
if (driftReport.modifiedFiles.length > 0) {
|
|
5696
|
+
summary.push(` \u2713 ${driftReport.modifiedFiles.length} modified files backed up`);
|
|
5697
|
+
}
|
|
5698
|
+
summary.push(
|
|
5699
|
+
``,
|
|
5700
|
+
`Your configuration and knowledge files were preserved.`,
|
|
5701
|
+
``,
|
|
5702
|
+
pc8.dim(`\u{1F4A1} If using OpenCode, you may need to reload for changes to take effect.`)
|
|
5703
|
+
);
|
|
5704
|
+
note6(summary.join("\n"), "Update Summary");
|
|
5705
|
+
outro2(pc8.green("\u2713 Successfully updated from package!"));
|
|
5706
|
+
} catch (error) {
|
|
5707
|
+
s.stop("Error occurred");
|
|
5708
|
+
cancel2(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
5709
|
+
process.exit(1);
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5712
|
+
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
5713
|
+
const globalPath = path22.join(customGlobalPath, "workspaces", workspaceName);
|
|
5714
|
+
const workspacePath = path22.join(workspaceRoot, ".rrce-workflow");
|
|
5715
|
+
switch (mode) {
|
|
5716
|
+
case "global":
|
|
5717
|
+
return [globalPath];
|
|
5718
|
+
case "workspace":
|
|
5719
|
+
return [workspacePath];
|
|
5720
|
+
default:
|
|
5721
|
+
return [globalPath];
|
|
5722
|
+
}
|
|
5723
|
+
}
|
|
5724
|
+
var init_update_flow = __esm({
|
|
5725
|
+
"src/commands/wizard/update-flow.ts"() {
|
|
5726
|
+
"use strict";
|
|
5727
|
+
init_paths();
|
|
5728
|
+
init_prompts();
|
|
5729
|
+
init_utils();
|
|
5730
|
+
init_drift_service();
|
|
5731
|
+
}
|
|
5732
|
+
});
|
|
5733
|
+
|
|
5734
|
+
// src/commands/wizard/index.ts
|
|
5735
|
+
import { intro as intro2, select as select5, spinner as spinner7, note as note11, outro as outro7, isCancel as isCancel12 } from "@clack/prompts";
|
|
5736
|
+
import pc13 from "picocolors";
|
|
5737
|
+
import * as fs25 from "fs";
|
|
5738
|
+
|
|
5739
|
+
// src/lib/git.ts
|
|
5740
|
+
import { execSync } from "child_process";
|
|
5741
|
+
function getGitUser() {
|
|
5742
|
+
try {
|
|
5743
|
+
const result = execSync("git config user.name", { encoding: "utf-8" });
|
|
5744
|
+
return result.trim() || null;
|
|
5745
|
+
} catch {
|
|
5746
|
+
return null;
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
|
|
5750
|
+
// src/commands/wizard/index.ts
|
|
5751
|
+
init_paths();
|
|
5752
|
+
init_detection_service();
|
|
5753
|
+
|
|
5754
|
+
// src/commands/wizard/setup-flow.ts
|
|
5755
|
+
import { spinner as spinner3, note as note7, outro as outro3, cancel as cancel3, isCancel as isCancel8, confirm as confirm6, select as select3 } from "@clack/prompts";
|
|
5756
|
+
import pc9 from "picocolors";
|
|
5757
|
+
init_detection();
|
|
5758
|
+
init_tui_utils();
|
|
5759
|
+
init_install();
|
|
5760
|
+
init_paths();
|
|
5761
|
+
|
|
5762
|
+
// src/commands/wizard/setup-prompts.ts
|
|
5763
|
+
init_install();
|
|
5764
|
+
import { select as select2, multiselect, confirm, isCancel as isCancel2, cancel } from "@clack/prompts";
|
|
5765
|
+
import pc3 from "picocolors";
|
|
5766
|
+
async function promptStorageMode() {
|
|
5767
|
+
const result = await select2({
|
|
5768
|
+
message: "Where should workflow data be stored?",
|
|
5769
|
+
options: [
|
|
5770
|
+
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
|
|
5771
|
+
{ value: "workspace", label: "Workspace (.rrce-workflow/)", hint: "Self-contained, version with repo" }
|
|
5772
|
+
],
|
|
5773
|
+
initialValue: "global"
|
|
5774
|
+
});
|
|
5775
|
+
if (isCancel2(result)) {
|
|
5776
|
+
cancel("Setup cancelled.");
|
|
5777
|
+
process.exit(0);
|
|
5778
|
+
}
|
|
5779
|
+
return result;
|
|
5780
|
+
}
|
|
5781
|
+
async function promptTools() {
|
|
5782
|
+
const options = [];
|
|
5783
|
+
if (isOpenCodeInstalled()) {
|
|
5784
|
+
options.push({ value: "opencode", label: "OpenCode" });
|
|
5785
|
+
}
|
|
5786
|
+
if (isVSCodeInstalled()) {
|
|
5787
|
+
options.push({ value: "copilot", label: "GitHub Copilot", hint: "VSCode" });
|
|
5788
|
+
}
|
|
5789
|
+
if (isAntigravityInstalled()) {
|
|
5790
|
+
options.push({ value: "antigravity", label: "Antigravity IDE" });
|
|
5791
|
+
}
|
|
5792
|
+
if (options.length === 0) {
|
|
5793
|
+
options.push({ value: "none", label: "No supported IDEs detected", hint: "Skip" });
|
|
5794
|
+
}
|
|
5795
|
+
const result = await multiselect({
|
|
5796
|
+
message: "Which AI tools do you use?",
|
|
5797
|
+
options,
|
|
5798
|
+
required: false
|
|
5799
|
+
});
|
|
5800
|
+
if (isCancel2(result)) {
|
|
5801
|
+
cancel("Setup cancelled.");
|
|
5802
|
+
process.exit(0);
|
|
5803
|
+
}
|
|
5804
|
+
return result.filter((t) => t !== "none");
|
|
5805
|
+
}
|
|
5806
|
+
async function promptMCPExposure() {
|
|
5807
|
+
const result = await confirm({
|
|
5808
|
+
message: "Expose this project to MCP (AI Agent) server?",
|
|
5809
|
+
initialValue: true
|
|
5810
|
+
});
|
|
5811
|
+
if (isCancel2(result)) {
|
|
5812
|
+
cancel("Setup cancelled.");
|
|
5813
|
+
process.exit(0);
|
|
5814
|
+
}
|
|
5815
|
+
return result;
|
|
5816
|
+
}
|
|
5817
|
+
async function promptLinkedProjects(existingProjects) {
|
|
5818
|
+
if (existingProjects.length === 0) {
|
|
5819
|
+
return [];
|
|
5820
|
+
}
|
|
5821
|
+
const result = await multiselect({
|
|
5822
|
+
message: "Link knowledge from other projects?",
|
|
5823
|
+
options: existingProjects.map((project) => ({
|
|
5824
|
+
value: `${project.name}:${project.source}`,
|
|
5825
|
+
label: `${project.name} ${pc3.dim(`(${project.source})`)}`,
|
|
5826
|
+
hint: pc3.dim(
|
|
5827
|
+
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
5828
|
+
)
|
|
5829
|
+
})),
|
|
5830
|
+
required: false
|
|
5831
|
+
});
|
|
5832
|
+
if (isCancel2(result)) {
|
|
5833
|
+
cancel("Setup cancelled.");
|
|
5834
|
+
process.exit(0);
|
|
5835
|
+
}
|
|
5836
|
+
return result;
|
|
5837
|
+
}
|
|
5838
|
+
async function promptGitignore() {
|
|
5839
|
+
const result = await confirm({
|
|
5840
|
+
message: "Add generated folders to .gitignore?",
|
|
5841
|
+
initialValue: true
|
|
5842
|
+
});
|
|
5843
|
+
if (isCancel2(result)) {
|
|
5844
|
+
cancel("Setup cancelled.");
|
|
5845
|
+
process.exit(0);
|
|
5846
|
+
}
|
|
5847
|
+
return result;
|
|
5848
|
+
}
|
|
5849
|
+
async function promptRAG() {
|
|
5850
|
+
const result = await confirm({
|
|
5851
|
+
message: `Enable Semantic Search (Local Mini RAG)?
|
|
5852
|
+
${pc3.yellow("\u26A0 First use will download a ~100MB model")}`,
|
|
5853
|
+
initialValue: true
|
|
5854
|
+
});
|
|
5855
|
+
if (isCancel2(result)) {
|
|
5856
|
+
cancel("Setup cancelled.");
|
|
5857
|
+
process.exit(0);
|
|
5858
|
+
}
|
|
5859
|
+
return result;
|
|
5492
5860
|
}
|
|
5493
5861
|
async function promptConfirmation() {
|
|
5494
5862
|
const result = await confirm({
|
|
@@ -5505,90 +5873,11 @@ async function promptConfirmation() {
|
|
|
5505
5873
|
// src/commands/wizard/setup-actions.ts
|
|
5506
5874
|
init_paths();
|
|
5507
5875
|
init_prompts();
|
|
5876
|
+
init_utils();
|
|
5508
5877
|
import * as fs10 from "fs";
|
|
5509
5878
|
import * as path12 from "path";
|
|
5510
5879
|
import pc4 from "picocolors";
|
|
5511
5880
|
import { note as note2 } from "@clack/prompts";
|
|
5512
|
-
import { stringify as stringify2 } from "yaml";
|
|
5513
|
-
|
|
5514
|
-
// src/commands/wizard/utils.ts
|
|
5515
|
-
init_paths();
|
|
5516
|
-
import * as fs7 from "fs";
|
|
5517
|
-
import * as path8 from "path";
|
|
5518
|
-
import * as os2 from "os";
|
|
5519
|
-
import "yaml";
|
|
5520
|
-
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
5521
|
-
for (const prompt of prompts) {
|
|
5522
|
-
const baseName = path8.basename(prompt.filePath, ".md");
|
|
5523
|
-
const targetName = baseName + extension;
|
|
5524
|
-
const targetPath = path8.join(targetDir, targetName);
|
|
5525
|
-
const content = fs7.readFileSync(prompt.filePath, "utf-8");
|
|
5526
|
-
fs7.writeFileSync(targetPath, content);
|
|
5527
|
-
}
|
|
5528
|
-
}
|
|
5529
|
-
function updateOpenCodeConfig(newAgents) {
|
|
5530
|
-
const opencodePath = path8.join(os2.homedir(), ".config", "opencode", "opencode.json");
|
|
5531
|
-
if (!fs7.existsSync(opencodePath)) {
|
|
5532
|
-
return;
|
|
5533
|
-
}
|
|
5534
|
-
try {
|
|
5535
|
-
const config = JSON.parse(fs7.readFileSync(opencodePath, "utf8"));
|
|
5536
|
-
if (!config.agents) {
|
|
5537
|
-
config.agents = {};
|
|
5538
|
-
}
|
|
5539
|
-
const existingAgentKeys = Object.keys(config.agents);
|
|
5540
|
-
const rrceKeys = existingAgentKeys.filter((key) => key.startsWith("rrce_"));
|
|
5541
|
-
for (const key of rrceKeys) {
|
|
5542
|
-
if (!newAgents[key]) {
|
|
5543
|
-
delete config.agents[key];
|
|
5544
|
-
}
|
|
5545
|
-
}
|
|
5546
|
-
for (const [key, value] of Object.entries(newAgents)) {
|
|
5547
|
-
if (key.startsWith("rrce_")) {
|
|
5548
|
-
config.agents[key] = value;
|
|
5549
|
-
}
|
|
5550
|
-
}
|
|
5551
|
-
fs7.writeFileSync(opencodePath, JSON.stringify(config, null, 2));
|
|
5552
|
-
} catch (e) {
|
|
5553
|
-
console.error("Failed to update OpenCode config:", e);
|
|
5554
|
-
}
|
|
5555
|
-
}
|
|
5556
|
-
function convertToOpenCodeAgent(prompt, useFileReference = false, promptFilePath) {
|
|
5557
|
-
const { frontmatter, content } = prompt;
|
|
5558
|
-
const tools = {};
|
|
5559
|
-
const hostTools = ["read", "write", "edit", "bash", "grep", "glob", "webfetch", "terminalLastCommand", "task"];
|
|
5560
|
-
if (frontmatter.tools) {
|
|
5561
|
-
for (const tool of frontmatter.tools) {
|
|
5562
|
-
if (hostTools.includes(tool)) {
|
|
5563
|
-
tools[tool] = true;
|
|
5564
|
-
} else {
|
|
5565
|
-
tools[`rrce_${tool}`] = true;
|
|
5566
|
-
}
|
|
5567
|
-
}
|
|
5568
|
-
}
|
|
5569
|
-
tools["webfetch"] = true;
|
|
5570
|
-
const mode = frontmatter.mode || "subagent";
|
|
5571
|
-
const invocationHint = mode === "primary" ? "" : " (Invoke via @rrce_*)";
|
|
5572
|
-
return {
|
|
5573
|
-
description: `${frontmatter.description}${invocationHint}`,
|
|
5574
|
-
mode,
|
|
5575
|
-
prompt: useFileReference && promptFilePath ? `{file:${promptFilePath}}` : content,
|
|
5576
|
-
tools
|
|
5577
|
-
};
|
|
5578
|
-
}
|
|
5579
|
-
function copyDirRecursive(src, dest) {
|
|
5580
|
-
const entries = fs7.readdirSync(src, { withFileTypes: true });
|
|
5581
|
-
for (const entry of entries) {
|
|
5582
|
-
const srcPath = path8.join(src, entry.name);
|
|
5583
|
-
const destPath = path8.join(dest, entry.name);
|
|
5584
|
-
if (entry.isDirectory()) {
|
|
5585
|
-
ensureDir(destPath);
|
|
5586
|
-
copyDirRecursive(srcPath, destPath);
|
|
5587
|
-
} else {
|
|
5588
|
-
fs7.copyFileSync(srcPath, destPath);
|
|
5589
|
-
}
|
|
5590
|
-
}
|
|
5591
|
-
}
|
|
5592
5881
|
|
|
5593
5882
|
// src/commands/wizard/vscode.ts
|
|
5594
5883
|
init_paths();
|
|
@@ -5677,6 +5966,46 @@ function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, c
|
|
|
5677
5966
|
|
|
5678
5967
|
// src/commands/wizard/setup-actions.ts
|
|
5679
5968
|
init_install();
|
|
5969
|
+
function detectExistingProject(workspacePath, workspaceName, globalPath) {
|
|
5970
|
+
const rrceHome = globalPath || getDefaultRRCEHome2();
|
|
5971
|
+
const globalConfigPath = path12.join(rrceHome, "workspaces", workspaceName, "config.yaml");
|
|
5972
|
+
const workspaceConfigPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
5973
|
+
const hasOpenCodeAgents = checkForRRCEAgents();
|
|
5974
|
+
if (fs10.existsSync(globalConfigPath)) {
|
|
5975
|
+
return {
|
|
5976
|
+
isExisting: true,
|
|
5977
|
+
currentMode: "global",
|
|
5978
|
+
configPath: globalConfigPath
|
|
5979
|
+
};
|
|
5980
|
+
} else if (fs10.existsSync(workspaceConfigPath)) {
|
|
5981
|
+
return {
|
|
5982
|
+
isExisting: true,
|
|
5983
|
+
currentMode: "workspace",
|
|
5984
|
+
configPath: workspaceConfigPath
|
|
5985
|
+
};
|
|
5986
|
+
} else if (hasOpenCodeAgents) {
|
|
5987
|
+
return {
|
|
5988
|
+
isExisting: true,
|
|
5989
|
+
currentMode: null,
|
|
5990
|
+
configPath: null
|
|
5991
|
+
};
|
|
5992
|
+
}
|
|
5993
|
+
return {
|
|
5994
|
+
isExisting: false,
|
|
5995
|
+
currentMode: null,
|
|
5996
|
+
configPath: null
|
|
5997
|
+
};
|
|
5998
|
+
}
|
|
5999
|
+
function checkForRRCEAgents() {
|
|
6000
|
+
if (!fs10.existsSync(OPENCODE_CONFIG)) return false;
|
|
6001
|
+
try {
|
|
6002
|
+
const config = JSON.parse(fs10.readFileSync(OPENCODE_CONFIG, "utf8"));
|
|
6003
|
+
const agentKeys = Object.keys(config.agent || config.agents || {});
|
|
6004
|
+
return agentKeys.some((key) => key.startsWith("rrce_"));
|
|
6005
|
+
} catch {
|
|
6006
|
+
return false;
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
5680
6009
|
function createDirectoryStructure(dataPaths) {
|
|
5681
6010
|
for (const dataPath of dataPaths) {
|
|
5682
6011
|
ensureDir(dataPath);
|
|
@@ -5712,51 +6041,10 @@ async function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
|
5712
6041
|
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
5713
6042
|
}
|
|
5714
6043
|
}
|
|
5715
|
-
if (config.tools.includes("opencode")) {
|
|
5716
|
-
const primaryDataPath = dataPaths[0];
|
|
5717
|
-
if (primaryDataPath) {
|
|
5718
|
-
|
|
5719
|
-
try {
|
|
5720
|
-
const promptsDir = path12.join(path12.dirname(OPENCODE_CONFIG), "prompts");
|
|
5721
|
-
ensureDir(promptsDir);
|
|
5722
|
-
let opencodeConfig = { $schema: "https://opencode.ai/config.json" };
|
|
5723
|
-
if (fs10.existsSync(OPENCODE_CONFIG)) {
|
|
5724
|
-
opencodeConfig = JSON.parse(fs10.readFileSync(OPENCODE_CONFIG, "utf-8"));
|
|
5725
|
-
}
|
|
5726
|
-
if (!opencodeConfig.agent) opencodeConfig.agent = {};
|
|
5727
|
-
for (const prompt of prompts) {
|
|
5728
|
-
const baseName = path12.basename(prompt.filePath, ".md");
|
|
5729
|
-
const agentId = `rrce_${baseName}`;
|
|
5730
|
-
const promptFileName = `rrce-${baseName}.md`;
|
|
5731
|
-
const promptFilePath = path12.join(promptsDir, promptFileName);
|
|
5732
|
-
fs10.writeFileSync(promptFilePath, prompt.content);
|
|
5733
|
-
const agentConfig = convertToOpenCodeAgent(prompt, true, `./prompts/${promptFileName}`);
|
|
5734
|
-
opencodeConfig.agent[agentId] = agentConfig;
|
|
5735
|
-
}
|
|
5736
|
-
if (!opencodeConfig.agent) opencodeConfig.agent = {};
|
|
5737
|
-
if (!opencodeConfig.agent.plan) opencodeConfig.agent.plan = {};
|
|
5738
|
-
opencodeConfig.agent.plan.disable = true;
|
|
5739
|
-
fs10.writeFileSync(OPENCODE_CONFIG, JSON.stringify(opencodeConfig, null, 2) + "\n");
|
|
5740
|
-
} catch (e) {
|
|
5741
|
-
console.error("Failed to update global OpenCode config with agents:", e);
|
|
5742
|
-
}
|
|
5743
|
-
} else {
|
|
5744
|
-
const opencodeBaseDir = path12.join(primaryDataPath, ".opencode", "agent");
|
|
5745
|
-
ensureDir(opencodeBaseDir);
|
|
5746
|
-
for (const prompt of prompts) {
|
|
5747
|
-
const baseName = path12.basename(prompt.filePath, ".md");
|
|
5748
|
-
const agentId = `rrce_${baseName}`;
|
|
5749
|
-
const agentConfig = convertToOpenCodeAgent(prompt);
|
|
5750
|
-
const content = `---
|
|
5751
|
-
${stringify2({
|
|
5752
|
-
description: agentConfig.description,
|
|
5753
|
-
mode: agentConfig.mode,
|
|
5754
|
-
tools: agentConfig.tools
|
|
5755
|
-
})}---
|
|
5756
|
-
${agentConfig.prompt}`;
|
|
5757
|
-
fs10.writeFileSync(path12.join(opencodeBaseDir, `${agentId}.md`), content);
|
|
5758
|
-
}
|
|
5759
|
-
}
|
|
6044
|
+
if (config.tools.includes("opencode")) {
|
|
6045
|
+
const primaryDataPath = dataPaths[0];
|
|
6046
|
+
if (primaryDataPath) {
|
|
6047
|
+
surgicalUpdateOpenCodeAgents(prompts, config.storageMode, primaryDataPath);
|
|
5760
6048
|
}
|
|
5761
6049
|
}
|
|
5762
6050
|
}
|
|
@@ -5882,8 +6170,8 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5882
6170
|
],
|
|
5883
6171
|
initialValue: "global"
|
|
5884
6172
|
});
|
|
5885
|
-
if (
|
|
5886
|
-
|
|
6173
|
+
if (isCancel8(storageModeResult)) {
|
|
6174
|
+
cancel3("Setup cancelled.");
|
|
5887
6175
|
process.exit(0);
|
|
5888
6176
|
}
|
|
5889
6177
|
const storageMode = storageModeResult;
|
|
@@ -5891,7 +6179,7 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5891
6179
|
if (storageMode === "global") {
|
|
5892
6180
|
customGlobalPath = await resolveGlobalPath();
|
|
5893
6181
|
if (!customGlobalPath) {
|
|
5894
|
-
|
|
6182
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
5895
6183
|
process.exit(0);
|
|
5896
6184
|
}
|
|
5897
6185
|
}
|
|
@@ -5900,8 +6188,8 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5900
6188
|
if (isVSCodeInstalled()) toolsPreview.push("GitHub Copilot");
|
|
5901
6189
|
if (isAntigravityInstalled()) toolsPreview.push("Antigravity");
|
|
5902
6190
|
const toolsText = toolsPreview.length > 0 ? toolsPreview.join(", ") : "None detected";
|
|
5903
|
-
|
|
5904
|
-
`${
|
|
6191
|
+
note7(
|
|
6192
|
+
`${pc9.bold("Express Setup will configure:")}
|
|
5905
6193
|
\u2022 Storage: ${storageMode === "global" ? "Global" : "Workspace"}
|
|
5906
6194
|
\u2022 MCP Server: Enabled
|
|
5907
6195
|
\u2022 Semantic Search (RAG): Enabled
|
|
@@ -5909,12 +6197,12 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5909
6197
|
` : "") + `\u2022 AI Tools: ${toolsText}`,
|
|
5910
6198
|
"Configuration Preview"
|
|
5911
6199
|
);
|
|
5912
|
-
const confirmed = await
|
|
6200
|
+
const confirmed = await confirm6({
|
|
5913
6201
|
message: "Proceed with express setup?",
|
|
5914
6202
|
initialValue: true
|
|
5915
6203
|
});
|
|
5916
|
-
if (
|
|
5917
|
-
|
|
6204
|
+
if (isCancel8(confirmed) || !confirmed) {
|
|
6205
|
+
cancel3("Setup cancelled.");
|
|
5918
6206
|
process.exit(0);
|
|
5919
6207
|
}
|
|
5920
6208
|
const defaultTools = [];
|
|
@@ -5935,19 +6223,63 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5935
6223
|
const { updateGitignore: updateGitignore2 } = await Promise.resolve().then(() => (init_gitignore(), gitignore_exports));
|
|
5936
6224
|
updateGitignore2(workspacePath, config.storageMode, config.tools);
|
|
5937
6225
|
}
|
|
5938
|
-
const startMCP = await
|
|
6226
|
+
const startMCP = await confirm6({
|
|
6227
|
+
message: "Start MCP server now?",
|
|
6228
|
+
initialValue: true
|
|
6229
|
+
});
|
|
6230
|
+
if (startMCP && !isCancel8(startMCP)) {
|
|
6231
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6232
|
+
await runMCP2();
|
|
6233
|
+
} else {
|
|
6234
|
+
outro3(pc9.green(`\u2713 Express setup complete! Run ${pc9.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
6235
|
+
}
|
|
6236
|
+
}
|
|
6237
|
+
async function runSetupAsUpdate(workspacePath, workspaceName, currentMode) {
|
|
6238
|
+
let mode = currentMode;
|
|
6239
|
+
if (!mode) {
|
|
6240
|
+
const modeResult = await select3({
|
|
6241
|
+
message: "Storage mode not detected. Please confirm:",
|
|
6242
|
+
options: [
|
|
6243
|
+
{ value: "global", label: "Global (~/.rrce-workflow/)" },
|
|
6244
|
+
{ value: "workspace", label: "Workspace (.rrce-workflow/)" }
|
|
6245
|
+
],
|
|
6246
|
+
initialValue: "global"
|
|
6247
|
+
});
|
|
6248
|
+
if (isCancel8(modeResult)) {
|
|
6249
|
+
cancel3("Setup cancelled.");
|
|
6250
|
+
process.exit(0);
|
|
6251
|
+
}
|
|
6252
|
+
mode = modeResult;
|
|
6253
|
+
}
|
|
6254
|
+
const { runUpdateFlow: runUpdateFlow2 } = await Promise.resolve().then(() => (init_update_flow(), update_flow_exports));
|
|
6255
|
+
await runUpdateFlow2(workspacePath, workspaceName, mode);
|
|
6256
|
+
const startMCP = await confirm6({
|
|
5939
6257
|
message: "Start MCP server now?",
|
|
5940
6258
|
initialValue: true
|
|
5941
6259
|
});
|
|
5942
|
-
if (startMCP && !
|
|
6260
|
+
if (startMCP && !isCancel8(startMCP)) {
|
|
5943
6261
|
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
5944
6262
|
await runMCP2();
|
|
5945
6263
|
} else {
|
|
5946
|
-
|
|
6264
|
+
outro3(pc9.green(`\u2713 Setup complete! Run ${pc9.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
5947
6265
|
}
|
|
5948
6266
|
}
|
|
5949
6267
|
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
5950
|
-
const
|
|
6268
|
+
const customGlobalPath = getDefaultRRCEHome2();
|
|
6269
|
+
const existingProjectInfo = detectExistingProject(workspacePath, workspaceName, customGlobalPath);
|
|
6270
|
+
if (existingProjectInfo.isExisting) {
|
|
6271
|
+
note7(
|
|
6272
|
+
`${pc9.cyan("\u2139")} Existing RRCE installation detected.
|
|
6273
|
+
Running smart update to sync with latest version.`,
|
|
6274
|
+
"Update Mode"
|
|
6275
|
+
);
|
|
6276
|
+
return runSetupAsUpdate(
|
|
6277
|
+
workspacePath,
|
|
6278
|
+
workspaceName,
|
|
6279
|
+
existingProjectInfo.currentMode
|
|
6280
|
+
);
|
|
6281
|
+
}
|
|
6282
|
+
const s = spinner3();
|
|
5951
6283
|
const setupModeResult = await select3({
|
|
5952
6284
|
message: "Setup mode:",
|
|
5953
6285
|
options: [
|
|
@@ -5956,19 +6288,19 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
5956
6288
|
],
|
|
5957
6289
|
initialValue: "express"
|
|
5958
6290
|
});
|
|
5959
|
-
if (
|
|
5960
|
-
|
|
6291
|
+
if (isCancel8(setupModeResult)) {
|
|
6292
|
+
cancel3("Setup cancelled.");
|
|
5961
6293
|
process.exit(0);
|
|
5962
6294
|
}
|
|
5963
6295
|
if (setupModeResult === "express") {
|
|
5964
6296
|
return runExpressSetup(workspacePath, workspaceName, existingProjects, s);
|
|
5965
6297
|
}
|
|
5966
6298
|
const storageMode = await promptStorageMode();
|
|
5967
|
-
let
|
|
6299
|
+
let resolvedGlobalPath;
|
|
5968
6300
|
if (storageMode === "global") {
|
|
5969
|
-
|
|
5970
|
-
if (!
|
|
5971
|
-
|
|
6301
|
+
resolvedGlobalPath = await resolveGlobalPath();
|
|
6302
|
+
if (!resolvedGlobalPath) {
|
|
6303
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
5972
6304
|
process.exit(0);
|
|
5973
6305
|
}
|
|
5974
6306
|
}
|
|
@@ -5982,12 +6314,12 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
5982
6314
|
const enableRAG = await promptRAG();
|
|
5983
6315
|
const confirmed = await promptConfirmation();
|
|
5984
6316
|
if (!confirmed) {
|
|
5985
|
-
|
|
6317
|
+
outro3("Setup cancelled by user.");
|
|
5986
6318
|
process.exit(0);
|
|
5987
6319
|
}
|
|
5988
6320
|
const config = {
|
|
5989
6321
|
storageMode,
|
|
5990
|
-
globalPath:
|
|
6322
|
+
globalPath: resolvedGlobalPath,
|
|
5991
6323
|
tools,
|
|
5992
6324
|
linkedProjects,
|
|
5993
6325
|
addToGitignore,
|
|
@@ -6024,59 +6356,59 @@ async function executeSetup(config, workspacePath, workspaceName, allProjects, s
|
|
|
6024
6356
|
s.stop("Configuration generated");
|
|
6025
6357
|
const dataSummary = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
6026
6358
|
const summary = [
|
|
6027
|
-
`${
|
|
6028
|
-
config.tools.length > 0 ? `${
|
|
6029
|
-
config.exposeToMCP ? `${
|
|
6030
|
-
config.enableRAG ? `${
|
|
6031
|
-
config.linkedProjects.length > 0 ? `${
|
|
6032
|
-
ideResults.success.length > 0 ? `${
|
|
6033
|
-
ideResults.failed.length > 0 ? `${
|
|
6359
|
+
`${pc9.green("\u2713")} Data stored at: ${pc9.dim(dataSummary[0])}`,
|
|
6360
|
+
config.tools.length > 0 ? `${pc9.green("\u2713")} Tools: ${config.tools.join(", ")}` : null,
|
|
6361
|
+
config.exposeToMCP ? `${pc9.green("\u2713")} MCP server configured` : null,
|
|
6362
|
+
config.enableRAG ? `${pc9.green("\u2713")} Semantic Search enabled` : null,
|
|
6363
|
+
config.linkedProjects.length > 0 ? `${pc9.green("\u2713")} Linked ${config.linkedProjects.length} project(s)` : null,
|
|
6364
|
+
ideResults.success.length > 0 ? `${pc9.green("\u2713")} RRCE installed to: ${ideResults.success.join(", ")}` : null,
|
|
6365
|
+
ideResults.failed.length > 0 ? `${pc9.yellow("\u26A0")} Failed to install to: ${ideResults.failed.join(", ")}` : null
|
|
6034
6366
|
].filter(Boolean);
|
|
6035
6367
|
if (ideResults.success.length > 0) {
|
|
6036
6368
|
summary.push("");
|
|
6037
|
-
summary.push(
|
|
6369
|
+
summary.push(pc9.dim("\u{1F4A1} You may need to restart your IDE or refresh MCP config for changes to take effect."));
|
|
6038
6370
|
}
|
|
6039
|
-
|
|
6371
|
+
note7(summary.join("\n"), "Setup Complete");
|
|
6040
6372
|
} catch (error) {
|
|
6041
6373
|
s.stop("Error occurred");
|
|
6042
|
-
|
|
6374
|
+
cancel3(
|
|
6043
6375
|
`Setup failed: ${error instanceof Error ? error.message : String(error)}
|
|
6044
6376
|
|
|
6045
|
-
${
|
|
6377
|
+
${pc9.dim("Tip: You can re-run the wizard to try again.")}`
|
|
6046
6378
|
);
|
|
6047
6379
|
process.exit(1);
|
|
6048
6380
|
}
|
|
6049
6381
|
}
|
|
6050
6382
|
async function handlePostSetup(config, workspacePath, workspaceName, linkedProjects) {
|
|
6051
6383
|
if (config.exposeToMCP) {
|
|
6052
|
-
const shouldConfigureMCP = await
|
|
6384
|
+
const shouldConfigureMCP = await confirm6({
|
|
6053
6385
|
message: "Would you like to start the MCP server now?",
|
|
6054
6386
|
initialValue: true
|
|
6055
6387
|
});
|
|
6056
|
-
if (shouldConfigureMCP && !
|
|
6388
|
+
if (shouldConfigureMCP && !isCancel8(shouldConfigureMCP)) {
|
|
6057
6389
|
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6058
6390
|
await runMCP2();
|
|
6059
6391
|
} else {
|
|
6060
6392
|
if (linkedProjects.length > 0) {
|
|
6061
|
-
|
|
6393
|
+
outro3(pc9.green(`\u2713 Setup complete! Open ${pc9.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
6062
6394
|
} else {
|
|
6063
|
-
|
|
6395
|
+
outro3(pc9.green(`\u2713 Setup complete! Run ${pc9.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
6064
6396
|
}
|
|
6065
6397
|
}
|
|
6066
6398
|
} else {
|
|
6067
6399
|
if (linkedProjects.length > 0) {
|
|
6068
|
-
|
|
6400
|
+
outro3(pc9.green(`\u2713 Setup complete! Open ${pc9.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
6069
6401
|
} else {
|
|
6070
|
-
|
|
6402
|
+
outro3(pc9.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
6071
6403
|
}
|
|
6072
6404
|
}
|
|
6073
6405
|
}
|
|
6074
6406
|
|
|
6075
6407
|
// src/commands/wizard/link-flow.ts
|
|
6076
6408
|
init_paths();
|
|
6077
|
-
import { multiselect as multiselect4, spinner as
|
|
6078
|
-
import
|
|
6079
|
-
import * as
|
|
6409
|
+
import { multiselect as multiselect4, spinner as spinner4, note as note8, outro as outro4, cancel as cancel4, isCancel as isCancel9, confirm as confirm7 } from "@clack/prompts";
|
|
6410
|
+
import pc10 from "picocolors";
|
|
6411
|
+
import * as fs22 from "fs";
|
|
6080
6412
|
init_detection();
|
|
6081
6413
|
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
6082
6414
|
const projects = scanForProjects({
|
|
@@ -6084,7 +6416,7 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
6084
6416
|
workspacePath
|
|
6085
6417
|
});
|
|
6086
6418
|
if (projects.length === 0) {
|
|
6087
|
-
|
|
6419
|
+
outro4(pc10.yellow("No other projects found. Try setting up another project first."));
|
|
6088
6420
|
return;
|
|
6089
6421
|
}
|
|
6090
6422
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
@@ -6093,29 +6425,29 @@ async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
|
6093
6425
|
options: projects.map((project) => ({
|
|
6094
6426
|
value: `${project.name}:${project.source}`,
|
|
6095
6427
|
// Unique key
|
|
6096
|
-
label: `${project.name} ${
|
|
6097
|
-
hint:
|
|
6428
|
+
label: `${project.name} ${pc10.dim(`(${project.source})`)}`,
|
|
6429
|
+
hint: pc10.dim(
|
|
6098
6430
|
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
6099
6431
|
)
|
|
6100
6432
|
})),
|
|
6101
6433
|
required: true
|
|
6102
6434
|
});
|
|
6103
|
-
if (
|
|
6104
|
-
|
|
6435
|
+
if (isCancel9(linkedProjects)) {
|
|
6436
|
+
cancel4("Cancelled.");
|
|
6105
6437
|
process.exit(0);
|
|
6106
6438
|
}
|
|
6107
6439
|
const selectedKeys = linkedProjects;
|
|
6108
6440
|
if (selectedKeys.length === 0) {
|
|
6109
|
-
|
|
6441
|
+
outro4("No projects selected.");
|
|
6110
6442
|
return;
|
|
6111
6443
|
}
|
|
6112
6444
|
const selectedProjects = projects.filter(
|
|
6113
6445
|
(p) => selectedKeys.includes(`${p.name}:${p.source}`)
|
|
6114
6446
|
);
|
|
6115
|
-
const s =
|
|
6447
|
+
const s = spinner4();
|
|
6116
6448
|
s.start("Linking projects");
|
|
6117
6449
|
const configFilePath = getConfigPath(workspacePath);
|
|
6118
|
-
let configContent =
|
|
6450
|
+
let configContent = fs22.readFileSync(configFilePath, "utf-8");
|
|
6119
6451
|
if (configContent.includes("linked_projects:")) {
|
|
6120
6452
|
const lines = configContent.split("\n");
|
|
6121
6453
|
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
@@ -6142,23 +6474,23 @@ linked_projects:
|
|
|
6142
6474
|
`;
|
|
6143
6475
|
});
|
|
6144
6476
|
}
|
|
6145
|
-
|
|
6477
|
+
fs22.writeFileSync(configFilePath, configContent);
|
|
6146
6478
|
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
6147
6479
|
s.stop("Projects linked");
|
|
6148
6480
|
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
6149
6481
|
const summary = [
|
|
6150
6482
|
`Linked projects:`,
|
|
6151
|
-
...selectedProjects.map((p) => ` \u2713 ${p.name} ${
|
|
6483
|
+
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc10.dim(`(${p.source})`)}`),
|
|
6152
6484
|
``,
|
|
6153
|
-
`Workspace file: ${
|
|
6485
|
+
`Workspace file: ${pc10.cyan(workspaceFile)}`
|
|
6154
6486
|
];
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
const shouldExpose = await
|
|
6487
|
+
note8(summary.join("\n"), "Link Summary");
|
|
6488
|
+
outro4(pc10.green(`\u2713 Projects linked! Open ${pc10.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
6489
|
+
const shouldExpose = await confirm7({
|
|
6158
6490
|
message: "Also expose these linked projects to the MCP server (for Agent access)?",
|
|
6159
6491
|
initialValue: true
|
|
6160
6492
|
});
|
|
6161
|
-
if (shouldExpose && !
|
|
6493
|
+
if (shouldExpose && !isCancel9(shouldExpose)) {
|
|
6162
6494
|
try {
|
|
6163
6495
|
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6164
6496
|
const mcpConfig = loadMCPConfig3();
|
|
@@ -6166,53 +6498,54 @@ linked_projects:
|
|
|
6166
6498
|
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
6167
6499
|
}
|
|
6168
6500
|
saveMCPConfig2(mcpConfig);
|
|
6169
|
-
|
|
6501
|
+
note8("Projects have been added to the global MCP configuration.", "MCP Updated");
|
|
6170
6502
|
} catch (err) {
|
|
6171
|
-
|
|
6503
|
+
note8(`Failed to update MCP config: ${err}`, "MCP Update Failed");
|
|
6172
6504
|
}
|
|
6173
6505
|
}
|
|
6174
6506
|
}
|
|
6175
6507
|
|
|
6176
6508
|
// src/commands/wizard/sync-flow.ts
|
|
6177
6509
|
init_paths();
|
|
6178
|
-
|
|
6179
|
-
import
|
|
6180
|
-
import
|
|
6181
|
-
import * as
|
|
6510
|
+
init_utils();
|
|
6511
|
+
import { confirm as confirm8, spinner as spinner5, note as note9, outro as outro5, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
|
|
6512
|
+
import pc11 from "picocolors";
|
|
6513
|
+
import * as fs23 from "fs";
|
|
6514
|
+
import * as path23 from "path";
|
|
6182
6515
|
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
6183
6516
|
const localPath = getLocalWorkspacePath(workspacePath);
|
|
6184
6517
|
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
6185
|
-
const globalPath =
|
|
6518
|
+
const globalPath = path23.join(customGlobalPath, "workspaces", workspaceName);
|
|
6186
6519
|
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
6187
6520
|
const existingDirs = subdirs.filter(
|
|
6188
|
-
(dir) =>
|
|
6521
|
+
(dir) => fs23.existsSync(path23.join(localPath, dir))
|
|
6189
6522
|
);
|
|
6190
6523
|
if (existingDirs.length === 0) {
|
|
6191
|
-
|
|
6524
|
+
outro5(pc11.yellow("No data found in workspace storage to sync."));
|
|
6192
6525
|
return;
|
|
6193
6526
|
}
|
|
6194
|
-
|
|
6527
|
+
note9(
|
|
6195
6528
|
`The following will be copied to global storage:
|
|
6196
6529
|
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
6197
6530
|
|
|
6198
|
-
Destination: ${
|
|
6531
|
+
Destination: ${pc11.cyan(globalPath)}`,
|
|
6199
6532
|
"Sync Preview"
|
|
6200
6533
|
);
|
|
6201
|
-
const shouldSync = await
|
|
6534
|
+
const shouldSync = await confirm8({
|
|
6202
6535
|
message: "Proceed with sync to global storage?",
|
|
6203
6536
|
initialValue: true
|
|
6204
6537
|
});
|
|
6205
|
-
if (
|
|
6206
|
-
|
|
6538
|
+
if (isCancel10(shouldSync) || !shouldSync) {
|
|
6539
|
+
outro5("Sync cancelled.");
|
|
6207
6540
|
return;
|
|
6208
6541
|
}
|
|
6209
|
-
const s =
|
|
6542
|
+
const s = spinner5();
|
|
6210
6543
|
s.start("Syncing to global storage");
|
|
6211
6544
|
try {
|
|
6212
6545
|
ensureDir(globalPath);
|
|
6213
6546
|
for (const dir of existingDirs) {
|
|
6214
|
-
const srcDir =
|
|
6215
|
-
const destDir =
|
|
6547
|
+
const srcDir = path23.join(localPath, dir);
|
|
6548
|
+
const destDir = path23.join(globalPath, dir);
|
|
6216
6549
|
ensureDir(destDir);
|
|
6217
6550
|
copyDirRecursive(srcDir, destDir);
|
|
6218
6551
|
}
|
|
@@ -6221,287 +6554,21 @@ Destination: ${pc10.cyan(globalPath)}`,
|
|
|
6221
6554
|
`Synced directories:`,
|
|
6222
6555
|
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
6223
6556
|
``,
|
|
6224
|
-
`Global path: ${
|
|
6557
|
+
`Global path: ${pc11.cyan(globalPath)}`,
|
|
6225
6558
|
``,
|
|
6226
6559
|
`Other projects can now link this knowledge!`
|
|
6227
6560
|
];
|
|
6228
|
-
|
|
6229
|
-
|
|
6561
|
+
note9(summary.join("\n"), "Sync Summary");
|
|
6562
|
+
outro5(pc11.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
6230
6563
|
} catch (error) {
|
|
6231
6564
|
s.stop("Error occurred");
|
|
6232
|
-
|
|
6565
|
+
cancel5(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
6233
6566
|
process.exit(1);
|
|
6234
6567
|
}
|
|
6235
6568
|
}
|
|
6236
6569
|
|
|
6237
|
-
// src/commands/wizard/
|
|
6238
|
-
|
|
6239
|
-
init_prompts();
|
|
6240
|
-
import { confirm as confirm8, spinner as spinner5, note as note9, outro as outro5, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
|
|
6241
|
-
import pc11 from "picocolors";
|
|
6242
|
-
import * as fs23 from "fs";
|
|
6243
|
-
import * as path23 from "path";
|
|
6244
|
-
import { stringify as stringify3, parse } from "yaml";
|
|
6245
|
-
init_install();
|
|
6246
|
-
init_drift_service();
|
|
6247
|
-
function backupFile(filePath) {
|
|
6248
|
-
if (!fs23.existsSync(filePath)) return null;
|
|
6249
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T")[0] + "-" + Date.now();
|
|
6250
|
-
const backupPath = `${filePath}.${timestamp}.bak`;
|
|
6251
|
-
try {
|
|
6252
|
-
fs23.copyFileSync(filePath, backupPath);
|
|
6253
|
-
return backupPath;
|
|
6254
|
-
} catch (e) {
|
|
6255
|
-
console.error(`Failed to backup ${filePath}:`, e);
|
|
6256
|
-
return null;
|
|
6257
|
-
}
|
|
6258
|
-
}
|
|
6259
|
-
function getPackageVersion2() {
|
|
6260
|
-
try {
|
|
6261
|
-
const agentCoreDir = getAgentCoreDir();
|
|
6262
|
-
const packageJsonPath = path23.join(path23.dirname(agentCoreDir), "package.json");
|
|
6263
|
-
if (fs23.existsSync(packageJsonPath)) {
|
|
6264
|
-
return JSON.parse(fs23.readFileSync(packageJsonPath, "utf8")).version;
|
|
6265
|
-
}
|
|
6266
|
-
} catch (e) {
|
|
6267
|
-
}
|
|
6268
|
-
return "0.0.0";
|
|
6269
|
-
}
|
|
6270
|
-
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
6271
|
-
const s = spinner5();
|
|
6272
|
-
s.start("Checking for updates");
|
|
6273
|
-
try {
|
|
6274
|
-
const agentCoreDir = getAgentCoreDir();
|
|
6275
|
-
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
6276
|
-
const runningVersion = getPackageVersion2();
|
|
6277
|
-
const mode = currentStorageMode || "global";
|
|
6278
|
-
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
6279
|
-
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
6280
|
-
const configFilePath = getConfigPath(workspacePath);
|
|
6281
|
-
let currentSyncedVersion;
|
|
6282
|
-
if (fs23.existsSync(configFilePath)) {
|
|
6283
|
-
try {
|
|
6284
|
-
const content = fs23.readFileSync(configFilePath, "utf-8");
|
|
6285
|
-
const config = parse(content);
|
|
6286
|
-
currentSyncedVersion = config.last_synced_version;
|
|
6287
|
-
} catch (e) {
|
|
6288
|
-
}
|
|
6289
|
-
}
|
|
6290
|
-
const driftReport = DriftService.checkDrift(dataPaths[0], currentSyncedVersion, runningVersion);
|
|
6291
|
-
s.stop("Updates found");
|
|
6292
|
-
if (driftReport.type === "version") {
|
|
6293
|
-
note9(`New version available: ${pc11.green(runningVersion)} (Current synced: ${pc11.dim(currentSyncedVersion || "None")})`, "Update Available");
|
|
6294
|
-
}
|
|
6295
|
-
if (driftReport.modifiedFiles.length > 0) {
|
|
6296
|
-
note9(
|
|
6297
|
-
pc11.yellow(`The following files have been modified and will be backed up before updating:
|
|
6298
|
-
`) + driftReport.modifiedFiles.map((f) => ` \u2022 ${f}`).join("\n"),
|
|
6299
|
-
"Modifications Detected"
|
|
6300
|
-
);
|
|
6301
|
-
}
|
|
6302
|
-
const updateTargets = [
|
|
6303
|
-
` \u2022 prompts/ (${prompts.length} agent prompts)`,
|
|
6304
|
-
` \u2022 templates/ (output templates)`,
|
|
6305
|
-
` \u2022 docs/ (documentation)`
|
|
6306
|
-
];
|
|
6307
|
-
const ideTargets = [];
|
|
6308
|
-
if (fs23.existsSync(configFilePath)) {
|
|
6309
|
-
const configContent = fs23.readFileSync(configFilePath, "utf-8");
|
|
6310
|
-
if (configContent.includes("opencode: true")) ideTargets.push("OpenCode agents");
|
|
6311
|
-
if (configContent.includes("copilot: true")) ideTargets.push("GitHub Copilot");
|
|
6312
|
-
if (configContent.includes("antigravity: true")) ideTargets.push("Antigravity");
|
|
6313
|
-
}
|
|
6314
|
-
if (ideTargets.length > 0) {
|
|
6315
|
-
updateTargets.push(` \u2022 IDE integrations: ${ideTargets.join(", ")}`);
|
|
6316
|
-
}
|
|
6317
|
-
note9(
|
|
6318
|
-
`The following will be updated from the package:
|
|
6319
|
-
${updateTargets.join("\n")}
|
|
6320
|
-
|
|
6321
|
-
Target locations:
|
|
6322
|
-
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
6323
|
-
"Update Preview"
|
|
6324
|
-
);
|
|
6325
|
-
const shouldUpdate = await confirm8({
|
|
6326
|
-
message: "Proceed with update?",
|
|
6327
|
-
initialValue: true
|
|
6328
|
-
});
|
|
6329
|
-
if (isCancel10(shouldUpdate) || !shouldUpdate) {
|
|
6330
|
-
outro5("Update cancelled.");
|
|
6331
|
-
return;
|
|
6332
|
-
}
|
|
6333
|
-
s.start("Updating from package");
|
|
6334
|
-
for (const dataPath of dataPaths) {
|
|
6335
|
-
const dirs = ["templates", "prompts", "docs"];
|
|
6336
|
-
const updatedFiles = [];
|
|
6337
|
-
for (const dir of dirs) {
|
|
6338
|
-
const srcDir = path23.join(agentCoreDir, dir);
|
|
6339
|
-
if (!fs23.existsSync(srcDir)) continue;
|
|
6340
|
-
const syncFiles = (src, rel) => {
|
|
6341
|
-
const entries = fs23.readdirSync(src, { withFileTypes: true });
|
|
6342
|
-
for (const entry of entries) {
|
|
6343
|
-
const entrySrc = path23.join(src, entry.name);
|
|
6344
|
-
const entryRel = path23.join(rel, entry.name);
|
|
6345
|
-
const entryDest = path23.join(dataPath, entryRel);
|
|
6346
|
-
if (entry.isDirectory()) {
|
|
6347
|
-
ensureDir(entryDest);
|
|
6348
|
-
syncFiles(entrySrc, entryRel);
|
|
6349
|
-
} else {
|
|
6350
|
-
if (driftReport.modifiedFiles.includes(entryRel)) {
|
|
6351
|
-
backupFile(entryDest);
|
|
6352
|
-
}
|
|
6353
|
-
fs23.copyFileSync(entrySrc, entryDest);
|
|
6354
|
-
updatedFiles.push(entryRel);
|
|
6355
|
-
}
|
|
6356
|
-
}
|
|
6357
|
-
};
|
|
6358
|
-
syncFiles(srcDir, dir);
|
|
6359
|
-
}
|
|
6360
|
-
const manifest = DriftService.generateManifest(dataPath, updatedFiles);
|
|
6361
|
-
DriftService.saveManifest(dataPath, manifest);
|
|
6362
|
-
}
|
|
6363
|
-
const rrceHome = customGlobalPath || getDefaultRRCEHome2();
|
|
6364
|
-
ensureDir(path23.join(rrceHome, "templates"));
|
|
6365
|
-
ensureDir(path23.join(rrceHome, "docs"));
|
|
6366
|
-
copyDirRecursive(path23.join(agentCoreDir, "templates"), path23.join(rrceHome, "templates"));
|
|
6367
|
-
copyDirRecursive(path23.join(agentCoreDir, "docs"), path23.join(rrceHome, "docs"));
|
|
6368
|
-
if (fs23.existsSync(configFilePath)) {
|
|
6369
|
-
const configContent = fs23.readFileSync(configFilePath, "utf-8");
|
|
6370
|
-
if (configContent.includes("copilot: true")) {
|
|
6371
|
-
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
6372
|
-
ensureDir(copilotPath);
|
|
6373
|
-
clearDirectory(copilotPath);
|
|
6374
|
-
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
6375
|
-
}
|
|
6376
|
-
if (configContent.includes("antigravity: true")) {
|
|
6377
|
-
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
6378
|
-
ensureDir(antigravityPath);
|
|
6379
|
-
clearDirectory(antigravityPath);
|
|
6380
|
-
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
6381
|
-
}
|
|
6382
|
-
if (configContent.includes("opencode: true")) {
|
|
6383
|
-
const primaryDataPath = dataPaths[0];
|
|
6384
|
-
if (primaryDataPath) {
|
|
6385
|
-
updateOpenCodeAgents(prompts, mode, primaryDataPath);
|
|
6386
|
-
}
|
|
6387
|
-
}
|
|
6388
|
-
try {
|
|
6389
|
-
const yaml = parse(configContent);
|
|
6390
|
-
yaml.last_synced_version = runningVersion;
|
|
6391
|
-
fs23.writeFileSync(configFilePath, stringify3(yaml));
|
|
6392
|
-
} catch (e) {
|
|
6393
|
-
console.error("Failed to update config.yaml version:", e);
|
|
6394
|
-
}
|
|
6395
|
-
}
|
|
6396
|
-
const mcpPath = path23.join(rrceHome, "mcp.yaml");
|
|
6397
|
-
if (fs23.existsSync(mcpPath)) {
|
|
6398
|
-
try {
|
|
6399
|
-
const content = fs23.readFileSync(mcpPath, "utf-8");
|
|
6400
|
-
const yaml = parse(content);
|
|
6401
|
-
if (yaml.projects) {
|
|
6402
|
-
const project = yaml.projects.find((p) => p.name === workspaceName);
|
|
6403
|
-
if (project) {
|
|
6404
|
-
project.last_synced_version = runningVersion;
|
|
6405
|
-
fs23.writeFileSync(mcpPath, stringify3(yaml));
|
|
6406
|
-
}
|
|
6407
|
-
}
|
|
6408
|
-
} catch (e) {
|
|
6409
|
-
console.error("Failed to update mcp.yaml version:", e);
|
|
6410
|
-
}
|
|
6411
|
-
}
|
|
6412
|
-
s.stop("Update complete");
|
|
6413
|
-
const summary = [
|
|
6414
|
-
`Updated:`,
|
|
6415
|
-
` \u2713 ${prompts.length} agent prompts`,
|
|
6416
|
-
` \u2713 Output templates`,
|
|
6417
|
-
` \u2713 Documentation`
|
|
6418
|
-
];
|
|
6419
|
-
if (ideTargets.length > 0) {
|
|
6420
|
-
summary.push(` \u2713 IDE integrations: ${ideTargets.join(", ")}`);
|
|
6421
|
-
}
|
|
6422
|
-
if (driftReport.modifiedFiles.length > 0) {
|
|
6423
|
-
summary.push(` \u2713 ${driftReport.modifiedFiles.length} modified files backed up`);
|
|
6424
|
-
}
|
|
6425
|
-
summary.push(
|
|
6426
|
-
``,
|
|
6427
|
-
`Your configuration and knowledge files were preserved.`,
|
|
6428
|
-
``,
|
|
6429
|
-
pc11.dim(`\u{1F4A1} If using OpenCode, you may need to reload for changes to take effect.`)
|
|
6430
|
-
);
|
|
6431
|
-
note9(summary.join("\n"), "Update Summary");
|
|
6432
|
-
outro5(pc11.green("\u2713 Successfully updated from package!"));
|
|
6433
|
-
} catch (error) {
|
|
6434
|
-
s.stop("Error occurred");
|
|
6435
|
-
cancel5(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
6436
|
-
process.exit(1);
|
|
6437
|
-
}
|
|
6438
|
-
}
|
|
6439
|
-
function updateOpenCodeAgents(prompts, mode, primaryDataPath) {
|
|
6440
|
-
if (mode === "global") {
|
|
6441
|
-
try {
|
|
6442
|
-
const promptsDir = path23.join(path23.dirname(OPENCODE_CONFIG), "prompts");
|
|
6443
|
-
ensureDir(promptsDir);
|
|
6444
|
-
const newAgents = {};
|
|
6445
|
-
for (const prompt of prompts) {
|
|
6446
|
-
const baseName = path23.basename(prompt.filePath, ".md");
|
|
6447
|
-
const agentId = `rrce_${baseName}`;
|
|
6448
|
-
const promptFileName = `rrce-${baseName}.md`;
|
|
6449
|
-
const promptFilePath = path23.join(promptsDir, promptFileName);
|
|
6450
|
-
fs23.writeFileSync(promptFilePath, prompt.content);
|
|
6451
|
-
const agentConfig = convertToOpenCodeAgent(prompt, true, `./prompts/${promptFileName}`);
|
|
6452
|
-
newAgents[agentId] = agentConfig;
|
|
6453
|
-
}
|
|
6454
|
-
updateOpenCodeConfig(newAgents);
|
|
6455
|
-
if (fs23.existsSync(OPENCODE_CONFIG)) {
|
|
6456
|
-
const config = JSON.parse(fs23.readFileSync(OPENCODE_CONFIG, "utf8"));
|
|
6457
|
-
if (!config.agents) config.agents = {};
|
|
6458
|
-
if (!config.agents.plan) config.agents.plan = {};
|
|
6459
|
-
config.agents.plan.disable = true;
|
|
6460
|
-
fs23.writeFileSync(OPENCODE_CONFIG, JSON.stringify(config, null, 2));
|
|
6461
|
-
}
|
|
6462
|
-
} catch (e) {
|
|
6463
|
-
console.error("Failed to update global OpenCode config with agents:", e);
|
|
6464
|
-
}
|
|
6465
|
-
} else {
|
|
6466
|
-
const opencodeBaseDir = path23.join(primaryDataPath, ".opencode", "agent");
|
|
6467
|
-
ensureDir(opencodeBaseDir);
|
|
6468
|
-
clearDirectory(opencodeBaseDir);
|
|
6469
|
-
for (const prompt of prompts) {
|
|
6470
|
-
const baseName = path23.basename(prompt.filePath, ".md");
|
|
6471
|
-
const agentId = `rrce_${baseName}`;
|
|
6472
|
-
const agentConfig = convertToOpenCodeAgent(prompt);
|
|
6473
|
-
const content = `---
|
|
6474
|
-
${stringify3({
|
|
6475
|
-
description: agentConfig.description,
|
|
6476
|
-
mode: agentConfig.mode,
|
|
6477
|
-
tools: agentConfig.tools
|
|
6478
|
-
})}---
|
|
6479
|
-
${agentConfig.prompt}`;
|
|
6480
|
-
fs23.writeFileSync(path23.join(opencodeBaseDir, `${agentId}.md`), content);
|
|
6481
|
-
}
|
|
6482
|
-
}
|
|
6483
|
-
}
|
|
6484
|
-
function clearDirectory(dirPath) {
|
|
6485
|
-
if (!fs23.existsSync(dirPath)) return;
|
|
6486
|
-
const entries = fs23.readdirSync(dirPath, { withFileTypes: true });
|
|
6487
|
-
for (const entry of entries) {
|
|
6488
|
-
if (entry.isFile()) {
|
|
6489
|
-
fs23.unlinkSync(path23.join(dirPath, entry.name));
|
|
6490
|
-
}
|
|
6491
|
-
}
|
|
6492
|
-
}
|
|
6493
|
-
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
6494
|
-
const globalPath = path23.join(customGlobalPath, "workspaces", workspaceName);
|
|
6495
|
-
const workspacePath = path23.join(workspaceRoot, ".rrce-workflow");
|
|
6496
|
-
switch (mode) {
|
|
6497
|
-
case "global":
|
|
6498
|
-
return [globalPath];
|
|
6499
|
-
case "workspace":
|
|
6500
|
-
return [workspacePath];
|
|
6501
|
-
default:
|
|
6502
|
-
return [globalPath];
|
|
6503
|
-
}
|
|
6504
|
-
}
|
|
6570
|
+
// src/commands/wizard/index.ts
|
|
6571
|
+
init_update_flow();
|
|
6505
6572
|
|
|
6506
6573
|
// src/commands/wizard/delete-flow.ts
|
|
6507
6574
|
import { multiselect as multiselect5, confirm as confirm9, spinner as spinner6, note as note10, cancel as cancel6, isCancel as isCancel11 } from "@clack/prompts";
|