rrce-workflow 0.3.0 → 0.3.2
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 +1096 -799
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -574,9 +574,97 @@ var init_detection_service = __esm({
|
|
|
574
574
|
}
|
|
575
575
|
});
|
|
576
576
|
|
|
577
|
-
// src/
|
|
577
|
+
// src/types/prompt.ts
|
|
578
|
+
import { z } from "zod";
|
|
579
|
+
var PromptArgSchema, AutoIdentitySchema, PromptFrontmatterSchema;
|
|
580
|
+
var init_prompt = __esm({
|
|
581
|
+
"src/types/prompt.ts"() {
|
|
582
|
+
"use strict";
|
|
583
|
+
PromptArgSchema = z.object({
|
|
584
|
+
name: z.string(),
|
|
585
|
+
default: z.string().optional(),
|
|
586
|
+
prompt: z.string().optional()
|
|
587
|
+
});
|
|
588
|
+
AutoIdentitySchema = z.object({
|
|
589
|
+
user: z.string(),
|
|
590
|
+
model: z.string()
|
|
591
|
+
});
|
|
592
|
+
PromptFrontmatterSchema = z.object({
|
|
593
|
+
name: z.string(),
|
|
594
|
+
description: z.string(),
|
|
595
|
+
"argument-hint": z.union([z.string(), z.array(z.string())]).optional(),
|
|
596
|
+
tools: z.array(z.string()).optional(),
|
|
597
|
+
mode: z.enum(["primary", "subagent"]).optional(),
|
|
598
|
+
"required-args": z.array(PromptArgSchema).optional(),
|
|
599
|
+
"optional-args": z.array(PromptArgSchema).optional(),
|
|
600
|
+
"auto-identity": AutoIdentitySchema.optional()
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
// src/lib/prompts.ts
|
|
578
606
|
import * as fs4 from "fs";
|
|
579
607
|
import * as path4 from "path";
|
|
608
|
+
import { fileURLToPath } from "url";
|
|
609
|
+
import matter from "gray-matter";
|
|
610
|
+
function parsePromptFile(filePath) {
|
|
611
|
+
try {
|
|
612
|
+
const fileContent = fs4.readFileSync(filePath, "utf-8");
|
|
613
|
+
const { data, content } = matter(fileContent);
|
|
614
|
+
const parsed = PromptFrontmatterSchema.safeParse(data);
|
|
615
|
+
if (!parsed.success) {
|
|
616
|
+
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
return {
|
|
620
|
+
frontmatter: parsed.data,
|
|
621
|
+
content: content.trim(),
|
|
622
|
+
filePath
|
|
623
|
+
};
|
|
624
|
+
} catch (error) {
|
|
625
|
+
console.error(`Error reading prompt file ${filePath}:`, error);
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
function loadPromptsFromDir(dirPath) {
|
|
630
|
+
if (!fs4.existsSync(dirPath)) {
|
|
631
|
+
return [];
|
|
632
|
+
}
|
|
633
|
+
const files = fs4.readdirSync(dirPath).filter((f) => f.endsWith(".md"));
|
|
634
|
+
const prompts = [];
|
|
635
|
+
for (const file of files) {
|
|
636
|
+
const prompt = parsePromptFile(path4.join(dirPath, file));
|
|
637
|
+
if (prompt) {
|
|
638
|
+
prompts.push(prompt);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return prompts;
|
|
642
|
+
}
|
|
643
|
+
function getAgentCoreDir() {
|
|
644
|
+
if (__dirname.includes("/src/") || __dirname.includes("\\src\\")) {
|
|
645
|
+
if (fs4.existsSync(path4.join(process.cwd(), "agent-core"))) {
|
|
646
|
+
return path4.join(process.cwd(), "agent-core");
|
|
647
|
+
}
|
|
648
|
+
return path4.resolve(__dirname, "../..", "agent-core");
|
|
649
|
+
}
|
|
650
|
+
return path4.join(__dirname, "..", "agent-core");
|
|
651
|
+
}
|
|
652
|
+
function getAgentCorePromptsDir() {
|
|
653
|
+
return path4.join(getAgentCoreDir(), "prompts");
|
|
654
|
+
}
|
|
655
|
+
var __filename, __dirname;
|
|
656
|
+
var init_prompts = __esm({
|
|
657
|
+
"src/lib/prompts.ts"() {
|
|
658
|
+
"use strict";
|
|
659
|
+
init_prompt();
|
|
660
|
+
__filename = fileURLToPath(import.meta.url);
|
|
661
|
+
__dirname = path4.dirname(__filename);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// src/lib/autocomplete-prompt.ts
|
|
666
|
+
import * as fs5 from "fs";
|
|
667
|
+
import * as path5 from "path";
|
|
580
668
|
import * as readline from "readline";
|
|
581
669
|
import pc from "picocolors";
|
|
582
670
|
function directoryPrompt(opts) {
|
|
@@ -635,19 +723,19 @@ function completeDirectory(line) {
|
|
|
635
723
|
prefix = "";
|
|
636
724
|
basePath = expanded;
|
|
637
725
|
} else {
|
|
638
|
-
dirToScan =
|
|
639
|
-
prefix =
|
|
726
|
+
dirToScan = path5.dirname(expanded);
|
|
727
|
+
prefix = path5.basename(expanded).toLowerCase();
|
|
640
728
|
basePath = dirToScan === "/" ? "/" : dirToScan + "/";
|
|
641
729
|
}
|
|
642
|
-
if (!
|
|
730
|
+
if (!fs5.existsSync(dirToScan)) {
|
|
643
731
|
return [[], line];
|
|
644
732
|
}
|
|
645
|
-
const entries =
|
|
733
|
+
const entries = fs5.readdirSync(dirToScan, { withFileTypes: true }).filter((entry) => {
|
|
646
734
|
if (!entry.isDirectory()) return false;
|
|
647
735
|
if (entry.name.startsWith(".") && !prefix.startsWith(".")) return false;
|
|
648
736
|
return prefix === "" || entry.name.toLowerCase().startsWith(prefix);
|
|
649
737
|
}).map((entry) => {
|
|
650
|
-
const fullPath =
|
|
738
|
+
const fullPath = path5.join(dirToScan, entry.name);
|
|
651
739
|
const displayPath = fullPath.startsWith(process.env.HOME || "") ? fullPath.replace(process.env.HOME || "", "~") : fullPath;
|
|
652
740
|
return displayPath + "/";
|
|
653
741
|
}).sort();
|
|
@@ -693,7 +781,7 @@ __export(tui_utils_exports, {
|
|
|
693
781
|
});
|
|
694
782
|
import { select, note, isCancel } from "@clack/prompts";
|
|
695
783
|
import pc2 from "picocolors";
|
|
696
|
-
import * as
|
|
784
|
+
import * as path6 from "path";
|
|
697
785
|
async function resolveGlobalPath() {
|
|
698
786
|
const prefs = loadUserPreferences();
|
|
699
787
|
const defaultPath = prefs.defaultGlobalPath || getDefaultRRCEHome2();
|
|
@@ -732,7 +820,7 @@ Please choose a custom path instead.`,
|
|
|
732
820
|
}
|
|
733
821
|
return defaultPath;
|
|
734
822
|
}
|
|
735
|
-
const suggestedPath =
|
|
823
|
+
const suggestedPath = path6.join(process.env.HOME || "~", ".rrce-workflow");
|
|
736
824
|
const customPath = await directoryPrompt({
|
|
737
825
|
message: "Enter custom global path (Tab to autocomplete):",
|
|
738
826
|
defaultValue: suggestedPath,
|
|
@@ -751,7 +839,7 @@ Please choose a custom path instead.`,
|
|
|
751
839
|
}
|
|
752
840
|
let expandedPath = customPath;
|
|
753
841
|
if (!expandedPath.endsWith(".rrce-workflow")) {
|
|
754
|
-
expandedPath =
|
|
842
|
+
expandedPath = path6.join(expandedPath, ".rrce-workflow");
|
|
755
843
|
}
|
|
756
844
|
saveUserPreferences({ defaultGlobalPath: expandedPath, useCustomGlobalPath: true });
|
|
757
845
|
return expandedPath;
|
|
@@ -766,8 +854,8 @@ var init_tui_utils = __esm({
|
|
|
766
854
|
});
|
|
767
855
|
|
|
768
856
|
// src/mcp/install.ts
|
|
769
|
-
import * as
|
|
770
|
-
import * as
|
|
857
|
+
import * as fs6 from "fs";
|
|
858
|
+
import * as path7 from "path";
|
|
771
859
|
import * as os from "os";
|
|
772
860
|
function checkInstallStatus(workspacePath) {
|
|
773
861
|
return {
|
|
@@ -779,46 +867,46 @@ function checkInstallStatus(workspacePath) {
|
|
|
779
867
|
};
|
|
780
868
|
}
|
|
781
869
|
function checkAntigravityConfig() {
|
|
782
|
-
if (!
|
|
870
|
+
if (!fs6.existsSync(ANTIGRAVITY_CONFIG)) return false;
|
|
783
871
|
try {
|
|
784
|
-
const content = JSON.parse(
|
|
872
|
+
const content = JSON.parse(fs6.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
785
873
|
return !!content.mcpServers?.["rrce"];
|
|
786
874
|
} catch {
|
|
787
875
|
return false;
|
|
788
876
|
}
|
|
789
877
|
}
|
|
790
878
|
function checkClaudeConfig() {
|
|
791
|
-
if (!
|
|
879
|
+
if (!fs6.existsSync(CLAUDE_CONFIG)) return false;
|
|
792
880
|
try {
|
|
793
|
-
const content = JSON.parse(
|
|
881
|
+
const content = JSON.parse(fs6.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
794
882
|
return !!content.mcpServers?.["rrce"];
|
|
795
883
|
} catch {
|
|
796
884
|
return false;
|
|
797
885
|
}
|
|
798
886
|
}
|
|
799
887
|
function checkVSCodeGlobalConfig() {
|
|
800
|
-
if (!
|
|
888
|
+
if (!fs6.existsSync(VSCODE_GLOBAL_CONFIG)) return false;
|
|
801
889
|
try {
|
|
802
|
-
const content = JSON.parse(
|
|
890
|
+
const content = JSON.parse(fs6.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
803
891
|
return !!content["mcp.servers"]?.["rrce"];
|
|
804
892
|
} catch {
|
|
805
893
|
return false;
|
|
806
894
|
}
|
|
807
895
|
}
|
|
808
896
|
function checkVSCodeWorkspaceConfig(workspacePath) {
|
|
809
|
-
const configPath =
|
|
810
|
-
if (!
|
|
897
|
+
const configPath = path7.join(workspacePath, ".vscode", "mcp.json");
|
|
898
|
+
if (!fs6.existsSync(configPath)) return false;
|
|
811
899
|
try {
|
|
812
|
-
const content = JSON.parse(
|
|
900
|
+
const content = JSON.parse(fs6.readFileSync(configPath, "utf-8"));
|
|
813
901
|
return !!content.servers?.["rrce"];
|
|
814
902
|
} catch {
|
|
815
903
|
return false;
|
|
816
904
|
}
|
|
817
905
|
}
|
|
818
906
|
function checkOpenCodeConfig() {
|
|
819
|
-
if (!
|
|
907
|
+
if (!fs6.existsSync(OPENCODE_CONFIG)) return false;
|
|
820
908
|
try {
|
|
821
|
-
const content = JSON.parse(
|
|
909
|
+
const content = JSON.parse(fs6.readFileSync(OPENCODE_CONFIG, "utf-8"));
|
|
822
910
|
return !!content.mcp?.["rrce"];
|
|
823
911
|
} catch {
|
|
824
912
|
return false;
|
|
@@ -845,14 +933,14 @@ function installToConfig(target, workspacePath) {
|
|
|
845
933
|
}
|
|
846
934
|
}
|
|
847
935
|
function installToAntigravity() {
|
|
848
|
-
const dir =
|
|
849
|
-
if (!
|
|
850
|
-
|
|
936
|
+
const dir = path7.dirname(ANTIGRAVITY_CONFIG);
|
|
937
|
+
if (!fs6.existsSync(dir)) {
|
|
938
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
851
939
|
}
|
|
852
940
|
let config = { mcpServers: {} };
|
|
853
|
-
if (
|
|
941
|
+
if (fs6.existsSync(ANTIGRAVITY_CONFIG)) {
|
|
854
942
|
try {
|
|
855
|
-
config = JSON.parse(
|
|
943
|
+
config = JSON.parse(fs6.readFileSync(ANTIGRAVITY_CONFIG, "utf-8"));
|
|
856
944
|
} catch {
|
|
857
945
|
}
|
|
858
946
|
}
|
|
@@ -862,21 +950,21 @@ function installToAntigravity() {
|
|
|
862
950
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
863
951
|
};
|
|
864
952
|
try {
|
|
865
|
-
|
|
953
|
+
fs6.writeFileSync(ANTIGRAVITY_CONFIG, JSON.stringify(config, null, 2));
|
|
866
954
|
return true;
|
|
867
955
|
} catch {
|
|
868
956
|
return false;
|
|
869
957
|
}
|
|
870
958
|
}
|
|
871
959
|
function installToClaude() {
|
|
872
|
-
const dir =
|
|
873
|
-
if (!
|
|
874
|
-
|
|
960
|
+
const dir = path7.dirname(CLAUDE_CONFIG);
|
|
961
|
+
if (!fs6.existsSync(dir)) {
|
|
962
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
875
963
|
}
|
|
876
964
|
let config = { mcpServers: {} };
|
|
877
|
-
if (
|
|
965
|
+
if (fs6.existsSync(CLAUDE_CONFIG)) {
|
|
878
966
|
try {
|
|
879
|
-
config = JSON.parse(
|
|
967
|
+
config = JSON.parse(fs6.readFileSync(CLAUDE_CONFIG, "utf-8"));
|
|
880
968
|
} catch {
|
|
881
969
|
}
|
|
882
970
|
}
|
|
@@ -886,21 +974,21 @@ function installToClaude() {
|
|
|
886
974
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
887
975
|
};
|
|
888
976
|
try {
|
|
889
|
-
|
|
977
|
+
fs6.writeFileSync(CLAUDE_CONFIG, JSON.stringify(config, null, 2));
|
|
890
978
|
return true;
|
|
891
979
|
} catch {
|
|
892
980
|
return false;
|
|
893
981
|
}
|
|
894
982
|
}
|
|
895
983
|
function installToVSCodeGlobal() {
|
|
896
|
-
const dir =
|
|
897
|
-
if (!
|
|
898
|
-
|
|
984
|
+
const dir = path7.dirname(VSCODE_GLOBAL_CONFIG);
|
|
985
|
+
if (!fs6.existsSync(dir)) {
|
|
986
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
899
987
|
}
|
|
900
988
|
let settings = {};
|
|
901
|
-
if (
|
|
989
|
+
if (fs6.existsSync(VSCODE_GLOBAL_CONFIG)) {
|
|
902
990
|
try {
|
|
903
|
-
settings = JSON.parse(
|
|
991
|
+
settings = JSON.parse(fs6.readFileSync(VSCODE_GLOBAL_CONFIG, "utf-8"));
|
|
904
992
|
} catch {
|
|
905
993
|
}
|
|
906
994
|
}
|
|
@@ -910,22 +998,22 @@ function installToVSCodeGlobal() {
|
|
|
910
998
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
911
999
|
};
|
|
912
1000
|
try {
|
|
913
|
-
|
|
1001
|
+
fs6.writeFileSync(VSCODE_GLOBAL_CONFIG, JSON.stringify(settings, null, 2));
|
|
914
1002
|
return true;
|
|
915
1003
|
} catch {
|
|
916
1004
|
return false;
|
|
917
1005
|
}
|
|
918
1006
|
}
|
|
919
1007
|
function installToVSCodeWorkspace(workspacePath) {
|
|
920
|
-
const vscodeDir =
|
|
921
|
-
const configPath =
|
|
922
|
-
if (!
|
|
923
|
-
|
|
1008
|
+
const vscodeDir = path7.join(workspacePath, ".vscode");
|
|
1009
|
+
const configPath = path7.join(vscodeDir, "mcp.json");
|
|
1010
|
+
if (!fs6.existsSync(vscodeDir)) {
|
|
1011
|
+
fs6.mkdirSync(vscodeDir, { recursive: true });
|
|
924
1012
|
}
|
|
925
1013
|
let config = { servers: {} };
|
|
926
|
-
if (
|
|
1014
|
+
if (fs6.existsSync(configPath)) {
|
|
927
1015
|
try {
|
|
928
|
-
config = JSON.parse(
|
|
1016
|
+
config = JSON.parse(fs6.readFileSync(configPath, "utf-8"));
|
|
929
1017
|
} catch {
|
|
930
1018
|
}
|
|
931
1019
|
}
|
|
@@ -935,23 +1023,23 @@ function installToVSCodeWorkspace(workspacePath) {
|
|
|
935
1023
|
args: ["-y", "rrce-workflow", "mcp", "start"]
|
|
936
1024
|
};
|
|
937
1025
|
try {
|
|
938
|
-
|
|
1026
|
+
fs6.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
939
1027
|
return true;
|
|
940
1028
|
} catch {
|
|
941
1029
|
return false;
|
|
942
1030
|
}
|
|
943
1031
|
}
|
|
944
1032
|
function installToOpenCode() {
|
|
945
|
-
const dir =
|
|
946
|
-
if (!
|
|
947
|
-
|
|
1033
|
+
const dir = path7.dirname(OPENCODE_CONFIG);
|
|
1034
|
+
if (!fs6.existsSync(dir)) {
|
|
1035
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
948
1036
|
}
|
|
949
1037
|
let config = {
|
|
950
1038
|
$schema: "https://opencode.ai/config.json"
|
|
951
1039
|
};
|
|
952
|
-
if (
|
|
1040
|
+
if (fs6.existsSync(OPENCODE_CONFIG)) {
|
|
953
1041
|
try {
|
|
954
|
-
config = JSON.parse(
|
|
1042
|
+
config = JSON.parse(fs6.readFileSync(OPENCODE_CONFIG, "utf-8"));
|
|
955
1043
|
} catch (error) {
|
|
956
1044
|
console.error("Warning: Could not parse existing OpenCode config, creating fresh config");
|
|
957
1045
|
}
|
|
@@ -963,7 +1051,7 @@ function installToOpenCode() {
|
|
|
963
1051
|
enabled: true
|
|
964
1052
|
};
|
|
965
1053
|
try {
|
|
966
|
-
|
|
1054
|
+
fs6.writeFileSync(OPENCODE_CONFIG, JSON.stringify(config, null, 2) + "\n");
|
|
967
1055
|
return true;
|
|
968
1056
|
} catch (error) {
|
|
969
1057
|
console.error("Failed to write OpenCode config:", error instanceof Error ? error.message : String(error));
|
|
@@ -987,115 +1075,170 @@ function getTargetLabel(target) {
|
|
|
987
1075
|
}
|
|
988
1076
|
}
|
|
989
1077
|
function isOpenCodeInstalled() {
|
|
990
|
-
const configDir =
|
|
991
|
-
const configFile =
|
|
992
|
-
return
|
|
1078
|
+
const configDir = path7.join(os.homedir(), ".config/opencode");
|
|
1079
|
+
const configFile = path7.join(configDir, "opencode.json");
|
|
1080
|
+
return fs6.existsSync(configDir) || fs6.existsSync(configFile);
|
|
993
1081
|
}
|
|
994
1082
|
function isAntigravityInstalled() {
|
|
995
|
-
const configDir =
|
|
996
|
-
return
|
|
1083
|
+
const configDir = path7.join(os.homedir(), ".gemini/antigravity");
|
|
1084
|
+
return fs6.existsSync(configDir);
|
|
997
1085
|
}
|
|
998
1086
|
function isVSCodeInstalled() {
|
|
999
|
-
const configDir =
|
|
1000
|
-
return
|
|
1087
|
+
const configDir = path7.join(os.homedir(), ".config/Code/User");
|
|
1088
|
+
return fs6.existsSync(configDir);
|
|
1001
1089
|
}
|
|
1002
1090
|
var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG, VSCODE_GLOBAL_CONFIG, OPENCODE_CONFIG_DIR, OPENCODE_CONFIG;
|
|
1003
1091
|
var init_install = __esm({
|
|
1004
1092
|
"src/mcp/install.ts"() {
|
|
1005
1093
|
"use strict";
|
|
1006
|
-
ANTIGRAVITY_CONFIG =
|
|
1007
|
-
CLAUDE_CONFIG =
|
|
1008
|
-
VSCODE_GLOBAL_CONFIG =
|
|
1009
|
-
OPENCODE_CONFIG_DIR =
|
|
1010
|
-
OPENCODE_CONFIG =
|
|
1094
|
+
ANTIGRAVITY_CONFIG = path7.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
|
|
1095
|
+
CLAUDE_CONFIG = path7.join(os.homedir(), ".config/claude/claude_desktop_config.json");
|
|
1096
|
+
VSCODE_GLOBAL_CONFIG = path7.join(os.homedir(), ".config/Code/User/settings.json");
|
|
1097
|
+
OPENCODE_CONFIG_DIR = path7.join(os.homedir(), ".config/opencode");
|
|
1098
|
+
OPENCODE_CONFIG = path7.join(OPENCODE_CONFIG_DIR, "opencode.json");
|
|
1011
1099
|
}
|
|
1012
1100
|
});
|
|
1013
1101
|
|
|
1014
|
-
// src/
|
|
1015
|
-
import
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
"required-args": z.array(PromptArgSchema).optional(),
|
|
1036
|
-
"optional-args": z.array(PromptArgSchema).optional(),
|
|
1037
|
-
"auto-identity": AutoIdentitySchema.optional()
|
|
1038
|
-
});
|
|
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;
|
|
1039
1123
|
}
|
|
1040
|
-
});
|
|
1041
|
-
|
|
1042
|
-
// src/lib/prompts.ts
|
|
1043
|
-
import * as fs6 from "fs";
|
|
1044
|
-
import * as path7 from "path";
|
|
1045
|
-
import { fileURLToPath } from "url";
|
|
1046
|
-
import matter from "gray-matter";
|
|
1047
|
-
function parsePromptFile(filePath) {
|
|
1048
1124
|
try {
|
|
1049
|
-
const
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
if (!parsed.success) {
|
|
1053
|
-
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
1054
|
-
return null;
|
|
1125
|
+
const config = JSON.parse(fs7.readFileSync(opencodePath, "utf8"));
|
|
1126
|
+
if (!config.agents) {
|
|
1127
|
+
config.agents = {};
|
|
1055
1128
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
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);
|
|
1064
1144
|
}
|
|
1065
1145
|
}
|
|
1066
|
-
function
|
|
1067
|
-
|
|
1068
|
-
|
|
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
|
+
}
|
|
1069
1158
|
}
|
|
1070
|
-
|
|
1071
|
-
const
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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);
|
|
1076
1179
|
}
|
|
1077
1180
|
}
|
|
1078
|
-
return prompts;
|
|
1079
1181
|
}
|
|
1080
|
-
function
|
|
1081
|
-
if (
|
|
1082
|
-
|
|
1083
|
-
|
|
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));
|
|
1084
1188
|
}
|
|
1085
|
-
return path7.resolve(__dirname, "../..", "agent-core");
|
|
1086
1189
|
}
|
|
1087
|
-
return path7.join(__dirname, "..", "agent-core");
|
|
1088
1190
|
}
|
|
1089
|
-
function
|
|
1090
|
-
|
|
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
|
+
}
|
|
1091
1237
|
}
|
|
1092
|
-
var
|
|
1093
|
-
|
|
1094
|
-
"src/lib/prompts.ts"() {
|
|
1238
|
+
var init_utils = __esm({
|
|
1239
|
+
"src/commands/wizard/utils.ts"() {
|
|
1095
1240
|
"use strict";
|
|
1096
|
-
|
|
1097
|
-
__filename = fileURLToPath(import.meta.url);
|
|
1098
|
-
__dirname = path7.dirname(__filename);
|
|
1241
|
+
init_paths();
|
|
1099
1242
|
}
|
|
1100
1243
|
});
|
|
1101
1244
|
|
|
@@ -3872,7 +4015,7 @@ Hidden projects: ${projects.length - exposedCount}`,
|
|
|
3872
4015
|
async function handleConfigureGlobalPath() {
|
|
3873
4016
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
3874
4017
|
const fs26 = await import("fs");
|
|
3875
|
-
const
|
|
4018
|
+
const path25 = await import("path");
|
|
3876
4019
|
note3(
|
|
3877
4020
|
`MCP Hub requires a ${pc5.bold("global storage path")} to store its configuration
|
|
3878
4021
|
and coordinate across projects.
|
|
@@ -3895,7 +4038,7 @@ locally in each project. MCP needs a central location.`,
|
|
|
3895
4038
|
`${pc5.green("\u2713")} Global path configured: ${pc5.cyan(resolvedPath)}
|
|
3896
4039
|
|
|
3897
4040
|
MCP config will be stored at:
|
|
3898
|
-
${
|
|
4041
|
+
${path25.join(resolvedPath, "mcp.yaml")}`,
|
|
3899
4042
|
"Configuration Saved"
|
|
3900
4043
|
);
|
|
3901
4044
|
return true;
|
|
@@ -5364,12 +5507,359 @@ var init_mcp = __esm({
|
|
|
5364
5507
|
}
|
|
5365
5508
|
});
|
|
5366
5509
|
|
|
5367
|
-
// src/commands/wizard/
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5510
|
+
// src/commands/wizard/update-flow.ts
|
|
5511
|
+
var update_flow_exports = {};
|
|
5512
|
+
__export(update_flow_exports, {
|
|
5513
|
+
runSilentUpdate: () => runSilentUpdate,
|
|
5514
|
+
runUpdateFlow: () => runUpdateFlow
|
|
5515
|
+
});
|
|
5516
|
+
import { confirm as confirm5, spinner as spinner2, note as note6, outro as outro2, cancel as cancel2, isCancel as isCancel7 } from "@clack/prompts";
|
|
5517
|
+
import pc8 from "picocolors";
|
|
5518
|
+
import * as fs21 from "fs";
|
|
5519
|
+
import * as path22 from "path";
|
|
5520
|
+
import { stringify as stringify2, parse } from "yaml";
|
|
5521
|
+
function backupFile(filePath) {
|
|
5522
|
+
if (!fs21.existsSync(filePath)) return null;
|
|
5523
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T")[0] + "-" + Date.now();
|
|
5524
|
+
const backupPath = `${filePath}.${timestamp}.bak`;
|
|
5525
|
+
try {
|
|
5526
|
+
fs21.copyFileSync(filePath, backupPath);
|
|
5527
|
+
return backupPath;
|
|
5528
|
+
} catch (e) {
|
|
5529
|
+
console.error(`Failed to backup ${filePath}:`, e);
|
|
5530
|
+
return null;
|
|
5531
|
+
}
|
|
5532
|
+
}
|
|
5533
|
+
function getPackageVersion2() {
|
|
5534
|
+
try {
|
|
5535
|
+
const agentCoreDir = getAgentCoreDir();
|
|
5536
|
+
const packageJsonPath = path22.join(path22.dirname(agentCoreDir), "package.json");
|
|
5537
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
5538
|
+
return JSON.parse(fs21.readFileSync(packageJsonPath, "utf8")).version;
|
|
5539
|
+
}
|
|
5540
|
+
} catch (e) {
|
|
5541
|
+
}
|
|
5542
|
+
return "0.0.0";
|
|
5543
|
+
}
|
|
5544
|
+
async function performUpdate(workspacePath, workspaceName, currentStorageMode, options = {}) {
|
|
5545
|
+
const agentCoreDir = getAgentCoreDir();
|
|
5546
|
+
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
5547
|
+
const runningVersion = getPackageVersion2();
|
|
5548
|
+
const mode = currentStorageMode || "global";
|
|
5549
|
+
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
5550
|
+
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
5551
|
+
const configFilePath = getConfigPath(workspacePath);
|
|
5552
|
+
let currentSyncedVersion;
|
|
5553
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5554
|
+
try {
|
|
5555
|
+
const content = fs21.readFileSync(configFilePath, "utf-8");
|
|
5556
|
+
const config = parse(content);
|
|
5557
|
+
currentSyncedVersion = config.last_synced_version;
|
|
5558
|
+
} catch (e) {
|
|
5559
|
+
}
|
|
5560
|
+
}
|
|
5561
|
+
const driftReport = DriftService.checkDrift(dataPaths[0], currentSyncedVersion, runningVersion);
|
|
5562
|
+
const ideTargets = [];
|
|
5563
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5564
|
+
const configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
5565
|
+
if (configContent.includes("opencode: true")) ideTargets.push("OpenCode agents");
|
|
5566
|
+
if (configContent.includes("copilot: true")) ideTargets.push("GitHub Copilot");
|
|
5567
|
+
if (configContent.includes("antigravity: true")) ideTargets.push("Antigravity");
|
|
5568
|
+
}
|
|
5569
|
+
for (const dataPath of dataPaths) {
|
|
5570
|
+
const dirs = ["templates", "prompts", "docs"];
|
|
5571
|
+
const updatedFiles = [];
|
|
5572
|
+
for (const dir of dirs) {
|
|
5573
|
+
const srcDir = path22.join(agentCoreDir, dir);
|
|
5574
|
+
if (!fs21.existsSync(srcDir)) continue;
|
|
5575
|
+
const syncFiles = (src, rel) => {
|
|
5576
|
+
const entries = fs21.readdirSync(src, { withFileTypes: true });
|
|
5577
|
+
for (const entry of entries) {
|
|
5578
|
+
const entrySrc = path22.join(src, entry.name);
|
|
5579
|
+
const entryRel = path22.join(rel, entry.name);
|
|
5580
|
+
const entryDest = path22.join(dataPath, entryRel);
|
|
5581
|
+
if (entry.isDirectory()) {
|
|
5582
|
+
ensureDir(entryDest);
|
|
5583
|
+
syncFiles(entrySrc, entryRel);
|
|
5584
|
+
} else {
|
|
5585
|
+
if (driftReport.modifiedFiles.includes(entryRel)) {
|
|
5586
|
+
backupFile(entryDest);
|
|
5587
|
+
}
|
|
5588
|
+
fs21.copyFileSync(entrySrc, entryDest);
|
|
5589
|
+
updatedFiles.push(entryRel);
|
|
5590
|
+
}
|
|
5591
|
+
}
|
|
5592
|
+
};
|
|
5593
|
+
syncFiles(srcDir, dir);
|
|
5594
|
+
}
|
|
5595
|
+
const manifest = DriftService.generateManifest(dataPath, updatedFiles);
|
|
5596
|
+
DriftService.saveManifest(dataPath, manifest);
|
|
5597
|
+
}
|
|
5598
|
+
const rrceHome = customGlobalPath || getDefaultRRCEHome2();
|
|
5599
|
+
ensureDir(path22.join(rrceHome, "templates"));
|
|
5600
|
+
ensureDir(path22.join(rrceHome, "docs"));
|
|
5601
|
+
copyDirRecursive(path22.join(agentCoreDir, "templates"), path22.join(rrceHome, "templates"));
|
|
5602
|
+
copyDirRecursive(path22.join(agentCoreDir, "docs"), path22.join(rrceHome, "docs"));
|
|
5603
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5604
|
+
const configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
5605
|
+
if (configContent.includes("copilot: true")) {
|
|
5606
|
+
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
5607
|
+
ensureDir(copilotPath);
|
|
5608
|
+
clearDirectory(copilotPath);
|
|
5609
|
+
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
5610
|
+
}
|
|
5611
|
+
if (configContent.includes("antigravity: true")) {
|
|
5612
|
+
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
5613
|
+
ensureDir(antigravityPath);
|
|
5614
|
+
clearDirectory(antigravityPath);
|
|
5615
|
+
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
5616
|
+
}
|
|
5617
|
+
if (configContent.includes("opencode: true")) {
|
|
5618
|
+
const primaryDataPath = dataPaths[0];
|
|
5619
|
+
if (primaryDataPath) {
|
|
5620
|
+
surgicalUpdateOpenCodeAgents(prompts, mode, primaryDataPath);
|
|
5621
|
+
}
|
|
5622
|
+
}
|
|
5623
|
+
try {
|
|
5624
|
+
const yaml = parse(configContent);
|
|
5625
|
+
yaml.last_synced_version = runningVersion;
|
|
5626
|
+
fs21.writeFileSync(configFilePath, stringify2(yaml));
|
|
5627
|
+
} catch (e) {
|
|
5628
|
+
console.error("Failed to update config.yaml version:", e);
|
|
5629
|
+
}
|
|
5630
|
+
}
|
|
5631
|
+
const mcpPath = path22.join(rrceHome, "mcp.yaml");
|
|
5632
|
+
if (fs21.existsSync(mcpPath)) {
|
|
5633
|
+
try {
|
|
5634
|
+
const content = fs21.readFileSync(mcpPath, "utf-8");
|
|
5635
|
+
const yaml = parse(content);
|
|
5636
|
+
if (yaml.projects) {
|
|
5637
|
+
const project = yaml.projects.find((p) => p.name === workspaceName);
|
|
5638
|
+
if (project) {
|
|
5639
|
+
project.last_synced_version = runningVersion;
|
|
5640
|
+
fs21.writeFileSync(mcpPath, stringify2(yaml));
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5643
|
+
} catch (e) {
|
|
5644
|
+
console.error("Failed to update mcp.yaml version:", e);
|
|
5645
|
+
}
|
|
5646
|
+
}
|
|
5647
|
+
return {
|
|
5648
|
+
success: true,
|
|
5649
|
+
ideTargets,
|
|
5650
|
+
modifiedFiles: driftReport.modifiedFiles
|
|
5651
|
+
};
|
|
5652
|
+
}
|
|
5653
|
+
async function runSilentUpdate(workspacePath, workspaceName, currentStorageMode) {
|
|
5654
|
+
const s = spinner2();
|
|
5655
|
+
s.start("Applying updates...");
|
|
5656
|
+
try {
|
|
5657
|
+
await performUpdate(workspacePath, workspaceName, currentStorageMode, { silent: true });
|
|
5658
|
+
s.stop("Updates applied");
|
|
5659
|
+
} catch (error) {
|
|
5660
|
+
s.stop("Update failed");
|
|
5661
|
+
throw error;
|
|
5662
|
+
}
|
|
5663
|
+
}
|
|
5664
|
+
async function runUpdateFlow(workspacePath, workspaceName, currentStorageMode) {
|
|
5665
|
+
const s = spinner2();
|
|
5666
|
+
s.start("Checking for updates");
|
|
5667
|
+
try {
|
|
5668
|
+
const agentCoreDir = getAgentCoreDir();
|
|
5669
|
+
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
5670
|
+
const runningVersion = getPackageVersion2();
|
|
5671
|
+
const mode = currentStorageMode || "global";
|
|
5672
|
+
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
5673
|
+
const dataPaths = resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspacePath, customGlobalPath);
|
|
5674
|
+
const configFilePath = getConfigPath(workspacePath);
|
|
5675
|
+
let currentSyncedVersion;
|
|
5676
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5677
|
+
try {
|
|
5678
|
+
const content = fs21.readFileSync(configFilePath, "utf-8");
|
|
5679
|
+
const config = parse(content);
|
|
5680
|
+
currentSyncedVersion = config.last_synced_version;
|
|
5681
|
+
} catch (e) {
|
|
5682
|
+
}
|
|
5683
|
+
}
|
|
5684
|
+
const driftReport = DriftService.checkDrift(dataPaths[0], currentSyncedVersion, runningVersion);
|
|
5685
|
+
s.stop("Updates found");
|
|
5686
|
+
if (driftReport.type === "version") {
|
|
5687
|
+
note6(`New version available: ${pc8.green(runningVersion)} (Current synced: ${pc8.dim(currentSyncedVersion || "None")})`, "Update Available");
|
|
5688
|
+
}
|
|
5689
|
+
if (driftReport.modifiedFiles.length > 0) {
|
|
5690
|
+
note6(
|
|
5691
|
+
pc8.yellow(`The following files have been modified and will be backed up before updating:
|
|
5692
|
+
`) + driftReport.modifiedFiles.map((f) => ` \u2022 ${f}`).join("\n"),
|
|
5693
|
+
"Modifications Detected"
|
|
5694
|
+
);
|
|
5695
|
+
}
|
|
5696
|
+
const updateTargets = [
|
|
5697
|
+
` \u2022 prompts/ (${prompts.length} agent prompts)`,
|
|
5698
|
+
` \u2022 templates/ (output templates)`,
|
|
5699
|
+
` \u2022 docs/ (documentation)`
|
|
5700
|
+
];
|
|
5701
|
+
const ideTargets = [];
|
|
5702
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5703
|
+
const configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
5704
|
+
if (configContent.includes("opencode: true")) ideTargets.push("OpenCode agents");
|
|
5705
|
+
if (configContent.includes("copilot: true")) ideTargets.push("GitHub Copilot");
|
|
5706
|
+
if (configContent.includes("antigravity: true")) ideTargets.push("Antigravity");
|
|
5707
|
+
}
|
|
5708
|
+
if (ideTargets.length > 0) {
|
|
5709
|
+
updateTargets.push(` \u2022 IDE integrations: ${ideTargets.join(", ")}`);
|
|
5710
|
+
}
|
|
5711
|
+
note6(
|
|
5712
|
+
`The following will be updated from the package:
|
|
5713
|
+
${updateTargets.join("\n")}
|
|
5714
|
+
|
|
5715
|
+
Target locations:
|
|
5716
|
+
${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
|
|
5717
|
+
"Update Preview"
|
|
5718
|
+
);
|
|
5719
|
+
const shouldUpdate = await confirm5({
|
|
5720
|
+
message: "Proceed with update?",
|
|
5721
|
+
initialValue: true
|
|
5722
|
+
});
|
|
5723
|
+
if (isCancel7(shouldUpdate) || !shouldUpdate) {
|
|
5724
|
+
outro2("Update cancelled.");
|
|
5725
|
+
return;
|
|
5726
|
+
}
|
|
5727
|
+
s.start("Updating from package");
|
|
5728
|
+
for (const dataPath of dataPaths) {
|
|
5729
|
+
const dirs = ["templates", "prompts", "docs"];
|
|
5730
|
+
const updatedFiles = [];
|
|
5731
|
+
for (const dir of dirs) {
|
|
5732
|
+
const srcDir = path22.join(agentCoreDir, dir);
|
|
5733
|
+
if (!fs21.existsSync(srcDir)) continue;
|
|
5734
|
+
const syncFiles = (src, rel) => {
|
|
5735
|
+
const entries = fs21.readdirSync(src, { withFileTypes: true });
|
|
5736
|
+
for (const entry of entries) {
|
|
5737
|
+
const entrySrc = path22.join(src, entry.name);
|
|
5738
|
+
const entryRel = path22.join(rel, entry.name);
|
|
5739
|
+
const entryDest = path22.join(dataPath, entryRel);
|
|
5740
|
+
if (entry.isDirectory()) {
|
|
5741
|
+
ensureDir(entryDest);
|
|
5742
|
+
syncFiles(entrySrc, entryRel);
|
|
5743
|
+
} else {
|
|
5744
|
+
if (driftReport.modifiedFiles.includes(entryRel)) {
|
|
5745
|
+
backupFile(entryDest);
|
|
5746
|
+
}
|
|
5747
|
+
fs21.copyFileSync(entrySrc, entryDest);
|
|
5748
|
+
updatedFiles.push(entryRel);
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
};
|
|
5752
|
+
syncFiles(srcDir, dir);
|
|
5753
|
+
}
|
|
5754
|
+
const manifest = DriftService.generateManifest(dataPath, updatedFiles);
|
|
5755
|
+
DriftService.saveManifest(dataPath, manifest);
|
|
5756
|
+
}
|
|
5757
|
+
const rrceHome = customGlobalPath || getDefaultRRCEHome2();
|
|
5758
|
+
ensureDir(path22.join(rrceHome, "templates"));
|
|
5759
|
+
ensureDir(path22.join(rrceHome, "docs"));
|
|
5760
|
+
copyDirRecursive(path22.join(agentCoreDir, "templates"), path22.join(rrceHome, "templates"));
|
|
5761
|
+
copyDirRecursive(path22.join(agentCoreDir, "docs"), path22.join(rrceHome, "docs"));
|
|
5762
|
+
if (fs21.existsSync(configFilePath)) {
|
|
5763
|
+
const configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
5764
|
+
if (configContent.includes("copilot: true")) {
|
|
5765
|
+
const copilotPath = getAgentPromptPath(workspacePath, "copilot");
|
|
5766
|
+
ensureDir(copilotPath);
|
|
5767
|
+
clearDirectory(copilotPath);
|
|
5768
|
+
copyPromptsToDir(prompts, copilotPath, ".agent.md");
|
|
5769
|
+
}
|
|
5770
|
+
if (configContent.includes("antigravity: true")) {
|
|
5771
|
+
const antigravityPath = getAgentPromptPath(workspacePath, "antigravity");
|
|
5772
|
+
ensureDir(antigravityPath);
|
|
5773
|
+
clearDirectory(antigravityPath);
|
|
5774
|
+
copyPromptsToDir(prompts, antigravityPath, ".md");
|
|
5775
|
+
}
|
|
5776
|
+
if (configContent.includes("opencode: true")) {
|
|
5777
|
+
const primaryDataPath = dataPaths[0];
|
|
5778
|
+
if (primaryDataPath) {
|
|
5779
|
+
surgicalUpdateOpenCodeAgents(prompts, mode, primaryDataPath);
|
|
5780
|
+
}
|
|
5781
|
+
}
|
|
5782
|
+
try {
|
|
5783
|
+
const yaml = parse(configContent);
|
|
5784
|
+
yaml.last_synced_version = runningVersion;
|
|
5785
|
+
fs21.writeFileSync(configFilePath, stringify2(yaml));
|
|
5786
|
+
} catch (e) {
|
|
5787
|
+
console.error("Failed to update config.yaml version:", e);
|
|
5788
|
+
}
|
|
5789
|
+
}
|
|
5790
|
+
const mcpPath = path22.join(rrceHome, "mcp.yaml");
|
|
5791
|
+
if (fs21.existsSync(mcpPath)) {
|
|
5792
|
+
try {
|
|
5793
|
+
const content = fs21.readFileSync(mcpPath, "utf-8");
|
|
5794
|
+
const yaml = parse(content);
|
|
5795
|
+
if (yaml.projects) {
|
|
5796
|
+
const project = yaml.projects.find((p) => p.name === workspaceName);
|
|
5797
|
+
if (project) {
|
|
5798
|
+
project.last_synced_version = runningVersion;
|
|
5799
|
+
fs21.writeFileSync(mcpPath, stringify2(yaml));
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5802
|
+
} catch (e) {
|
|
5803
|
+
console.error("Failed to update mcp.yaml version:", e);
|
|
5804
|
+
}
|
|
5805
|
+
}
|
|
5806
|
+
s.stop("Update complete");
|
|
5807
|
+
const summary = [
|
|
5808
|
+
`Updated:`,
|
|
5809
|
+
` \u2713 ${prompts.length} agent prompts`,
|
|
5810
|
+
` \u2713 Output templates`,
|
|
5811
|
+
` \u2713 Documentation`
|
|
5812
|
+
];
|
|
5813
|
+
if (ideTargets.length > 0) {
|
|
5814
|
+
summary.push(` \u2713 IDE integrations: ${ideTargets.join(", ")}`);
|
|
5815
|
+
}
|
|
5816
|
+
if (driftReport.modifiedFiles.length > 0) {
|
|
5817
|
+
summary.push(` \u2713 ${driftReport.modifiedFiles.length} modified files backed up`);
|
|
5818
|
+
}
|
|
5819
|
+
summary.push(
|
|
5820
|
+
``,
|
|
5821
|
+
`Your configuration and knowledge files were preserved.`,
|
|
5822
|
+
``,
|
|
5823
|
+
pc8.dim(`\u{1F4A1} If using OpenCode, you may need to reload for changes to take effect.`)
|
|
5824
|
+
);
|
|
5825
|
+
note6(summary.join("\n"), "Update Summary");
|
|
5826
|
+
outro2(pc8.green("\u2713 Successfully updated from package!"));
|
|
5827
|
+
} catch (error) {
|
|
5828
|
+
s.stop("Error occurred");
|
|
5829
|
+
cancel2(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
|
|
5830
|
+
process.exit(1);
|
|
5831
|
+
}
|
|
5832
|
+
}
|
|
5833
|
+
function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
5834
|
+
const globalPath = path22.join(customGlobalPath, "workspaces", workspaceName);
|
|
5835
|
+
const workspacePath = path22.join(workspaceRoot, ".rrce-workflow");
|
|
5836
|
+
switch (mode) {
|
|
5837
|
+
case "global":
|
|
5838
|
+
return [globalPath];
|
|
5839
|
+
case "workspace":
|
|
5840
|
+
return [workspacePath];
|
|
5841
|
+
default:
|
|
5842
|
+
return [globalPath];
|
|
5843
|
+
}
|
|
5844
|
+
}
|
|
5845
|
+
var init_update_flow = __esm({
|
|
5846
|
+
"src/commands/wizard/update-flow.ts"() {
|
|
5847
|
+
"use strict";
|
|
5848
|
+
init_paths();
|
|
5849
|
+
init_prompts();
|
|
5850
|
+
init_utils();
|
|
5851
|
+
init_drift_service();
|
|
5852
|
+
}
|
|
5853
|
+
});
|
|
5854
|
+
|
|
5855
|
+
// src/commands/wizard/index.ts
|
|
5856
|
+
import { intro as intro2, select as select5, spinner as spinner7, note as note11, outro as outro7, isCancel as isCancel12, confirm as confirm10 } from "@clack/prompts";
|
|
5857
|
+
import pc13 from "picocolors";
|
|
5858
|
+
import * as fs25 from "fs";
|
|
5859
|
+
import * as path24 from "path";
|
|
5860
|
+
import { parse as parse2 } from "yaml";
|
|
5861
|
+
|
|
5862
|
+
// src/lib/git.ts
|
|
5373
5863
|
import { execSync } from "child_process";
|
|
5374
5864
|
function getGitUser() {
|
|
5375
5865
|
try {
|
|
@@ -5383,13 +5873,15 @@ function getGitUser() {
|
|
|
5383
5873
|
// src/commands/wizard/index.ts
|
|
5384
5874
|
init_paths();
|
|
5385
5875
|
init_detection_service();
|
|
5876
|
+
init_prompts();
|
|
5386
5877
|
|
|
5387
5878
|
// src/commands/wizard/setup-flow.ts
|
|
5388
|
-
import { spinner as
|
|
5389
|
-
import
|
|
5879
|
+
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";
|
|
5880
|
+
import pc9 from "picocolors";
|
|
5390
5881
|
init_detection();
|
|
5391
5882
|
init_tui_utils();
|
|
5392
5883
|
init_install();
|
|
5884
|
+
init_paths();
|
|
5393
5885
|
|
|
5394
5886
|
// src/commands/wizard/setup-prompts.ts
|
|
5395
5887
|
init_install();
|
|
@@ -5505,108 +5997,29 @@ async function promptConfirmation() {
|
|
|
5505
5997
|
// src/commands/wizard/setup-actions.ts
|
|
5506
5998
|
init_paths();
|
|
5507
5999
|
init_prompts();
|
|
6000
|
+
init_utils();
|
|
5508
6001
|
import * as fs10 from "fs";
|
|
5509
6002
|
import * as path12 from "path";
|
|
5510
6003
|
import pc4 from "picocolors";
|
|
5511
6004
|
import { note as note2 } from "@clack/prompts";
|
|
5512
|
-
import { stringify as stringify2 } from "yaml";
|
|
5513
6005
|
|
|
5514
|
-
// src/commands/wizard/
|
|
6006
|
+
// src/commands/wizard/vscode.ts
|
|
5515
6007
|
init_paths();
|
|
5516
|
-
|
|
5517
|
-
import * as
|
|
5518
|
-
import * as
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
}
|
|
5529
|
-
|
|
5530
|
-
|
|
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
|
-
|
|
5593
|
-
// src/commands/wizard/vscode.ts
|
|
5594
|
-
init_paths();
|
|
5595
|
-
init_detection();
|
|
5596
|
-
import * as fs8 from "fs";
|
|
5597
|
-
import * as path9 from "path";
|
|
5598
|
-
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
5599
|
-
const workspaceFilePath = path9.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
5600
|
-
let workspace;
|
|
5601
|
-
if (fs8.existsSync(workspaceFilePath)) {
|
|
5602
|
-
try {
|
|
5603
|
-
const content = fs8.readFileSync(workspaceFilePath, "utf-8");
|
|
5604
|
-
workspace = JSON.parse(content);
|
|
5605
|
-
} catch {
|
|
5606
|
-
workspace = { folders: [], settings: {} };
|
|
5607
|
-
}
|
|
5608
|
-
} else {
|
|
5609
|
-
workspace = { folders: [], settings: {} };
|
|
6008
|
+
init_detection();
|
|
6009
|
+
import * as fs8 from "fs";
|
|
6010
|
+
import * as path9 from "path";
|
|
6011
|
+
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
6012
|
+
const workspaceFilePath = path9.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
6013
|
+
let workspace;
|
|
6014
|
+
if (fs8.existsSync(workspaceFilePath)) {
|
|
6015
|
+
try {
|
|
6016
|
+
const content = fs8.readFileSync(workspaceFilePath, "utf-8");
|
|
6017
|
+
workspace = JSON.parse(content);
|
|
6018
|
+
} catch {
|
|
6019
|
+
workspace = { folders: [], settings: {} };
|
|
6020
|
+
}
|
|
6021
|
+
} else {
|
|
6022
|
+
workspace = { folders: [], settings: {} };
|
|
5610
6023
|
}
|
|
5611
6024
|
if (!workspace.settings) {
|
|
5612
6025
|
workspace.settings = {};
|
|
@@ -5677,6 +6090,46 @@ function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, c
|
|
|
5677
6090
|
|
|
5678
6091
|
// src/commands/wizard/setup-actions.ts
|
|
5679
6092
|
init_install();
|
|
6093
|
+
function detectExistingProject(workspacePath, workspaceName, globalPath) {
|
|
6094
|
+
const rrceHome = globalPath || getDefaultRRCEHome2();
|
|
6095
|
+
const globalConfigPath = path12.join(rrceHome, "workspaces", workspaceName, "config.yaml");
|
|
6096
|
+
const workspaceConfigPath = path12.join(workspacePath, ".rrce-workflow", "config.yaml");
|
|
6097
|
+
const hasOpenCodeAgents = checkForRRCEAgents();
|
|
6098
|
+
if (fs10.existsSync(globalConfigPath)) {
|
|
6099
|
+
return {
|
|
6100
|
+
isExisting: true,
|
|
6101
|
+
currentMode: "global",
|
|
6102
|
+
configPath: globalConfigPath
|
|
6103
|
+
};
|
|
6104
|
+
} else if (fs10.existsSync(workspaceConfigPath)) {
|
|
6105
|
+
return {
|
|
6106
|
+
isExisting: true,
|
|
6107
|
+
currentMode: "workspace",
|
|
6108
|
+
configPath: workspaceConfigPath
|
|
6109
|
+
};
|
|
6110
|
+
} else if (hasOpenCodeAgents) {
|
|
6111
|
+
return {
|
|
6112
|
+
isExisting: true,
|
|
6113
|
+
currentMode: null,
|
|
6114
|
+
configPath: null
|
|
6115
|
+
};
|
|
6116
|
+
}
|
|
6117
|
+
return {
|
|
6118
|
+
isExisting: false,
|
|
6119
|
+
currentMode: null,
|
|
6120
|
+
configPath: null
|
|
6121
|
+
};
|
|
6122
|
+
}
|
|
6123
|
+
function checkForRRCEAgents() {
|
|
6124
|
+
if (!fs10.existsSync(OPENCODE_CONFIG)) return false;
|
|
6125
|
+
try {
|
|
6126
|
+
const config = JSON.parse(fs10.readFileSync(OPENCODE_CONFIG, "utf8"));
|
|
6127
|
+
const agentKeys = Object.keys(config.agent || config.agents || {});
|
|
6128
|
+
return agentKeys.some((key) => key.startsWith("rrce_"));
|
|
6129
|
+
} catch {
|
|
6130
|
+
return false;
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
5680
6133
|
function createDirectoryStructure(dataPaths) {
|
|
5681
6134
|
for (const dataPath of dataPaths) {
|
|
5682
6135
|
ensureDir(dataPath);
|
|
@@ -5715,48 +6168,7 @@ async function installAgentPrompts(config, workspacePath, dataPaths) {
|
|
|
5715
6168
|
if (config.tools.includes("opencode")) {
|
|
5716
6169
|
const primaryDataPath = dataPaths[0];
|
|
5717
6170
|
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
|
-
}
|
|
6171
|
+
surgicalUpdateOpenCodeAgents(prompts, config.storageMode, primaryDataPath);
|
|
5760
6172
|
}
|
|
5761
6173
|
}
|
|
5762
6174
|
}
|
|
@@ -5882,8 +6294,8 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5882
6294
|
],
|
|
5883
6295
|
initialValue: "global"
|
|
5884
6296
|
});
|
|
5885
|
-
if (
|
|
5886
|
-
|
|
6297
|
+
if (isCancel8(storageModeResult)) {
|
|
6298
|
+
cancel3("Setup cancelled.");
|
|
5887
6299
|
process.exit(0);
|
|
5888
6300
|
}
|
|
5889
6301
|
const storageMode = storageModeResult;
|
|
@@ -5891,7 +6303,7 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5891
6303
|
if (storageMode === "global") {
|
|
5892
6304
|
customGlobalPath = await resolveGlobalPath();
|
|
5893
6305
|
if (!customGlobalPath) {
|
|
5894
|
-
|
|
6306
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
5895
6307
|
process.exit(0);
|
|
5896
6308
|
}
|
|
5897
6309
|
}
|
|
@@ -5900,8 +6312,8 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5900
6312
|
if (isVSCodeInstalled()) toolsPreview.push("GitHub Copilot");
|
|
5901
6313
|
if (isAntigravityInstalled()) toolsPreview.push("Antigravity");
|
|
5902
6314
|
const toolsText = toolsPreview.length > 0 ? toolsPreview.join(", ") : "None detected";
|
|
5903
|
-
|
|
5904
|
-
`${
|
|
6315
|
+
note7(
|
|
6316
|
+
`${pc9.bold("Express Setup will configure:")}
|
|
5905
6317
|
\u2022 Storage: ${storageMode === "global" ? "Global" : "Workspace"}
|
|
5906
6318
|
\u2022 MCP Server: Enabled
|
|
5907
6319
|
\u2022 Semantic Search (RAG): Enabled
|
|
@@ -5909,12 +6321,12 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5909
6321
|
` : "") + `\u2022 AI Tools: ${toolsText}`,
|
|
5910
6322
|
"Configuration Preview"
|
|
5911
6323
|
);
|
|
5912
|
-
const confirmed = await
|
|
6324
|
+
const confirmed = await confirm6({
|
|
5913
6325
|
message: "Proceed with express setup?",
|
|
5914
6326
|
initialValue: true
|
|
5915
6327
|
});
|
|
5916
|
-
if (
|
|
5917
|
-
|
|
6328
|
+
if (isCancel8(confirmed) || !confirmed) {
|
|
6329
|
+
cancel3("Setup cancelled.");
|
|
5918
6330
|
process.exit(0);
|
|
5919
6331
|
}
|
|
5920
6332
|
const defaultTools = [];
|
|
@@ -5935,19 +6347,63 @@ async function runExpressSetup(workspacePath, workspaceName, existingProjects, s
|
|
|
5935
6347
|
const { updateGitignore: updateGitignore2 } = await Promise.resolve().then(() => (init_gitignore(), gitignore_exports));
|
|
5936
6348
|
updateGitignore2(workspacePath, config.storageMode, config.tools);
|
|
5937
6349
|
}
|
|
5938
|
-
const startMCP = await
|
|
6350
|
+
const startMCP = await confirm6({
|
|
5939
6351
|
message: "Start MCP server now?",
|
|
5940
6352
|
initialValue: true
|
|
5941
6353
|
});
|
|
5942
|
-
if (startMCP && !
|
|
6354
|
+
if (startMCP && !isCancel8(startMCP)) {
|
|
5943
6355
|
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
5944
6356
|
await runMCP2();
|
|
5945
6357
|
} else {
|
|
5946
|
-
|
|
6358
|
+
outro3(pc9.green(`\u2713 Express setup complete! Run ${pc9.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
6359
|
+
}
|
|
6360
|
+
}
|
|
6361
|
+
async function runSetupAsUpdate(workspacePath, workspaceName, currentMode) {
|
|
6362
|
+
let mode = currentMode;
|
|
6363
|
+
if (!mode) {
|
|
6364
|
+
const modeResult = await select3({
|
|
6365
|
+
message: "Storage mode not detected. Please confirm:",
|
|
6366
|
+
options: [
|
|
6367
|
+
{ value: "global", label: "Global (~/.rrce-workflow/)" },
|
|
6368
|
+
{ value: "workspace", label: "Workspace (.rrce-workflow/)" }
|
|
6369
|
+
],
|
|
6370
|
+
initialValue: "global"
|
|
6371
|
+
});
|
|
6372
|
+
if (isCancel8(modeResult)) {
|
|
6373
|
+
cancel3("Setup cancelled.");
|
|
6374
|
+
process.exit(0);
|
|
6375
|
+
}
|
|
6376
|
+
mode = modeResult;
|
|
6377
|
+
}
|
|
6378
|
+
const { runUpdateFlow: runUpdateFlow2 } = await Promise.resolve().then(() => (init_update_flow(), update_flow_exports));
|
|
6379
|
+
await runUpdateFlow2(workspacePath, workspaceName, mode);
|
|
6380
|
+
const startMCP = await confirm6({
|
|
6381
|
+
message: "Start MCP server now?",
|
|
6382
|
+
initialValue: true
|
|
6383
|
+
});
|
|
6384
|
+
if (startMCP && !isCancel8(startMCP)) {
|
|
6385
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6386
|
+
await runMCP2();
|
|
6387
|
+
} else {
|
|
6388
|
+
outro3(pc9.green(`\u2713 Setup complete! Run ${pc9.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
5947
6389
|
}
|
|
5948
6390
|
}
|
|
5949
6391
|
async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
5950
|
-
const
|
|
6392
|
+
const customGlobalPath = getDefaultRRCEHome2();
|
|
6393
|
+
const existingProjectInfo = detectExistingProject(workspacePath, workspaceName, customGlobalPath);
|
|
6394
|
+
if (existingProjectInfo.isExisting) {
|
|
6395
|
+
note7(
|
|
6396
|
+
`${pc9.cyan("\u2139")} Existing RRCE installation detected.
|
|
6397
|
+
Running smart update to sync with latest version.`,
|
|
6398
|
+
"Update Mode"
|
|
6399
|
+
);
|
|
6400
|
+
return runSetupAsUpdate(
|
|
6401
|
+
workspacePath,
|
|
6402
|
+
workspaceName,
|
|
6403
|
+
existingProjectInfo.currentMode
|
|
6404
|
+
);
|
|
6405
|
+
}
|
|
6406
|
+
const s = spinner3();
|
|
5951
6407
|
const setupModeResult = await select3({
|
|
5952
6408
|
message: "Setup mode:",
|
|
5953
6409
|
options: [
|
|
@@ -5956,19 +6412,19 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
5956
6412
|
],
|
|
5957
6413
|
initialValue: "express"
|
|
5958
6414
|
});
|
|
5959
|
-
if (
|
|
5960
|
-
|
|
6415
|
+
if (isCancel8(setupModeResult)) {
|
|
6416
|
+
cancel3("Setup cancelled.");
|
|
5961
6417
|
process.exit(0);
|
|
5962
6418
|
}
|
|
5963
6419
|
if (setupModeResult === "express") {
|
|
5964
6420
|
return runExpressSetup(workspacePath, workspaceName, existingProjects, s);
|
|
5965
6421
|
}
|
|
5966
6422
|
const storageMode = await promptStorageMode();
|
|
5967
|
-
let
|
|
6423
|
+
let resolvedGlobalPath;
|
|
5968
6424
|
if (storageMode === "global") {
|
|
5969
|
-
|
|
5970
|
-
if (!
|
|
5971
|
-
|
|
6425
|
+
resolvedGlobalPath = await resolveGlobalPath();
|
|
6426
|
+
if (!resolvedGlobalPath) {
|
|
6427
|
+
cancel3("Setup cancelled - no global path selected.");
|
|
5972
6428
|
process.exit(0);
|
|
5973
6429
|
}
|
|
5974
6430
|
}
|
|
@@ -5982,12 +6438,12 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
5982
6438
|
const enableRAG = await promptRAG();
|
|
5983
6439
|
const confirmed = await promptConfirmation();
|
|
5984
6440
|
if (!confirmed) {
|
|
5985
|
-
|
|
6441
|
+
outro3("Setup cancelled by user.");
|
|
5986
6442
|
process.exit(0);
|
|
5987
6443
|
}
|
|
5988
6444
|
const config = {
|
|
5989
6445
|
storageMode,
|
|
5990
|
-
globalPath:
|
|
6446
|
+
globalPath: resolvedGlobalPath,
|
|
5991
6447
|
tools,
|
|
5992
6448
|
linkedProjects,
|
|
5993
6449
|
addToGitignore,
|
|
@@ -6016,493 +6472,228 @@ async function executeSetup(config, workspacePath, workspaceName, allProjects, s
|
|
|
6016
6472
|
if (needsVSCodeWorkspace) {
|
|
6017
6473
|
const selectedProjects = allProjects.filter(
|
|
6018
6474
|
(p) => config.linkedProjects.includes(`${p.name}:${p.source}`)
|
|
6019
|
-
);
|
|
6020
|
-
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, config.globalPath);
|
|
6021
|
-
}
|
|
6022
|
-
await registerWithMCP(config, workspacePath, workspaceName);
|
|
6023
|
-
const ideResults = installToSelectedIDEs(config.tools);
|
|
6024
|
-
s.stop("Configuration generated");
|
|
6025
|
-
const dataSummary = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
6026
|
-
const summary = [
|
|
6027
|
-
`${pc8.green("\u2713")} Data stored at: ${pc8.dim(dataSummary[0])}`,
|
|
6028
|
-
config.tools.length > 0 ? `${pc8.green("\u2713")} Tools: ${config.tools.join(", ")}` : null,
|
|
6029
|
-
config.exposeToMCP ? `${pc8.green("\u2713")} MCP server configured` : null,
|
|
6030
|
-
config.enableRAG ? `${pc8.green("\u2713")} Semantic Search enabled` : null,
|
|
6031
|
-
config.linkedProjects.length > 0 ? `${pc8.green("\u2713")} Linked ${config.linkedProjects.length} project(s)` : null,
|
|
6032
|
-
ideResults.success.length > 0 ? `${pc8.green("\u2713")} RRCE installed to: ${ideResults.success.join(", ")}` : null,
|
|
6033
|
-
ideResults.failed.length > 0 ? `${pc8.yellow("\u26A0")} Failed to install to: ${ideResults.failed.join(", ")}` : null
|
|
6034
|
-
].filter(Boolean);
|
|
6035
|
-
if (ideResults.success.length > 0) {
|
|
6036
|
-
summary.push("");
|
|
6037
|
-
summary.push(pc8.dim("\u{1F4A1} You may need to restart your IDE or refresh MCP config for changes to take effect."));
|
|
6038
|
-
}
|
|
6039
|
-
note6(summary.join("\n"), "Setup Complete");
|
|
6040
|
-
} catch (error) {
|
|
6041
|
-
s.stop("Error occurred");
|
|
6042
|
-
cancel2(
|
|
6043
|
-
`Setup failed: ${error instanceof Error ? error.message : String(error)}
|
|
6044
|
-
|
|
6045
|
-
${pc8.dim("Tip: You can re-run the wizard to try again.")}`
|
|
6046
|
-
);
|
|
6047
|
-
process.exit(1);
|
|
6048
|
-
}
|
|
6049
|
-
}
|
|
6050
|
-
async function handlePostSetup(config, workspacePath, workspaceName, linkedProjects) {
|
|
6051
|
-
if (config.exposeToMCP) {
|
|
6052
|
-
const shouldConfigureMCP = await confirm5({
|
|
6053
|
-
message: "Would you like to start the MCP server now?",
|
|
6054
|
-
initialValue: true
|
|
6055
|
-
});
|
|
6056
|
-
if (shouldConfigureMCP && !isCancel7(shouldConfigureMCP)) {
|
|
6057
|
-
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6058
|
-
await runMCP2();
|
|
6059
|
-
} else {
|
|
6060
|
-
if (linkedProjects.length > 0) {
|
|
6061
|
-
outro2(pc8.green(`\u2713 Setup complete! Open ${pc8.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
6062
|
-
} else {
|
|
6063
|
-
outro2(pc8.green(`\u2713 Setup complete! Run ${pc8.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
6064
|
-
}
|
|
6065
|
-
}
|
|
6066
|
-
} else {
|
|
6067
|
-
if (linkedProjects.length > 0) {
|
|
6068
|
-
outro2(pc8.green(`\u2713 Setup complete! Open ${pc8.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
6069
|
-
} else {
|
|
6070
|
-
outro2(pc8.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
6071
|
-
}
|
|
6072
|
-
}
|
|
6073
|
-
}
|
|
6074
|
-
|
|
6075
|
-
// src/commands/wizard/link-flow.ts
|
|
6076
|
-
init_paths();
|
|
6077
|
-
import { multiselect as multiselect4, spinner as spinner3, note as note7, outro as outro3, cancel as cancel3, isCancel as isCancel8, confirm as confirm6 } from "@clack/prompts";
|
|
6078
|
-
import pc9 from "picocolors";
|
|
6079
|
-
import * as fs21 from "fs";
|
|
6080
|
-
init_detection();
|
|
6081
|
-
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
6082
|
-
const projects = scanForProjects({
|
|
6083
|
-
excludeWorkspace: workspaceName,
|
|
6084
|
-
workspacePath
|
|
6085
|
-
});
|
|
6086
|
-
if (projects.length === 0) {
|
|
6087
|
-
outro3(pc9.yellow("No other projects found. Try setting up another project first."));
|
|
6088
|
-
return;
|
|
6089
|
-
}
|
|
6090
|
-
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
6091
|
-
const linkedProjects = await multiselect4({
|
|
6092
|
-
message: "Select projects to link:",
|
|
6093
|
-
options: projects.map((project) => ({
|
|
6094
|
-
value: `${project.name}:${project.source}`,
|
|
6095
|
-
// Unique key
|
|
6096
|
-
label: `${project.name} ${pc9.dim(`(${project.source})`)}`,
|
|
6097
|
-
hint: pc9.dim(
|
|
6098
|
-
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
6099
|
-
)
|
|
6100
|
-
})),
|
|
6101
|
-
required: true
|
|
6102
|
-
});
|
|
6103
|
-
if (isCancel8(linkedProjects)) {
|
|
6104
|
-
cancel3("Cancelled.");
|
|
6105
|
-
process.exit(0);
|
|
6106
|
-
}
|
|
6107
|
-
const selectedKeys = linkedProjects;
|
|
6108
|
-
if (selectedKeys.length === 0) {
|
|
6109
|
-
outro3("No projects selected.");
|
|
6110
|
-
return;
|
|
6111
|
-
}
|
|
6112
|
-
const selectedProjects = projects.filter(
|
|
6113
|
-
(p) => selectedKeys.includes(`${p.name}:${p.source}`)
|
|
6114
|
-
);
|
|
6115
|
-
const s = spinner3();
|
|
6116
|
-
s.start("Linking projects");
|
|
6117
|
-
const configFilePath = getConfigPath(workspacePath);
|
|
6118
|
-
let configContent = fs21.readFileSync(configFilePath, "utf-8");
|
|
6119
|
-
if (configContent.includes("linked_projects:")) {
|
|
6120
|
-
const lines = configContent.split("\n");
|
|
6121
|
-
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
6122
|
-
if (linkedIndex !== -1) {
|
|
6123
|
-
let insertIndex = linkedIndex + 1;
|
|
6124
|
-
while (insertIndex < lines.length && lines[insertIndex]?.startsWith(" - ")) {
|
|
6125
|
-
insertIndex++;
|
|
6126
|
-
}
|
|
6127
|
-
for (const project of selectedProjects) {
|
|
6128
|
-
const entry = ` - ${project.name}:${project.source}`;
|
|
6129
|
-
if (!configContent.includes(entry)) {
|
|
6130
|
-
lines.splice(insertIndex, 0, entry);
|
|
6131
|
-
insertIndex++;
|
|
6132
|
-
}
|
|
6133
|
-
}
|
|
6134
|
-
configContent = lines.join("\n");
|
|
6135
|
-
}
|
|
6136
|
-
} else {
|
|
6137
|
-
configContent += `
|
|
6138
|
-
linked_projects:
|
|
6139
|
-
`;
|
|
6140
|
-
selectedProjects.forEach((project) => {
|
|
6141
|
-
configContent += ` - ${project.name}:${project.source}
|
|
6142
|
-
`;
|
|
6143
|
-
});
|
|
6144
|
-
}
|
|
6145
|
-
fs21.writeFileSync(configFilePath, configContent);
|
|
6146
|
-
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
6147
|
-
s.stop("Projects linked");
|
|
6148
|
-
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
6149
|
-
const summary = [
|
|
6150
|
-
`Linked projects:`,
|
|
6151
|
-
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc9.dim(`(${p.source})`)}`),
|
|
6152
|
-
``,
|
|
6153
|
-
`Workspace file: ${pc9.cyan(workspaceFile)}`
|
|
6154
|
-
];
|
|
6155
|
-
note7(summary.join("\n"), "Link Summary");
|
|
6156
|
-
outro3(pc9.green(`\u2713 Projects linked! Open ${pc9.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
6157
|
-
const shouldExpose = await confirm6({
|
|
6158
|
-
message: "Also expose these linked projects to the MCP server (for Agent access)?",
|
|
6159
|
-
initialValue: true
|
|
6160
|
-
});
|
|
6161
|
-
if (shouldExpose && !isCancel8(shouldExpose)) {
|
|
6162
|
-
try {
|
|
6163
|
-
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6164
|
-
const mcpConfig = loadMCPConfig3();
|
|
6165
|
-
for (const project of selectedProjects) {
|
|
6166
|
-
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
6167
|
-
}
|
|
6168
|
-
saveMCPConfig2(mcpConfig);
|
|
6169
|
-
note7("Projects have been added to the global MCP configuration.", "MCP Updated");
|
|
6170
|
-
} catch (err) {
|
|
6171
|
-
note7(`Failed to update MCP config: ${err}`, "MCP Update Failed");
|
|
6172
|
-
}
|
|
6173
|
-
}
|
|
6174
|
-
}
|
|
6175
|
-
|
|
6176
|
-
// src/commands/wizard/sync-flow.ts
|
|
6177
|
-
init_paths();
|
|
6178
|
-
import { confirm as confirm7, spinner as spinner4, note as note8, outro as outro4, cancel as cancel4, isCancel as isCancel9 } from "@clack/prompts";
|
|
6179
|
-
import pc10 from "picocolors";
|
|
6180
|
-
import * as fs22 from "fs";
|
|
6181
|
-
import * as path22 from "path";
|
|
6182
|
-
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
6183
|
-
const localPath = getLocalWorkspacePath(workspacePath);
|
|
6184
|
-
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
6185
|
-
const globalPath = path22.join(customGlobalPath, "workspaces", workspaceName);
|
|
6186
|
-
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
6187
|
-
const existingDirs = subdirs.filter(
|
|
6188
|
-
(dir) => fs22.existsSync(path22.join(localPath, dir))
|
|
6189
|
-
);
|
|
6190
|
-
if (existingDirs.length === 0) {
|
|
6191
|
-
outro4(pc10.yellow("No data found in workspace storage to sync."));
|
|
6192
|
-
return;
|
|
6193
|
-
}
|
|
6194
|
-
note8(
|
|
6195
|
-
`The following will be copied to global storage:
|
|
6196
|
-
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
6197
|
-
|
|
6198
|
-
Destination: ${pc10.cyan(globalPath)}`,
|
|
6199
|
-
"Sync Preview"
|
|
6200
|
-
);
|
|
6201
|
-
const shouldSync = await confirm7({
|
|
6202
|
-
message: "Proceed with sync to global storage?",
|
|
6203
|
-
initialValue: true
|
|
6204
|
-
});
|
|
6205
|
-
if (isCancel9(shouldSync) || !shouldSync) {
|
|
6206
|
-
outro4("Sync cancelled.");
|
|
6207
|
-
return;
|
|
6208
|
-
}
|
|
6209
|
-
const s = spinner4();
|
|
6210
|
-
s.start("Syncing to global storage");
|
|
6211
|
-
try {
|
|
6212
|
-
ensureDir(globalPath);
|
|
6213
|
-
for (const dir of existingDirs) {
|
|
6214
|
-
const srcDir = path22.join(localPath, dir);
|
|
6215
|
-
const destDir = path22.join(globalPath, dir);
|
|
6216
|
-
ensureDir(destDir);
|
|
6217
|
-
copyDirRecursive(srcDir, destDir);
|
|
6218
|
-
}
|
|
6219
|
-
s.stop("Sync complete");
|
|
6220
|
-
const summary = [
|
|
6221
|
-
`Synced directories:`,
|
|
6222
|
-
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
6223
|
-
``,
|
|
6224
|
-
`Global path: ${pc10.cyan(globalPath)}`,
|
|
6225
|
-
``,
|
|
6226
|
-
`Other projects can now link this knowledge!`
|
|
6227
|
-
];
|
|
6228
|
-
note8(summary.join("\n"), "Sync Summary");
|
|
6229
|
-
outro4(pc10.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
6230
|
-
} catch (error) {
|
|
6231
|
-
s.stop("Error occurred");
|
|
6232
|
-
cancel4(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
6233
|
-
process.exit(1);
|
|
6234
|
-
}
|
|
6235
|
-
}
|
|
6236
|
-
|
|
6237
|
-
// src/commands/wizard/update-flow.ts
|
|
6238
|
-
init_paths();
|
|
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(", ")}`);
|
|
6475
|
+
);
|
|
6476
|
+
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, config.globalPath);
|
|
6421
6477
|
}
|
|
6422
|
-
|
|
6423
|
-
|
|
6478
|
+
await registerWithMCP(config, workspacePath, workspaceName);
|
|
6479
|
+
const ideResults = installToSelectedIDEs(config.tools);
|
|
6480
|
+
s.stop("Configuration generated");
|
|
6481
|
+
const dataSummary = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
6482
|
+
const summary = [
|
|
6483
|
+
`${pc9.green("\u2713")} Data stored at: ${pc9.dim(dataSummary[0])}`,
|
|
6484
|
+
config.tools.length > 0 ? `${pc9.green("\u2713")} Tools: ${config.tools.join(", ")}` : null,
|
|
6485
|
+
config.exposeToMCP ? `${pc9.green("\u2713")} MCP server configured` : null,
|
|
6486
|
+
config.enableRAG ? `${pc9.green("\u2713")} Semantic Search enabled` : null,
|
|
6487
|
+
config.linkedProjects.length > 0 ? `${pc9.green("\u2713")} Linked ${config.linkedProjects.length} project(s)` : null,
|
|
6488
|
+
ideResults.success.length > 0 ? `${pc9.green("\u2713")} RRCE installed to: ${ideResults.success.join(", ")}` : null,
|
|
6489
|
+
ideResults.failed.length > 0 ? `${pc9.yellow("\u26A0")} Failed to install to: ${ideResults.failed.join(", ")}` : null
|
|
6490
|
+
].filter(Boolean);
|
|
6491
|
+
if (ideResults.success.length > 0) {
|
|
6492
|
+
summary.push("");
|
|
6493
|
+
summary.push(pc9.dim("\u{1F4A1} You may need to restart your IDE or refresh MCP config for changes to take effect."));
|
|
6424
6494
|
}
|
|
6425
|
-
summary.
|
|
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!"));
|
|
6495
|
+
note7(summary.join("\n"), "Setup Complete");
|
|
6433
6496
|
} catch (error) {
|
|
6434
6497
|
s.stop("Error occurred");
|
|
6435
|
-
|
|
6498
|
+
cancel3(
|
|
6499
|
+
`Setup failed: ${error instanceof Error ? error.message : String(error)}
|
|
6500
|
+
|
|
6501
|
+
${pc9.dim("Tip: You can re-run the wizard to try again.")}`
|
|
6502
|
+
);
|
|
6436
6503
|
process.exit(1);
|
|
6437
6504
|
}
|
|
6438
6505
|
}
|
|
6439
|
-
function
|
|
6440
|
-
if (
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
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));
|
|
6506
|
+
async function handlePostSetup(config, workspacePath, workspaceName, linkedProjects) {
|
|
6507
|
+
if (config.exposeToMCP) {
|
|
6508
|
+
const shouldConfigureMCP = await confirm6({
|
|
6509
|
+
message: "Would you like to start the MCP server now?",
|
|
6510
|
+
initialValue: true
|
|
6511
|
+
});
|
|
6512
|
+
if (shouldConfigureMCP && !isCancel8(shouldConfigureMCP)) {
|
|
6513
|
+
const { runMCP: runMCP2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
6514
|
+
await runMCP2();
|
|
6515
|
+
} else {
|
|
6516
|
+
if (linkedProjects.length > 0) {
|
|
6517
|
+
outro3(pc9.green(`\u2713 Setup complete! Open ${pc9.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
6518
|
+
} else {
|
|
6519
|
+
outro3(pc9.green(`\u2713 Setup complete! Run ${pc9.cyan("npx rrce-workflow mcp")} to start the server.`));
|
|
6461
6520
|
}
|
|
6462
|
-
} catch (e) {
|
|
6463
|
-
console.error("Failed to update global OpenCode config with agents:", e);
|
|
6464
6521
|
}
|
|
6465
6522
|
} else {
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
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);
|
|
6523
|
+
if (linkedProjects.length > 0) {
|
|
6524
|
+
outro3(pc9.green(`\u2713 Setup complete! Open ${pc9.bold(`${workspaceName}.code-workspace`)} in VSCode.`));
|
|
6525
|
+
} else {
|
|
6526
|
+
outro3(pc9.green(`\u2713 Setup complete! Your agents are ready to use.`));
|
|
6481
6527
|
}
|
|
6482
6528
|
}
|
|
6483
6529
|
}
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6530
|
+
|
|
6531
|
+
// src/commands/wizard/link-flow.ts
|
|
6532
|
+
init_paths();
|
|
6533
|
+
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";
|
|
6534
|
+
import pc10 from "picocolors";
|
|
6535
|
+
import * as fs22 from "fs";
|
|
6536
|
+
init_detection();
|
|
6537
|
+
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
6538
|
+
const projects = scanForProjects({
|
|
6539
|
+
excludeWorkspace: workspaceName,
|
|
6540
|
+
workspacePath
|
|
6541
|
+
});
|
|
6542
|
+
if (projects.length === 0) {
|
|
6543
|
+
outro4(pc10.yellow("No other projects found. Try setting up another project first."));
|
|
6544
|
+
return;
|
|
6545
|
+
}
|
|
6546
|
+
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
6547
|
+
const linkedProjects = await multiselect4({
|
|
6548
|
+
message: "Select projects to link:",
|
|
6549
|
+
options: projects.map((project) => ({
|
|
6550
|
+
value: `${project.name}:${project.source}`,
|
|
6551
|
+
// Unique key
|
|
6552
|
+
label: `${project.name} ${pc10.dim(`(${project.source})`)}`,
|
|
6553
|
+
hint: pc10.dim(
|
|
6554
|
+
project.source === "global" ? `~/.rrce-workflow/workspaces/${project.name}` : project.dataPath
|
|
6555
|
+
)
|
|
6556
|
+
})),
|
|
6557
|
+
required: true
|
|
6558
|
+
});
|
|
6559
|
+
if (isCancel9(linkedProjects)) {
|
|
6560
|
+
cancel4("Cancelled.");
|
|
6561
|
+
process.exit(0);
|
|
6562
|
+
}
|
|
6563
|
+
const selectedKeys = linkedProjects;
|
|
6564
|
+
if (selectedKeys.length === 0) {
|
|
6565
|
+
outro4("No projects selected.");
|
|
6566
|
+
return;
|
|
6567
|
+
}
|
|
6568
|
+
const selectedProjects = projects.filter(
|
|
6569
|
+
(p) => selectedKeys.includes(`${p.name}:${p.source}`)
|
|
6570
|
+
);
|
|
6571
|
+
const s = spinner4();
|
|
6572
|
+
s.start("Linking projects");
|
|
6573
|
+
const configFilePath = getConfigPath(workspacePath);
|
|
6574
|
+
let configContent = fs22.readFileSync(configFilePath, "utf-8");
|
|
6575
|
+
if (configContent.includes("linked_projects:")) {
|
|
6576
|
+
const lines = configContent.split("\n");
|
|
6577
|
+
const linkedIndex = lines.findIndex((l) => l.trim() === "linked_projects:");
|
|
6578
|
+
if (linkedIndex !== -1) {
|
|
6579
|
+
let insertIndex = linkedIndex + 1;
|
|
6580
|
+
while (insertIndex < lines.length && lines[insertIndex]?.startsWith(" - ")) {
|
|
6581
|
+
insertIndex++;
|
|
6582
|
+
}
|
|
6583
|
+
for (const project of selectedProjects) {
|
|
6584
|
+
const entry = ` - ${project.name}:${project.source}`;
|
|
6585
|
+
if (!configContent.includes(entry)) {
|
|
6586
|
+
lines.splice(insertIndex, 0, entry);
|
|
6587
|
+
insertIndex++;
|
|
6588
|
+
}
|
|
6589
|
+
}
|
|
6590
|
+
configContent = lines.join("\n");
|
|
6591
|
+
}
|
|
6592
|
+
} else {
|
|
6593
|
+
configContent += `
|
|
6594
|
+
linked_projects:
|
|
6595
|
+
`;
|
|
6596
|
+
selectedProjects.forEach((project) => {
|
|
6597
|
+
configContent += ` - ${project.name}:${project.source}
|
|
6598
|
+
`;
|
|
6599
|
+
});
|
|
6600
|
+
}
|
|
6601
|
+
fs22.writeFileSync(configFilePath, configContent);
|
|
6602
|
+
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
|
|
6603
|
+
s.stop("Projects linked");
|
|
6604
|
+
const workspaceFile = `${workspaceName}.code-workspace`;
|
|
6605
|
+
const summary = [
|
|
6606
|
+
`Linked projects:`,
|
|
6607
|
+
...selectedProjects.map((p) => ` \u2713 ${p.name} ${pc10.dim(`(${p.source})`)}`),
|
|
6608
|
+
``,
|
|
6609
|
+
`Workspace file: ${pc10.cyan(workspaceFile)}`
|
|
6610
|
+
];
|
|
6611
|
+
note8(summary.join("\n"), "Link Summary");
|
|
6612
|
+
outro4(pc10.green(`\u2713 Projects linked! Open ${pc10.bold(workspaceFile)} in VSCode to access linked data.`));
|
|
6613
|
+
const shouldExpose = await confirm7({
|
|
6614
|
+
message: "Also expose these linked projects to the MCP server (for Agent access)?",
|
|
6615
|
+
initialValue: true
|
|
6616
|
+
});
|
|
6617
|
+
if (shouldExpose && !isCancel9(shouldExpose)) {
|
|
6618
|
+
try {
|
|
6619
|
+
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6620
|
+
const mcpConfig = loadMCPConfig3();
|
|
6621
|
+
for (const project of selectedProjects) {
|
|
6622
|
+
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
6623
|
+
}
|
|
6624
|
+
saveMCPConfig2(mcpConfig);
|
|
6625
|
+
note8("Projects have been added to the global MCP configuration.", "MCP Updated");
|
|
6626
|
+
} catch (err) {
|
|
6627
|
+
note8(`Failed to update MCP config: ${err}`, "MCP Update Failed");
|
|
6490
6628
|
}
|
|
6491
6629
|
}
|
|
6492
6630
|
}
|
|
6493
|
-
|
|
6631
|
+
|
|
6632
|
+
// src/commands/wizard/sync-flow.ts
|
|
6633
|
+
init_paths();
|
|
6634
|
+
init_utils();
|
|
6635
|
+
import { confirm as confirm8, spinner as spinner5, note as note9, outro as outro5, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
|
|
6636
|
+
import pc11 from "picocolors";
|
|
6637
|
+
import * as fs23 from "fs";
|
|
6638
|
+
import * as path23 from "path";
|
|
6639
|
+
async function runSyncToGlobalFlow(workspacePath, workspaceName) {
|
|
6640
|
+
const localPath = getLocalWorkspacePath(workspacePath);
|
|
6641
|
+
const customGlobalPath = getEffectiveRRCEHome(workspacePath);
|
|
6494
6642
|
const globalPath = path23.join(customGlobalPath, "workspaces", workspaceName);
|
|
6495
|
-
const
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6643
|
+
const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
|
|
6644
|
+
const existingDirs = subdirs.filter(
|
|
6645
|
+
(dir) => fs23.existsSync(path23.join(localPath, dir))
|
|
6646
|
+
);
|
|
6647
|
+
if (existingDirs.length === 0) {
|
|
6648
|
+
outro5(pc11.yellow("No data found in workspace storage to sync."));
|
|
6649
|
+
return;
|
|
6650
|
+
}
|
|
6651
|
+
note9(
|
|
6652
|
+
`The following will be copied to global storage:
|
|
6653
|
+
${existingDirs.map((d) => ` \u2022 ${d}/`).join("\n")}
|
|
6654
|
+
|
|
6655
|
+
Destination: ${pc11.cyan(globalPath)}`,
|
|
6656
|
+
"Sync Preview"
|
|
6657
|
+
);
|
|
6658
|
+
const shouldSync = await confirm8({
|
|
6659
|
+
message: "Proceed with sync to global storage?",
|
|
6660
|
+
initialValue: true
|
|
6661
|
+
});
|
|
6662
|
+
if (isCancel10(shouldSync) || !shouldSync) {
|
|
6663
|
+
outro5("Sync cancelled.");
|
|
6664
|
+
return;
|
|
6665
|
+
}
|
|
6666
|
+
const s = spinner5();
|
|
6667
|
+
s.start("Syncing to global storage");
|
|
6668
|
+
try {
|
|
6669
|
+
ensureDir(globalPath);
|
|
6670
|
+
for (const dir of existingDirs) {
|
|
6671
|
+
const srcDir = path23.join(localPath, dir);
|
|
6672
|
+
const destDir = path23.join(globalPath, dir);
|
|
6673
|
+
ensureDir(destDir);
|
|
6674
|
+
copyDirRecursive(srcDir, destDir);
|
|
6675
|
+
}
|
|
6676
|
+
s.stop("Sync complete");
|
|
6677
|
+
const summary = [
|
|
6678
|
+
`Synced directories:`,
|
|
6679
|
+
...existingDirs.map((d) => ` \u2713 ${d}/`),
|
|
6680
|
+
``,
|
|
6681
|
+
`Global path: ${pc11.cyan(globalPath)}`,
|
|
6682
|
+
``,
|
|
6683
|
+
`Other projects can now link this knowledge!`
|
|
6684
|
+
];
|
|
6685
|
+
note9(summary.join("\n"), "Sync Summary");
|
|
6686
|
+
outro5(pc11.green("\u2713 Workspace knowledge synced to global storage!"));
|
|
6687
|
+
} catch (error) {
|
|
6688
|
+
s.stop("Error occurred");
|
|
6689
|
+
cancel5(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
|
|
6690
|
+
process.exit(1);
|
|
6503
6691
|
}
|
|
6504
6692
|
}
|
|
6505
6693
|
|
|
6694
|
+
// src/commands/wizard/index.ts
|
|
6695
|
+
init_update_flow();
|
|
6696
|
+
|
|
6506
6697
|
// src/commands/wizard/delete-flow.ts
|
|
6507
6698
|
import { multiselect as multiselect5, confirm as confirm9, spinner as spinner6, note as note10, cancel as cancel6, isCancel as isCancel11 } from "@clack/prompts";
|
|
6508
6699
|
import pc12 from "picocolors";
|
|
@@ -6570,6 +6761,76 @@ Are you sure?`,
|
|
|
6570
6761
|
// src/commands/wizard/index.ts
|
|
6571
6762
|
init_mcp();
|
|
6572
6763
|
init_config();
|
|
6764
|
+
function getPackageVersion3() {
|
|
6765
|
+
try {
|
|
6766
|
+
const agentCoreDir = getAgentCoreDir();
|
|
6767
|
+
const packageJsonPath = path24.join(path24.dirname(agentCoreDir), "package.json");
|
|
6768
|
+
if (fs25.existsSync(packageJsonPath)) {
|
|
6769
|
+
return JSON.parse(fs25.readFileSync(packageJsonPath, "utf8")).version;
|
|
6770
|
+
}
|
|
6771
|
+
} catch (e) {
|
|
6772
|
+
}
|
|
6773
|
+
return "0.0.0";
|
|
6774
|
+
}
|
|
6775
|
+
function getLastSyncedVersion(workspacePath, workspaceName) {
|
|
6776
|
+
const configFilePath = getConfigPath(workspacePath);
|
|
6777
|
+
if (fs25.existsSync(configFilePath)) {
|
|
6778
|
+
try {
|
|
6779
|
+
const content = fs25.readFileSync(configFilePath, "utf-8");
|
|
6780
|
+
const config = parse2(content);
|
|
6781
|
+
if (config.last_synced_version) {
|
|
6782
|
+
return config.last_synced_version;
|
|
6783
|
+
}
|
|
6784
|
+
} catch (e) {
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
const rrceHome = getEffectiveRRCEHome(workspacePath) || getDefaultRRCEHome2();
|
|
6788
|
+
const mcpPath = path24.join(rrceHome, "mcp.yaml");
|
|
6789
|
+
if (fs25.existsSync(mcpPath)) {
|
|
6790
|
+
try {
|
|
6791
|
+
const content = fs25.readFileSync(mcpPath, "utf-8");
|
|
6792
|
+
const config = parse2(content);
|
|
6793
|
+
const project = config.projects?.find((p) => p.name === workspaceName);
|
|
6794
|
+
if (project?.last_synced_version) {
|
|
6795
|
+
return project.last_synced_version;
|
|
6796
|
+
}
|
|
6797
|
+
} catch (e) {
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
return void 0;
|
|
6801
|
+
}
|
|
6802
|
+
async function checkAndPromptUpdate(workspacePath, workspaceName, currentStorageMode) {
|
|
6803
|
+
const runningVersion = getPackageVersion3();
|
|
6804
|
+
const lastSyncedVersion = getLastSyncedVersion(workspacePath, workspaceName);
|
|
6805
|
+
if (lastSyncedVersion === runningVersion) {
|
|
6806
|
+
return true;
|
|
6807
|
+
}
|
|
6808
|
+
const versionInfo = lastSyncedVersion ? `${pc13.dim(lastSyncedVersion)} \u2192 ${pc13.green(runningVersion)}` : `${pc13.dim("unknown")} \u2192 ${pc13.green(runningVersion)}`;
|
|
6809
|
+
note11(
|
|
6810
|
+
`${pc13.bold(pc13.cyan("Update available!"))} ${versionInfo}
|
|
6811
|
+
|
|
6812
|
+
New prompts, templates, and agent improvements are ready to install.
|
|
6813
|
+
Your custom knowledge and configuration will be preserved.`,
|
|
6814
|
+
"\u{1F4E6} Version Update"
|
|
6815
|
+
);
|
|
6816
|
+
const shouldUpdate = await confirm10({
|
|
6817
|
+
message: "Apply update now?",
|
|
6818
|
+
initialValue: true
|
|
6819
|
+
});
|
|
6820
|
+
if (isCancel12(shouldUpdate)) {
|
|
6821
|
+
return false;
|
|
6822
|
+
}
|
|
6823
|
+
if (shouldUpdate) {
|
|
6824
|
+
await runSilentUpdate(workspacePath, workspaceName, currentStorageMode);
|
|
6825
|
+
note11(
|
|
6826
|
+
`${pc13.green("\u2713")} Updated to version ${pc13.bold(runningVersion)}
|
|
6827
|
+
|
|
6828
|
+
All agent prompts, templates, and IDE integrations have been synced.`,
|
|
6829
|
+
"Update Complete"
|
|
6830
|
+
);
|
|
6831
|
+
}
|
|
6832
|
+
return true;
|
|
6833
|
+
}
|
|
6573
6834
|
async function runWizard() {
|
|
6574
6835
|
intro2(pc13.cyan(pc13.inverse(" RRCE-Workflow Setup ")));
|
|
6575
6836
|
const s = spinner7();
|
|
@@ -6620,24 +6881,22 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
6620
6881
|
const localDataPath = getLocalWorkspacePath(workspacePath);
|
|
6621
6882
|
const hasLocalData = fs25.existsSync(localDataPath);
|
|
6622
6883
|
if (isAlreadyConfigured) {
|
|
6884
|
+
const continueToMenu = await checkAndPromptUpdate(workspacePath, workspaceName, currentStorageMode);
|
|
6885
|
+
if (!continueToMenu) {
|
|
6886
|
+
outro7("Exited.");
|
|
6887
|
+
process.exit(0);
|
|
6888
|
+
}
|
|
6623
6889
|
const menuOptions = [];
|
|
6624
6890
|
menuOptions.push({
|
|
6625
6891
|
value: "mcp",
|
|
6626
|
-
label: "\u{1F50C}
|
|
6627
|
-
hint: "
|
|
6892
|
+
label: "\u{1F50C} MCP Dashboard",
|
|
6893
|
+
hint: "Manage projects & AI integrations"
|
|
6628
6894
|
});
|
|
6629
|
-
if (detectedProjects.some((p) => p.source === "global")) {
|
|
6630
|
-
menuOptions.push({
|
|
6631
|
-
value: "delete-global",
|
|
6632
|
-
label: "\u{1F5D1}\uFE0F Delete global project(s)",
|
|
6633
|
-
hint: "Remove knowledge and configuration"
|
|
6634
|
-
});
|
|
6635
|
-
}
|
|
6636
|
-
if (detectedProjects.length > 0) {
|
|
6895
|
+
if (detectedProjects.some((p) => p.source === "global") || detectedProjects.length > 0) {
|
|
6637
6896
|
menuOptions.push({
|
|
6638
|
-
value: "
|
|
6639
|
-
label: "\u{
|
|
6640
|
-
hint:
|
|
6897
|
+
value: "manage",
|
|
6898
|
+
label: "\u{1F4C1} Manage Projects",
|
|
6899
|
+
hint: "Link, delete, or sync projects"
|
|
6641
6900
|
});
|
|
6642
6901
|
}
|
|
6643
6902
|
if (currentStorageMode === "workspace" && hasLocalData) {
|
|
@@ -6647,11 +6906,10 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
6647
6906
|
hint: "Share knowledge with other projects"
|
|
6648
6907
|
});
|
|
6649
6908
|
}
|
|
6650
|
-
menuOptions.push({ value: "
|
|
6651
|
-
menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
|
|
6909
|
+
menuOptions.push({ value: "advanced", label: "\u2699\uFE0F Advanced", hint: "Update, reconfigure, or troubleshoot" });
|
|
6652
6910
|
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
6653
6911
|
const action = await select5({
|
|
6654
|
-
message: "
|
|
6912
|
+
message: "What would you like to do?",
|
|
6655
6913
|
options: menuOptions
|
|
6656
6914
|
});
|
|
6657
6915
|
if (isCancel12(action) || action === "exit") {
|
|
@@ -6662,23 +6920,62 @@ Workspace: ${pc13.bold(workspaceName)}`,
|
|
|
6662
6920
|
await runMCP();
|
|
6663
6921
|
return;
|
|
6664
6922
|
}
|
|
6665
|
-
if (action === "
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6923
|
+
if (action === "manage") {
|
|
6924
|
+
const manageOptions = [];
|
|
6925
|
+
if (detectedProjects.some((p) => p.source === "global")) {
|
|
6926
|
+
manageOptions.push({
|
|
6927
|
+
value: "delete-global",
|
|
6928
|
+
label: "\u{1F5D1}\uFE0F Delete global project(s)",
|
|
6929
|
+
hint: "Remove knowledge and configuration"
|
|
6930
|
+
});
|
|
6931
|
+
}
|
|
6932
|
+
if (detectedProjects.length > 0) {
|
|
6933
|
+
manageOptions.push({
|
|
6934
|
+
value: "link",
|
|
6935
|
+
label: "\u{1F517} Link other project knowledge",
|
|
6936
|
+
hint: `${detectedProjects.length} projects detected`
|
|
6937
|
+
});
|
|
6938
|
+
}
|
|
6939
|
+
manageOptions.push({ value: "back", label: "\u21A9 Back to main menu" });
|
|
6940
|
+
const manageAction = await select5({
|
|
6941
|
+
message: "Project Management",
|
|
6942
|
+
options: manageOptions
|
|
6943
|
+
});
|
|
6944
|
+
if (isCancel12(manageAction) || manageAction === "back") {
|
|
6945
|
+
return runWizard();
|
|
6946
|
+
}
|
|
6947
|
+
if (manageAction === "delete-global") {
|
|
6948
|
+
await runDeleteGlobalProjectFlow(detectedProjects);
|
|
6949
|
+
return;
|
|
6950
|
+
}
|
|
6951
|
+
if (manageAction === "link") {
|
|
6952
|
+
await runLinkProjectsFlow(workspacePath, workspaceName);
|
|
6953
|
+
return;
|
|
6954
|
+
}
|
|
6672
6955
|
}
|
|
6673
6956
|
if (action === "sync-global") {
|
|
6674
6957
|
await runSyncToGlobalFlow(workspacePath, workspaceName);
|
|
6675
6958
|
return;
|
|
6676
6959
|
}
|
|
6677
|
-
if (action === "
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6960
|
+
if (action === "advanced") {
|
|
6961
|
+
const advancedOptions = [
|
|
6962
|
+
{ value: "update", label: "\u{1F4E6} Manual Update", hint: "Force update from package" },
|
|
6963
|
+
{ value: "reconfigure", label: "\u{1F527} Reconfigure Project", hint: "Change storage mode, tools, etc." },
|
|
6964
|
+
{ value: "back", label: "\u21A9 Back to main menu" }
|
|
6965
|
+
];
|
|
6966
|
+
const advancedAction = await select5({
|
|
6967
|
+
message: "Advanced Options",
|
|
6968
|
+
options: advancedOptions
|
|
6969
|
+
});
|
|
6970
|
+
if (isCancel12(advancedAction) || advancedAction === "back") {
|
|
6971
|
+
return runWizard();
|
|
6972
|
+
}
|
|
6973
|
+
if (advancedAction === "update") {
|
|
6974
|
+
await runUpdateFlow(workspacePath, workspaceName, currentStorageMode);
|
|
6975
|
+
return;
|
|
6976
|
+
}
|
|
6977
|
+
if (advancedAction === "reconfigure") {
|
|
6978
|
+
}
|
|
6682
6979
|
}
|
|
6683
6980
|
}
|
|
6684
6981
|
await runSetupFlow(workspacePath, workspaceName, detectedProjects);
|