rrce-workflow 0.2.37 → 0.2.39

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.
Files changed (2) hide show
  1. package/dist/index.js +306 -58
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2121,9 +2121,12 @@ var StatusBoard;
2121
2121
  var init_StatusBoard = __esm({
2122
2122
  "src/mcp/ui/StatusBoard.tsx"() {
2123
2123
  "use strict";
2124
- StatusBoard = ({ exposedLabel, port, pid }) => {
2124
+ StatusBoard = ({ exposedLabel, port, pid, running }) => {
2125
2125
  return /* @__PURE__ */ jsx2(Box2, { borderStyle: "single", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsxs(Text2, { children: [
2126
- "\u{1F4CB} ",
2126
+ running ? /* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u25CF RUNNING" }) : /* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u25CF STOPPED" }),
2127
+ " ",
2128
+ "\u2502",
2129
+ " \u{1F4CB} ",
2127
2130
  /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: exposedLabel }),
2128
2131
  " ",
2129
2132
  "\u2502",
@@ -2185,10 +2188,62 @@ var init_CommandBar = __esm({
2185
2188
  }
2186
2189
  });
2187
2190
 
2188
- // src/mcp/ui/Dashboard.tsx
2191
+ // src/mcp/ui/HelpModal.tsx
2189
2192
  import "react";
2190
- import { Box as Box5 } from "ink";
2193
+ import { Box as Box5, Text as Text5 } from "ink";
2191
2194
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2195
+ var HelpModal;
2196
+ var init_HelpModal = __esm({
2197
+ "src/mcp/ui/HelpModal.tsx"() {
2198
+ "use strict";
2199
+ HelpModal = ({ onClose }) => {
2200
+ return /* @__PURE__ */ jsxs4(Box5, { borderStyle: "double", borderColor: "yellow", padding: 1, flexDirection: "column", children: [
2201
+ /* @__PURE__ */ jsx5(Text5, { bold: true, color: "yellow", children: "\u2328\uFE0F Keyboard Shortcuts" }),
2202
+ /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, children: [
2203
+ /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { bold: true, color: "cyan", children: "Configuration:" }) }),
2204
+ /* @__PURE__ */ jsxs4(Text5, { children: [
2205
+ " ",
2206
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "p" }),
2207
+ " - Configure Projects (Opens Wizard)"
2208
+ ] }),
2209
+ /* @__PURE__ */ jsxs4(Text5, { children: [
2210
+ " ",
2211
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "i" }),
2212
+ " - Install to IDEs (Opens Wizard)"
2213
+ ] }),
2214
+ /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { bold: true, color: "cyan", children: "Server Control:" }) }),
2215
+ /* @__PURE__ */ jsxs4(Text5, { children: [
2216
+ " ",
2217
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "r" }),
2218
+ " - Reload Configuration"
2219
+ ] }),
2220
+ /* @__PURE__ */ jsxs4(Text5, { children: [
2221
+ " ",
2222
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "c" }),
2223
+ " - Clear Logs"
2224
+ ] }),
2225
+ /* @__PURE__ */ jsxs4(Text5, { children: [
2226
+ " ",
2227
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "q" }),
2228
+ " - Stop Server & Exit"
2229
+ ] }),
2230
+ /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { bold: true, color: "cyan", children: "Other:" }) }),
2231
+ /* @__PURE__ */ jsxs4(Text5, { children: [
2232
+ " ",
2233
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "?" }),
2234
+ " - Toggle this Help"
2235
+ ] })
2236
+ ] }),
2237
+ /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "gray", children: "Press '?' again to close" }) })
2238
+ ] });
2239
+ };
2240
+ }
2241
+ });
2242
+
2243
+ // src/mcp/ui/Dashboard.tsx
2244
+ import "react";
2245
+ import { Box as Box6 } from "ink";
2246
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2192
2247
  var Dashboard;
2193
2248
  var init_Dashboard = __esm({
2194
2249
  "src/mcp/ui/Dashboard.tsx"() {
@@ -2197,26 +2252,226 @@ var init_Dashboard = __esm({
2197
2252
  init_StatusBoard();
2198
2253
  init_LogViewer();
2199
2254
  init_CommandBar();
2200
- Dashboard = ({ logs, exposedLabel, port, pid, logHeight }) => {
2201
- return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 0, children: [
2202
- /* @__PURE__ */ jsx5(Header, {}),
2203
- /* @__PURE__ */ jsx5(LogViewer, { logs, height: logHeight }),
2204
- /* @__PURE__ */ jsx5(StatusBoard, { exposedLabel, port, pid }),
2205
- /* @__PURE__ */ jsx5(CommandBar, {})
2255
+ init_HelpModal();
2256
+ Dashboard = ({ logs, exposedLabel, port, pid, running, logHeight, showHelp: showHelp2 }) => {
2257
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", padding: 0, children: [
2258
+ /* @__PURE__ */ jsx6(Header, {}),
2259
+ showHelp2 ? /* @__PURE__ */ jsx6(HelpModal, { onClose: () => {
2260
+ } }) : /* @__PURE__ */ jsx6(LogViewer, { logs, height: logHeight }),
2261
+ /* @__PURE__ */ jsx6(StatusBoard, { exposedLabel, port, pid, running }),
2262
+ /* @__PURE__ */ jsx6(CommandBar, {})
2206
2263
  ] });
2207
2264
  };
2208
2265
  }
2209
2266
  });
2210
2267
 
2268
+ // src/mcp/ui/components/SimpleSelect.tsx
2269
+ import { useState } from "react";
2270
+ import { Box as Box7, Text as Text6, useInput } from "ink";
2271
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2272
+ function SimpleSelect({
2273
+ items,
2274
+ onSelect,
2275
+ isMulti = false,
2276
+ initialSelected = [],
2277
+ onSubmit,
2278
+ onCancel,
2279
+ message
2280
+ }) {
2281
+ const [selectedIndex, setSelectedIndex] = useState(0);
2282
+ const [selectedValues, setSelectedValues] = useState(new Set(initialSelected));
2283
+ useInput((input, key) => {
2284
+ if (key.upArrow) {
2285
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : items.length - 1);
2286
+ }
2287
+ if (key.downArrow) {
2288
+ setSelectedIndex((prev) => prev < items.length - 1 ? prev + 1 : 0);
2289
+ }
2290
+ if (input === " " && isMulti) {
2291
+ const item = items[selectedIndex];
2292
+ if (item) {
2293
+ const newSet = new Set(selectedValues);
2294
+ if (newSet.has(item.value)) {
2295
+ newSet.delete(item.value);
2296
+ } else {
2297
+ newSet.add(item.value);
2298
+ }
2299
+ setSelectedValues(newSet);
2300
+ }
2301
+ }
2302
+ if (key.return) {
2303
+ if (isMulti) {
2304
+ onSubmit?.(Array.from(selectedValues));
2305
+ } else {
2306
+ const item = items[selectedIndex];
2307
+ if (item) onSelect(item);
2308
+ }
2309
+ }
2310
+ if (key.escape) {
2311
+ onCancel?.();
2312
+ }
2313
+ });
2314
+ return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
2315
+ message && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, children: /* @__PURE__ */ jsx7(Text6, { bold: true, children: message }) }),
2316
+ items.map((item, index) => {
2317
+ const isSelected = index === selectedIndex;
2318
+ const isChecked = isMulti && selectedValues.has(item.value);
2319
+ return /* @__PURE__ */ jsxs6(Box7, { children: [
2320
+ /* @__PURE__ */ jsx7(Text6, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
2321
+ isMulti && /* @__PURE__ */ jsx7(Text6, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
2322
+ /* @__PURE__ */ jsx7(Text6, { color: isSelected ? "cyan" : "white", children: item.label })
2323
+ ] }, item.key || String(item.value));
2324
+ }),
2325
+ /* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text6, { color: "gray", children: isMulti ? "Space to toggle, Enter to confirm, Esc to cancel" : "Enter to select, Esc to cancel" }) })
2326
+ ] });
2327
+ }
2328
+ var init_SimpleSelect = __esm({
2329
+ "src/mcp/ui/components/SimpleSelect.tsx"() {
2330
+ "use strict";
2331
+ }
2332
+ });
2333
+
2334
+ // src/mcp/ui/ConfigModal.tsx
2335
+ import { useState as useState2 } from "react";
2336
+ import { Box as Box8 } from "ink";
2337
+ import { jsx as jsx8 } from "react/jsx-runtime";
2338
+ var ConfigModal;
2339
+ var init_ConfigModal = __esm({
2340
+ "src/mcp/ui/ConfigModal.tsx"() {
2341
+ "use strict";
2342
+ init_SimpleSelect();
2343
+ init_config();
2344
+ init_detection();
2345
+ init_config();
2346
+ ConfigModal = ({ onBack }) => {
2347
+ const [config, setConfig] = useState2(loadMCPConfig());
2348
+ const allProjects = scanForProjects();
2349
+ const projectItems = allProjects.map((p) => {
2350
+ const projectConfig = config.projects.find(
2351
+ (c) => c.path && c.path === p.dataPath || !c.path && c.name === p.name
2352
+ );
2353
+ const isExposed = projectConfig ? projectConfig.expose : config.defaults.includeNew;
2354
+ return {
2355
+ label: p.name + ` (${p.source})` + (p.path ? ` - ${p.path}` : ""),
2356
+ value: p.dataPath,
2357
+ // Unique ID
2358
+ key: p.dataPath,
2359
+ exposed: isExposed
2360
+ };
2361
+ });
2362
+ const initialSelected = projectItems.filter((p) => p.exposed).map((p) => p.value);
2363
+ const handleSubmit = (selectedIds) => {
2364
+ let newConfig = { ...config };
2365
+ projectItems.forEach((item) => {
2366
+ const isSelected = selectedIds.includes(item.value);
2367
+ const project = allProjects.find((p) => p.dataPath === item.value);
2368
+ if (project) {
2369
+ newConfig = setProjectConfig(
2370
+ newConfig,
2371
+ project.name,
2372
+ isSelected,
2373
+ void 0,
2374
+ // Keep existing permissions or defaults
2375
+ project.path
2376
+ // Ensure path is stored
2377
+ );
2378
+ }
2379
+ });
2380
+ saveMCPConfig(newConfig);
2381
+ onBack();
2382
+ };
2383
+ return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsx8(
2384
+ SimpleSelect,
2385
+ {
2386
+ message: "Select projects to expose via MCP:",
2387
+ items: projectItems,
2388
+ isMulti: true,
2389
+ initialSelected,
2390
+ onSelect: () => {
2391
+ },
2392
+ onSubmit: handleSubmit,
2393
+ onCancel: onBack
2394
+ }
2395
+ ) });
2396
+ };
2397
+ }
2398
+ });
2399
+
2400
+ // src/mcp/ui/InstallModal.tsx
2401
+ import { useState as useState3 } from "react";
2402
+ import { Box as Box9, Text as Text8 } from "ink";
2403
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2404
+ var InstallModal;
2405
+ var init_InstallModal = __esm({
2406
+ "src/mcp/ui/InstallModal.tsx"() {
2407
+ "use strict";
2408
+ init_SimpleSelect();
2409
+ init_install();
2410
+ init_paths();
2411
+ InstallModal = ({ onBack }) => {
2412
+ const [step, setStep] = useState3("select");
2413
+ const [statusMsg, setStatusMsg] = useState3("");
2414
+ const items = [
2415
+ { label: "VSCode (User Settings)", value: "vscode-global" },
2416
+ { label: "VSCode (Workspace)", value: "vscode-workspace" },
2417
+ { label: "Claude Desktop", value: "claude" },
2418
+ { label: "Antigravity", value: "antigravity" }
2419
+ ];
2420
+ const handleInstall = async (targets) => {
2421
+ setStep("installing");
2422
+ setStatusMsg("Installing...");
2423
+ try {
2424
+ const workspacePath = detectWorkspaceRoot();
2425
+ const results = [];
2426
+ for (const target of targets) {
2427
+ const result = await installToConfig(target, workspacePath);
2428
+ results.push(`${target}: ${result ? "Success" : "Failed"}`);
2429
+ }
2430
+ setStatusMsg(results.join("\n"));
2431
+ setStep("done");
2432
+ } catch (e) {
2433
+ setStatusMsg(`Error: ${e}`);
2434
+ setStep("done");
2435
+ }
2436
+ };
2437
+ if (step === "done") {
2438
+ return /* @__PURE__ */ jsxs7(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "green", padding: 1, children: [
2439
+ /* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "Installation Complete" }),
2440
+ /* @__PURE__ */ jsx9(Text8, { children: statusMsg }),
2441
+ /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(
2442
+ SimpleSelect,
2443
+ {
2444
+ items: [{ label: "Back to Dashboard", value: "back" }],
2445
+ onSelect: onBack
2446
+ }
2447
+ ) })
2448
+ ] });
2449
+ }
2450
+ return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsx9(
2451
+ SimpleSelect,
2452
+ {
2453
+ message: "Select IDEs to install/update MCP config:",
2454
+ items,
2455
+ isMulti: true,
2456
+ onSubmit: handleInstall,
2457
+ onSelect: () => {
2458
+ },
2459
+ onCancel: onBack
2460
+ }
2461
+ ) });
2462
+ };
2463
+ }
2464
+ });
2465
+
2211
2466
  // src/mcp/ui/App.tsx
2212
2467
  var App_exports = {};
2213
2468
  __export(App_exports, {
2214
2469
  App: () => App
2215
2470
  });
2216
- import { useState, useEffect as useEffect2 } from "react";
2217
- import { useInput, useApp } from "ink";
2471
+ import { useState as useState4, useEffect as useEffect3 } from "react";
2472
+ import { useInput as useInput2, useApp } from "ink";
2218
2473
  import fs11 from "fs";
2219
- import { jsx as jsx6 } from "react/jsx-runtime";
2474
+ import { jsx as jsx10 } from "react/jsx-runtime";
2220
2475
  var App;
2221
2476
  var init_App = __esm({
2222
2477
  "src/mcp/ui/App.tsx"() {
@@ -2226,23 +2481,29 @@ var init_App = __esm({
2226
2481
  init_detection();
2227
2482
  init_logger();
2228
2483
  init_server();
2229
- App = ({ onExit, onConfigure, onInstall, initialPort }) => {
2484
+ init_ConfigModal();
2485
+ init_InstallModal();
2486
+ App = ({ onExit, initialPort }) => {
2230
2487
  const { exit } = useApp();
2231
- const [logs, setLogs] = useState([]);
2232
- const [serverInfo, setServerInfo] = useState({
2488
+ const [view, setView] = useState4("dashboard");
2489
+ const [logs, setLogs] = useState4([]);
2490
+ const [serverInfo, setServerInfo] = useState4({
2233
2491
  port: initialPort,
2234
2492
  pid: process.pid,
2235
2493
  running: false
2236
2494
  });
2495
+ const [showHelp2, setShowHelp] = useState4(false);
2237
2496
  const config = loadMCPConfig();
2238
2497
  const projects = scanForProjects();
2239
2498
  const exposedProjects = projects.filter((p) => {
2240
- const cfg = config.projects.find((c) => c.name === p.name);
2499
+ const cfg = config.projects.find(
2500
+ (c) => c.path && c.path === p.dataPath || !c.path && c.name === p.name
2501
+ );
2241
2502
  return cfg?.expose ?? config.defaults.includeNew;
2242
2503
  });
2243
2504
  const exposedNames = exposedProjects.map((p) => p.name).slice(0, 5);
2244
2505
  const exposedLabel = exposedNames.length > 0 ? exposedNames.join(", ") + (exposedProjects.length > 5 ? ` (+${exposedProjects.length - 5} more)` : "") : "(none)";
2245
- useEffect2(() => {
2506
+ useEffect3(() => {
2246
2507
  const start = async () => {
2247
2508
  const status = getMCPServerStatus();
2248
2509
  if (!status.running) {
@@ -2260,7 +2521,7 @@ var init_App = __esm({
2260
2521
  return () => {
2261
2522
  };
2262
2523
  }, []);
2263
- useEffect2(() => {
2524
+ useEffect3(() => {
2264
2525
  const logPath = getLogFilePath();
2265
2526
  let lastSize = 0;
2266
2527
  if (fs11.existsSync(logPath)) {
@@ -2287,19 +2548,17 @@ var init_App = __esm({
2287
2548
  }, 500);
2288
2549
  return () => clearInterval(interval);
2289
2550
  }, []);
2290
- useInput((input, key) => {
2551
+ useInput2((input, key) => {
2291
2552
  if (input === "q" || key.ctrl && input === "c") {
2292
2553
  stopMCPServer();
2293
2554
  onExit();
2294
2555
  exit();
2295
2556
  }
2296
2557
  if (input === "p") {
2297
- onConfigure();
2298
- exit();
2558
+ setView("config");
2299
2559
  }
2300
2560
  if (input === "i") {
2301
- onInstall();
2302
- exit();
2561
+ setView("install");
2303
2562
  }
2304
2563
  if (input === "c") {
2305
2564
  setLogs([]);
@@ -2307,17 +2566,28 @@ var init_App = __esm({
2307
2566
  if (input === "r") {
2308
2567
  setLogs((prev) => [...prev, "[INFO] Config reload requested..."]);
2309
2568
  }
2569
+ if (input === "?") {
2570
+ setShowHelp((prev) => !prev);
2571
+ }
2310
2572
  }, { isActive: true });
2311
2573
  const termHeight = process.stdout.rows || 24;
2312
2574
  const logHeight = Math.max(5, termHeight - 12);
2313
- return /* @__PURE__ */ jsx6(
2575
+ if (view === "config") {
2576
+ return /* @__PURE__ */ jsx10(ConfigModal, { onBack: () => setView("dashboard") });
2577
+ }
2578
+ if (view === "install") {
2579
+ return /* @__PURE__ */ jsx10(InstallModal, { onBack: () => setView("dashboard") });
2580
+ }
2581
+ return /* @__PURE__ */ jsx10(
2314
2582
  Dashboard,
2315
2583
  {
2316
2584
  logs,
2317
2585
  exposedLabel,
2318
2586
  port: serverInfo.port,
2319
2587
  pid: serverInfo.pid,
2320
- logHeight
2588
+ running: serverInfo.running,
2589
+ logHeight,
2590
+ showHelp: showHelp2
2321
2591
  }
2322
2592
  );
2323
2593
  };
@@ -2327,7 +2597,7 @@ var init_App = __esm({
2327
2597
  // src/mcp/commands/start.ts
2328
2598
  import { confirm, isCancel as isCancel4, text } from "@clack/prompts";
2329
2599
  async function handleStartServer() {
2330
- const React7 = await import("react");
2600
+ const React11 = await import("react");
2331
2601
  const { render } = await import("ink");
2332
2602
  const { App: App2 } = await Promise.resolve().then(() => (init_App(), App_exports));
2333
2603
  const config = loadMCPConfig();
@@ -2367,38 +2637,16 @@ async function handleStartServer() {
2367
2637
  initialPort = newPort;
2368
2638
  }
2369
2639
  }
2370
- console.clear();
2371
- let keepRunning = true;
2372
- while (keepRunning) {
2373
- let nextAction = "exit";
2374
- process.stdin.resume();
2375
- const app = render(React7.createElement(App2, {
2376
- initialPort,
2377
- onExit: () => {
2378
- nextAction = "exit";
2379
- },
2380
- onConfigure: () => {
2381
- nextAction = "configure";
2382
- },
2383
- onInstall: () => {
2384
- nextAction = "install";
2385
- }
2386
- }), {
2387
- exitOnCtrlC: false
2388
- // We handle this in App
2389
- });
2390
- await app.waitUntilExit();
2391
- if (nextAction === "exit") {
2392
- keepRunning = false;
2393
- } else if (nextAction === "configure") {
2394
- console.clear();
2395
- await handleConfigure();
2396
- } else if (nextAction === "install") {
2397
- console.clear();
2398
- const workspacePath = detectWorkspaceRoot();
2399
- await runInstallWizard(workspacePath);
2640
+ process.stdin.resume();
2641
+ const app = render(React11.createElement(App2, {
2642
+ initialPort,
2643
+ onExit: () => {
2400
2644
  }
2401
- }
2645
+ }), {
2646
+ exitOnCtrlC: false
2647
+ });
2648
+ await app.waitUntilExit();
2649
+ console.clear();
2402
2650
  }
2403
2651
  var init_start = __esm({
2404
2652
  "src/mcp/commands/start.ts"() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.37",
3
+ "version": "0.2.39",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",