rrce-workflow 0.2.24 → 0.2.26
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 +129 -101
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -865,6 +865,13 @@ function getExposedProjects() {
|
|
|
865
865
|
const allProjects = scanForProjects();
|
|
866
866
|
return allProjects.filter((project) => isProjectExposed(config, project.name));
|
|
867
867
|
}
|
|
868
|
+
function detectActiveProject() {
|
|
869
|
+
const exposed = getExposedProjects();
|
|
870
|
+
const cwd = process.cwd();
|
|
871
|
+
const matches = exposed.filter((p) => cwd.startsWith(p.path));
|
|
872
|
+
matches.sort((a, b) => b.path.length - a.path.length);
|
|
873
|
+
return matches[0];
|
|
874
|
+
}
|
|
868
875
|
function getProjectContext(projectName) {
|
|
869
876
|
const config = loadMCPConfig();
|
|
870
877
|
if (!isProjectExposed(config, projectName)) {
|
|
@@ -961,64 +968,46 @@ var init_resources = __esm({
|
|
|
961
968
|
});
|
|
962
969
|
|
|
963
970
|
// src/mcp/prompts.ts
|
|
964
|
-
|
|
971
|
+
function getAllPrompts() {
|
|
972
|
+
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
973
|
+
return prompts.map((p) => {
|
|
974
|
+
const args = [];
|
|
975
|
+
if (p.frontmatter["required-args"]) {
|
|
976
|
+
args.push(...p.frontmatter["required-args"].map((a) => ({
|
|
977
|
+
name: a.name,
|
|
978
|
+
description: a.prompt || a.name,
|
|
979
|
+
required: true
|
|
980
|
+
})));
|
|
981
|
+
}
|
|
982
|
+
if (p.frontmatter["optional-args"]) {
|
|
983
|
+
args.push(...p.frontmatter["optional-args"].map((a) => ({
|
|
984
|
+
name: a.name,
|
|
985
|
+
description: a.prompt || a.name,
|
|
986
|
+
required: false
|
|
987
|
+
})));
|
|
988
|
+
}
|
|
989
|
+
return {
|
|
990
|
+
name: p.frontmatter.name,
|
|
991
|
+
description: p.frontmatter.description,
|
|
992
|
+
arguments: args,
|
|
993
|
+
content: p.content
|
|
994
|
+
};
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
function getPromptDef(name) {
|
|
998
|
+
return getAllPrompts().find((p) => p.name === name);
|
|
999
|
+
}
|
|
1000
|
+
function renderPrompt(content, args) {
|
|
1001
|
+
let rendered = content;
|
|
1002
|
+
for (const [key, val] of Object.entries(args)) {
|
|
1003
|
+
rendered = rendered.replace(new RegExp(`{{${key}}}`, "g"), val);
|
|
1004
|
+
}
|
|
1005
|
+
return rendered;
|
|
1006
|
+
}
|
|
965
1007
|
var init_prompts2 = __esm({
|
|
966
1008
|
"src/mcp/prompts.ts"() {
|
|
967
1009
|
"use strict";
|
|
968
|
-
|
|
969
|
-
{
|
|
970
|
-
name: "init",
|
|
971
|
-
description: "Initialize project context by analyzing codebase structure, tech stack, and conventions",
|
|
972
|
-
file: "init.md",
|
|
973
|
-
arguments: [
|
|
974
|
-
{ name: "PROJECT_NAME", description: "Project name (optional, auto-detected if omitted)", required: false }
|
|
975
|
-
]
|
|
976
|
-
},
|
|
977
|
-
{
|
|
978
|
-
name: "research",
|
|
979
|
-
description: "Research and clarify requirements for a new task",
|
|
980
|
-
file: "research_discussion.md",
|
|
981
|
-
arguments: [
|
|
982
|
-
{ name: "REQUEST", description: "Description of the task or feature to research", required: true },
|
|
983
|
-
{ name: "TASK_SLUG", description: "Kebab-case identifier for the task", required: true },
|
|
984
|
-
{ name: "TITLE", description: "Human-readable title for the task", required: false }
|
|
985
|
-
]
|
|
986
|
-
},
|
|
987
|
-
{
|
|
988
|
-
name: "plan",
|
|
989
|
-
description: "Create an actionable execution plan from research findings",
|
|
990
|
-
file: "planning_orchestrator.md",
|
|
991
|
-
arguments: [
|
|
992
|
-
{ name: "TASK_SLUG", description: "Task slug to create plan for", required: true }
|
|
993
|
-
]
|
|
994
|
-
},
|
|
995
|
-
{
|
|
996
|
-
name: "execute",
|
|
997
|
-
description: "Implement the planned work with code and tests",
|
|
998
|
-
file: "executor.md",
|
|
999
|
-
arguments: [
|
|
1000
|
-
{ name: "TASK_SLUG", description: "Task slug to execute", required: true },
|
|
1001
|
-
{ name: "BRANCH", description: "Git branch reference (optional)", required: false }
|
|
1002
|
-
]
|
|
1003
|
-
},
|
|
1004
|
-
{
|
|
1005
|
-
name: "docs",
|
|
1006
|
-
description: "Generate documentation for completed work",
|
|
1007
|
-
file: "documentation.md",
|
|
1008
|
-
arguments: [
|
|
1009
|
-
{ name: "DOC_TYPE", description: "Type of documentation (api, architecture, runbook, changelog)", required: true },
|
|
1010
|
-
{ name: "TASK_SLUG", description: "Task slug if documenting specific task", required: false }
|
|
1011
|
-
]
|
|
1012
|
-
},
|
|
1013
|
-
{
|
|
1014
|
-
name: "sync",
|
|
1015
|
-
description: "Reconcile knowledge base with actual codebase state",
|
|
1016
|
-
file: "sync.md",
|
|
1017
|
-
arguments: [
|
|
1018
|
-
{ name: "SCOPE", description: "Specific path or module to sync (optional)", required: false }
|
|
1019
|
-
]
|
|
1020
|
-
}
|
|
1021
|
-
];
|
|
1010
|
+
init_prompts();
|
|
1022
1011
|
}
|
|
1023
1012
|
});
|
|
1024
1013
|
|
|
@@ -1033,8 +1022,6 @@ import {
|
|
|
1033
1022
|
ListPromptsRequestSchema,
|
|
1034
1023
|
GetPromptRequestSchema
|
|
1035
1024
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
1036
|
-
import * as fs15 from "fs";
|
|
1037
|
-
import * as path14 from "path";
|
|
1038
1025
|
async function startMCPServer() {
|
|
1039
1026
|
try {
|
|
1040
1027
|
logger.info("Starting MCP Server...");
|
|
@@ -1202,31 +1189,72 @@ function registerToolHandlers(server) {
|
|
|
1202
1189
|
});
|
|
1203
1190
|
}
|
|
1204
1191
|
function registerPromptHandlers(server) {
|
|
1205
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () =>
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1192
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
1193
|
+
logger.debug("Listing prompts");
|
|
1194
|
+
const prompts = getAllPrompts();
|
|
1195
|
+
return {
|
|
1196
|
+
prompts: prompts.map((p) => ({
|
|
1197
|
+
name: p.name,
|
|
1198
|
+
description: p.description,
|
|
1199
|
+
arguments: p.arguments.map((a) => ({
|
|
1200
|
+
name: a.name,
|
|
1201
|
+
description: a.description,
|
|
1202
|
+
required: a.required
|
|
1203
|
+
}))
|
|
1204
|
+
}))
|
|
1205
|
+
};
|
|
1206
|
+
});
|
|
1212
1207
|
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
1213
1208
|
const { name, arguments: args } = request.params;
|
|
1214
1209
|
logger.info(`Getting prompt: ${name}`, args);
|
|
1210
|
+
const promptDef = getPromptDef(name);
|
|
1211
|
+
if (!promptDef) {
|
|
1212
|
+
logger.error(`Prompt not found: ${name}`);
|
|
1213
|
+
throw new Error(`Prompt not found: ${name}`);
|
|
1214
|
+
}
|
|
1215
1215
|
try {
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
promptContent = promptContent.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), String(value));
|
|
1225
|
-
}
|
|
1216
|
+
const providedArgs = args || {};
|
|
1217
|
+
const missingArgs = promptDef.arguments.filter((a) => a.required && !providedArgs[a.name]).map((a) => a.name);
|
|
1218
|
+
if (missingArgs.length > 0) {
|
|
1219
|
+
throw new Error(`Missing required arguments: ${missingArgs.join(", ")}`);
|
|
1220
|
+
}
|
|
1221
|
+
const renderArgs = {};
|
|
1222
|
+
for (const [key, val] of Object.entries(providedArgs)) {
|
|
1223
|
+
renderArgs[key] = String(val);
|
|
1226
1224
|
}
|
|
1225
|
+
const content = renderPrompt(promptDef.content, renderArgs);
|
|
1226
|
+
const projects = getExposedProjects();
|
|
1227
|
+
const activeProject = detectActiveProject();
|
|
1228
|
+
const projectList = projects.map((p) => {
|
|
1229
|
+
const isActive = activeProject && p.dataPath === activeProject.dataPath;
|
|
1230
|
+
return `- ${p.name} (${p.source}) ${isActive ? "**[ACTIVE]**" : ""}`;
|
|
1231
|
+
}).join("\n");
|
|
1232
|
+
let contextPreamble = `
|
|
1233
|
+
Context - Available Projects (MCP Hub):
|
|
1234
|
+
${projectList}
|
|
1235
|
+
`;
|
|
1236
|
+
if (activeProject) {
|
|
1237
|
+
contextPreamble += `
|
|
1238
|
+
Current Active Workspace: ${activeProject.name} (${activeProject.path})
|
|
1239
|
+
`;
|
|
1240
|
+
contextPreamble += `IMPORTANT: Treat '${activeProject.path}' as the {{WORKSPACE_ROOT}}. All relative path operations (file reads/writes) MUST be performed relative to this directory.
|
|
1241
|
+
`;
|
|
1242
|
+
}
|
|
1243
|
+
contextPreamble += `
|
|
1244
|
+
Note: If the user's request refers to a project not listed here, ask them to expose it via 'rrce-workflow mcp configure'.
|
|
1245
|
+
|
|
1246
|
+
---
|
|
1247
|
+
`;
|
|
1227
1248
|
return {
|
|
1228
|
-
|
|
1229
|
-
|
|
1249
|
+
messages: [
|
|
1250
|
+
{
|
|
1251
|
+
role: "user",
|
|
1252
|
+
content: {
|
|
1253
|
+
type: "text",
|
|
1254
|
+
text: contextPreamble + content
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
]
|
|
1230
1258
|
};
|
|
1231
1259
|
} catch (error) {
|
|
1232
1260
|
logger.error(`Failed to get prompt: ${name}`, error);
|
|
@@ -1262,8 +1290,8 @@ var init_server = __esm({
|
|
|
1262
1290
|
});
|
|
1263
1291
|
|
|
1264
1292
|
// src/mcp/install.ts
|
|
1265
|
-
import * as
|
|
1266
|
-
import * as
|
|
1293
|
+
import * as fs15 from "fs";
|
|
1294
|
+
import * as path14 from "path";
|
|
1267
1295
|
import * as os from "os";
|
|
1268
1296
|
function checkInstallStatus() {
|
|
1269
1297
|
return {
|
|
@@ -1272,9 +1300,9 @@ function checkInstallStatus() {
|
|
|
1272
1300
|
};
|
|
1273
1301
|
}
|
|
1274
1302
|
function checkConfigFile(configPath) {
|
|
1275
|
-
if (!
|
|
1303
|
+
if (!fs15.existsSync(configPath)) return false;
|
|
1276
1304
|
try {
|
|
1277
|
-
const content = JSON.parse(
|
|
1305
|
+
const content = JSON.parse(fs15.readFileSync(configPath, "utf-8"));
|
|
1278
1306
|
return !!content.mcpServers?.["rrce"];
|
|
1279
1307
|
} catch {
|
|
1280
1308
|
return false;
|
|
@@ -1282,14 +1310,14 @@ function checkConfigFile(configPath) {
|
|
|
1282
1310
|
}
|
|
1283
1311
|
function installToConfig(target) {
|
|
1284
1312
|
const configPath = target === "antigravity" ? ANTIGRAVITY_CONFIG : CLAUDE_CONFIG;
|
|
1285
|
-
const dir =
|
|
1286
|
-
if (!
|
|
1287
|
-
|
|
1313
|
+
const dir = path14.dirname(configPath);
|
|
1314
|
+
if (!fs15.existsSync(dir)) {
|
|
1315
|
+
fs15.mkdirSync(dir, { recursive: true });
|
|
1288
1316
|
}
|
|
1289
1317
|
let config = { mcpServers: {} };
|
|
1290
|
-
if (
|
|
1318
|
+
if (fs15.existsSync(configPath)) {
|
|
1291
1319
|
try {
|
|
1292
|
-
config = JSON.parse(
|
|
1320
|
+
config = JSON.parse(fs15.readFileSync(configPath, "utf-8"));
|
|
1293
1321
|
} catch {
|
|
1294
1322
|
}
|
|
1295
1323
|
}
|
|
@@ -1300,7 +1328,7 @@ function installToConfig(target) {
|
|
|
1300
1328
|
// -y to avoid interactive prompts
|
|
1301
1329
|
};
|
|
1302
1330
|
try {
|
|
1303
|
-
|
|
1331
|
+
fs15.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
1304
1332
|
return true;
|
|
1305
1333
|
} catch {
|
|
1306
1334
|
return false;
|
|
@@ -1310,8 +1338,8 @@ var ANTIGRAVITY_CONFIG, CLAUDE_CONFIG;
|
|
|
1310
1338
|
var init_install = __esm({
|
|
1311
1339
|
"src/mcp/install.ts"() {
|
|
1312
1340
|
"use strict";
|
|
1313
|
-
ANTIGRAVITY_CONFIG =
|
|
1314
|
-
CLAUDE_CONFIG =
|
|
1341
|
+
ANTIGRAVITY_CONFIG = path14.join(os.homedir(), ".gemini/antigravity/mcp_config.json");
|
|
1342
|
+
CLAUDE_CONFIG = path14.join(os.homedir(), ".config/claude/claude_desktop_config.json");
|
|
1315
1343
|
}
|
|
1316
1344
|
});
|
|
1317
1345
|
|
|
@@ -1429,7 +1457,7 @@ async function handleInstallWizard() {
|
|
|
1429
1457
|
}
|
|
1430
1458
|
}
|
|
1431
1459
|
async function handleStartServer() {
|
|
1432
|
-
const
|
|
1460
|
+
const fs16 = await import("fs");
|
|
1433
1461
|
const { getLogFilePath: getLogFilePath2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
1434
1462
|
const config = loadMCPConfig();
|
|
1435
1463
|
const exposedCount = config.projects.filter((p) => p.expose).length;
|
|
@@ -1478,8 +1506,8 @@ async function handleStartServer() {
|
|
|
1478
1506
|
try {
|
|
1479
1507
|
await startMCPServer();
|
|
1480
1508
|
let lastSize = 0;
|
|
1481
|
-
if (
|
|
1482
|
-
const stats =
|
|
1509
|
+
if (fs16.existsSync(logPath)) {
|
|
1510
|
+
const stats = fs16.statSync(logPath);
|
|
1483
1511
|
lastSize = stats.size;
|
|
1484
1512
|
}
|
|
1485
1513
|
let isRunning = true;
|
|
@@ -1502,10 +1530,10 @@ async function handleStartServer() {
|
|
|
1502
1530
|
process.stdin.on("data", onKey);
|
|
1503
1531
|
const interval = setInterval(() => {
|
|
1504
1532
|
if (!isRunning) return;
|
|
1505
|
-
if (
|
|
1506
|
-
const stats =
|
|
1533
|
+
if (fs16.existsSync(logPath)) {
|
|
1534
|
+
const stats = fs16.statSync(logPath);
|
|
1507
1535
|
if (stats.size > lastSize) {
|
|
1508
|
-
const stream =
|
|
1536
|
+
const stream = fs16.createReadStream(logPath, {
|
|
1509
1537
|
start: lastSize,
|
|
1510
1538
|
end: stats.size,
|
|
1511
1539
|
encoding: "utf-8"
|
|
@@ -1539,8 +1567,8 @@ async function handleStartServer() {
|
|
|
1539
1567
|
}
|
|
1540
1568
|
async function handleConfigureGlobalPath() {
|
|
1541
1569
|
const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
|
|
1542
|
-
const
|
|
1543
|
-
const
|
|
1570
|
+
const fs16 = await import("fs");
|
|
1571
|
+
const path16 = await import("path");
|
|
1544
1572
|
note7(
|
|
1545
1573
|
`MCP Hub requires a ${pc8.bold("global storage path")} to store its configuration
|
|
1546
1574
|
and coordinate across projects.
|
|
@@ -1554,8 +1582,8 @@ locally in each project. MCP needs a central location.`,
|
|
|
1554
1582
|
return false;
|
|
1555
1583
|
}
|
|
1556
1584
|
try {
|
|
1557
|
-
if (!
|
|
1558
|
-
|
|
1585
|
+
if (!fs16.existsSync(resolvedPath)) {
|
|
1586
|
+
fs16.mkdirSync(resolvedPath, { recursive: true });
|
|
1559
1587
|
}
|
|
1560
1588
|
const config = loadMCPConfig();
|
|
1561
1589
|
saveMCPConfig(config);
|
|
@@ -1563,7 +1591,7 @@ locally in each project. MCP needs a central location.`,
|
|
|
1563
1591
|
`${pc8.green("\u2713")} Global path configured: ${pc8.cyan(resolvedPath)}
|
|
1564
1592
|
|
|
1565
1593
|
MCP config will be stored at:
|
|
1566
|
-
${
|
|
1594
|
+
${path16.join(resolvedPath, "mcp.yaml")}`,
|
|
1567
1595
|
"Configuration Saved"
|
|
1568
1596
|
);
|
|
1569
1597
|
return true;
|
|
@@ -2412,9 +2440,9 @@ Workspace: ${pc7.bold(workspaceName)}`,
|
|
|
2412
2440
|
init_prompts();
|
|
2413
2441
|
import { intro as intro3, select as select5, note as note8, cancel as cancel7, isCancel as isCancel8, outro as outro7 } from "@clack/prompts";
|
|
2414
2442
|
import pc9 from "picocolors";
|
|
2415
|
-
import * as
|
|
2443
|
+
import * as path15 from "path";
|
|
2416
2444
|
async function runSelector() {
|
|
2417
|
-
const workspaceName =
|
|
2445
|
+
const workspaceName = path15.basename(process.cwd());
|
|
2418
2446
|
intro3(pc9.cyan(pc9.inverse(` RRCE-Workflow | ${workspaceName} `)));
|
|
2419
2447
|
const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
|
|
2420
2448
|
if (prompts.length === 0) {
|