rrce-workflow 0.2.39 → 0.2.40

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 (3) hide show
  1. package/README.md +12 -1
  2. package/dist/index.js +313 -332
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -140,6 +140,7 @@ When you run the wizard on an already-configured project, you'll see:
140
140
  | **Link other project knowledge** | Reference knowledge from other projects in global storage |
141
141
  | **Sync to global storage** | Copy workspace data to global (enables cross-project access) |
142
142
  | **Update from package** | Get latest prompts and templates |
143
+ | **Reconfigure project** | Change storage mode, selected tools, or linked projects without resetting |
143
144
 
144
145
  ---
145
146
 
@@ -291,10 +292,20 @@ Most MCP clients follow similar patterns:
291
292
  Configure which projects to expose:
292
293
 
293
294
  ```bash
294
- npx rrce-workflow mcp # Interactive TUI
295
+ npx rrce-workflow mcp # Interactive TUI Dashboard
295
296
  npx rrce-workflow mcp status # View current status
296
297
  ```
297
298
 
299
+ **Interactive Dashboard Controls:**
300
+ - `p`: Open **Project Configuration** modal (Toggle exposed projects)
301
+ - `i`: Open **IDE Installation** modal (Auto-configure VSCode/Claude)
302
+ - `r`: Reload configuration
303
+ - `c`: Clear logs
304
+ - `?`: Toggle Help & Shortcuts
305
+
306
+ **Unified Context:**
307
+ Projects linked via the main wizard (`Link other project knowledge`) are automatically detected and exposed by the MCP server alongside globally configured projects.
308
+
298
309
  Config stored at `~/.rrce-workflow/mcp.yaml`
299
310
 
300
311
  ---
package/dist/index.js CHANGED
@@ -2141,125 +2141,40 @@ var init_StatusBoard = __esm({
2141
2141
  }
2142
2142
  });
2143
2143
 
2144
- // src/mcp/ui/LogViewer.tsx
2144
+ // src/mcp/ui/Overview.tsx
2145
2145
  import "react";
2146
2146
  import { Box as Box3, Text as Text3 } from "ink";
2147
2147
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
2148
- var LogViewer;
2149
- var init_LogViewer = __esm({
2150
- "src/mcp/ui/LogViewer.tsx"() {
2151
- "use strict";
2152
- LogViewer = ({ logs, height }) => {
2153
- const visibleLogs = logs.slice(-height);
2154
- const emptyLines = Math.max(0, height - visibleLogs.length);
2155
- const padding = Array(emptyLines).fill("");
2156
- return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "dim", paddingX: 1, height: height + 2, flexGrow: 1, children: [
2157
- padding.map((_, i) => /* @__PURE__ */ jsx3(Text3, { children: " " }, `empty-${i}`)),
2158
- visibleLogs.map((log, i) => /* @__PURE__ */ jsx3(Text3, { wrap: "truncate-end", children: log }, `log-${i}`))
2159
- ] });
2160
- };
2161
- }
2162
- });
2163
-
2164
- // src/mcp/ui/CommandBar.tsx
2165
- import "react";
2166
- import { Box as Box4, Text as Text4 } from "ink";
2167
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2168
- var CommandBar;
2169
- var init_CommandBar = __esm({
2170
- "src/mcp/ui/CommandBar.tsx"() {
2171
- "use strict";
2172
- CommandBar = () => {
2173
- return /* @__PURE__ */ jsx4(Box4, { borderStyle: "single", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsxs3(Text4, { children: [
2174
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "q" }),
2175
- ":Quit ",
2176
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "p" }),
2177
- ":Projects ",
2178
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "i" }),
2179
- ":Install ",
2180
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "r" }),
2181
- ":Reload ",
2182
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "c" }),
2183
- ":Clear ",
2184
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "?" }),
2185
- ":Help"
2186
- ] }) });
2187
- };
2188
- }
2189
- });
2190
-
2191
- // src/mcp/ui/HelpModal.tsx
2192
- import "react";
2193
- import { Box as Box5, Text as Text5 } from "ink";
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";
2247
- var Dashboard;
2248
- var init_Dashboard = __esm({
2249
- "src/mcp/ui/Dashboard.tsx"() {
2148
+ var Overview;
2149
+ var init_Overview = __esm({
2150
+ "src/mcp/ui/Overview.tsx"() {
2250
2151
  "use strict";
2251
2152
  init_Header();
2252
2153
  init_StatusBoard();
2253
- init_LogViewer();
2254
- init_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, {})
2154
+ Overview = ({ serverStatus, stats }) => {
2155
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", children: [
2156
+ /* @__PURE__ */ jsx3(Header, {}),
2157
+ /* @__PURE__ */ jsx3(Box3, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx3(
2158
+ StatusBoard,
2159
+ {
2160
+ exposedLabel: `${stats.exposedProjects} / ${stats.totalProjects} projects`,
2161
+ port: serverStatus.port,
2162
+ pid: serverStatus.pid,
2163
+ running: serverStatus.running
2164
+ }
2165
+ ) }),
2166
+ /* @__PURE__ */ jsxs2(Box3, { borderStyle: "round", padding: 1, borderColor: "white", flexDirection: "column", children: [
2167
+ /* @__PURE__ */ jsx3(Text3, { bold: true, underline: true, children: "System Status" }),
2168
+ /* @__PURE__ */ jsxs2(Box3, { marginTop: 1, children: [
2169
+ /* @__PURE__ */ jsx3(Text3, { children: "Integrations Installed: " }),
2170
+ /* @__PURE__ */ jsx3(Text3, { color: stats.installedIntegrations > 0 ? "green" : "yellow", children: stats.installedIntegrations })
2171
+ ] }),
2172
+ /* @__PURE__ */ jsxs2(Box3, { children: [
2173
+ /* @__PURE__ */ jsx3(Text3, { children: "Server Port: " }),
2174
+ /* @__PURE__ */ jsx3(Text3, { color: "cyan", children: serverStatus.port })
2175
+ ] }),
2176
+ /* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx3(Text3, { color: "dim", children: "Press 'q' to stop server and exit." }) })
2177
+ ] })
2263
2178
  ] });
2264
2179
  };
2265
2180
  }
@@ -2267,8 +2182,8 @@ var init_Dashboard = __esm({
2267
2182
 
2268
2183
  // src/mcp/ui/components/SimpleSelect.tsx
2269
2184
  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";
2185
+ import { Box as Box4, Text as Text4, useInput } from "ink";
2186
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2272
2187
  function SimpleSelect({
2273
2188
  items,
2274
2189
  onSelect,
@@ -2311,18 +2226,18 @@ function SimpleSelect({
2311
2226
  onCancel?.();
2312
2227
  }
2313
2228
  });
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 }) }),
2229
+ return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
2230
+ message && /* @__PURE__ */ jsx4(Box4, { marginBottom: 1, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: message }) }),
2316
2231
  items.map((item, index) => {
2317
2232
  const isSelected = index === selectedIndex;
2318
2233
  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 })
2234
+ return /* @__PURE__ */ jsxs3(Box4, { children: [
2235
+ /* @__PURE__ */ jsx4(Text4, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
2236
+ isMulti && /* @__PURE__ */ jsx4(Text4, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
2237
+ /* @__PURE__ */ jsx4(Text4, { color: isSelected ? "cyan" : "white", children: item.label })
2323
2238
  ] }, item.key || String(item.value));
2324
2239
  }),
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" }) })
2240
+ /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text4, { color: "gray", children: isMulti ? "Space to toggle, Enter to confirm, Esc to cancel" : "Enter to select, Esc to cancel" }) })
2326
2241
  ] });
2327
2242
  }
2328
2243
  var init_SimpleSelect = __esm({
@@ -2331,19 +2246,18 @@ var init_SimpleSelect = __esm({
2331
2246
  }
2332
2247
  });
2333
2248
 
2334
- // src/mcp/ui/ConfigModal.tsx
2249
+ // src/mcp/ui/ProjectsView.tsx
2335
2250
  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"() {
2251
+ import { Box as Box5, Text as Text5 } from "ink";
2252
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2253
+ var ProjectsView;
2254
+ var init_ProjectsView = __esm({
2255
+ "src/mcp/ui/ProjectsView.tsx"() {
2341
2256
  "use strict";
2342
2257
  init_SimpleSelect();
2343
2258
  init_config();
2344
2259
  init_detection();
2345
- init_config();
2346
- ConfigModal = ({ onBack }) => {
2260
+ ProjectsView = () => {
2347
2261
  const [config, setConfig] = useState2(loadMCPConfig());
2348
2262
  const allProjects = scanForProjects();
2349
2263
  const projectItems = allProjects.map((p) => {
@@ -2371,94 +2285,215 @@ var init_ConfigModal = __esm({
2371
2285
  project.name,
2372
2286
  isSelected,
2373
2287
  void 0,
2374
- // Keep existing permissions or defaults
2375
2288
  project.path
2376
- // Ensure path is stored
2377
2289
  );
2378
2290
  }
2379
2291
  });
2380
2292
  saveMCPConfig(newConfig);
2381
- onBack();
2293
+ setConfig(newConfig);
2382
2294
  };
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: () => {
2295
+ return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", children: [
2296
+ /* @__PURE__ */ jsx5(Text5, { bold: true, color: "cyan", children: " Exposed Projects " }),
2297
+ /* @__PURE__ */ jsx5(Text5, { color: "dim", children: " Select projects to expose via the MCP server. Use Space to toggle, Enter to save." }),
2298
+ /* @__PURE__ */ jsx5(Box5, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx5(
2299
+ SimpleSelect,
2300
+ {
2301
+ message: "",
2302
+ items: projectItems,
2303
+ isMulti: true,
2304
+ initialSelected,
2305
+ onSelect: () => {
2306
+ },
2307
+ onSubmit: handleSubmit,
2308
+ onCancel: () => {
2309
+ },
2310
+ itemLimit: 10
2391
2311
  },
2392
- onSubmit: handleSubmit,
2393
- onCancel: onBack
2394
- }
2395
- ) });
2312
+ JSON.stringify(initialSelected)
2313
+ ) })
2314
+ ] });
2396
2315
  };
2397
2316
  }
2398
2317
  });
2399
2318
 
2400
- // src/mcp/ui/InstallModal.tsx
2319
+ // src/mcp/ui/components/InstallWizard.tsx
2401
2320
  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"() {
2321
+ import { Box as Box6, Text as Text6 } from "ink";
2322
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2323
+ var InstallWizard;
2324
+ var init_InstallWizard = __esm({
2325
+ "src/mcp/ui/components/InstallWizard.tsx"() {
2407
2326
  "use strict";
2408
2327
  init_SimpleSelect();
2409
2328
  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" }
2329
+ InstallWizard = ({ workspacePath, onComplete, onCancel }) => {
2330
+ const [status, setStatus] = useState3(checkInstallStatus(workspacePath));
2331
+ const [message, setMessage] = useState3("");
2332
+ const options = [
2333
+ {
2334
+ value: "antigravity",
2335
+ label: "Antigravity IDE",
2336
+ hint: status.antigravity ? "INSTALLED" : "Not installed"
2337
+ },
2338
+ {
2339
+ value: "vscode-global",
2340
+ label: "VSCode (Global Settings)",
2341
+ hint: status.vscodeGlobal ? "INSTALLED" : "Not installed"
2342
+ },
2343
+ {
2344
+ value: "vscode-workspace",
2345
+ label: "VSCode (Workspace Config)",
2346
+ hint: status.vscodeWorkspace ? "INSTALLED" : "Not installed"
2347
+ },
2348
+ {
2349
+ value: "claude",
2350
+ label: "Claude Desktop",
2351
+ hint: status.claude ? "INSTALLED" : "Not installed"
2352
+ }
2419
2353
  ];
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"}`);
2354
+ const initialSelected = [
2355
+ ...status.antigravity ? ["antigravity"] : [],
2356
+ ...status.vscodeGlobal ? ["vscode-global"] : [],
2357
+ ...status.vscodeWorkspace ? ["vscode-workspace"] : [],
2358
+ ...status.claude ? ["claude"] : []
2359
+ ];
2360
+ const handleSubmit = (selectedIds) => {
2361
+ const targets = selectedIds;
2362
+ let results = [];
2363
+ targets.forEach((target) => {
2364
+ const success = installToConfig(target, workspacePath);
2365
+ const label = getTargetLabel(target);
2366
+ results.push(`${label}: ${success ? "Success" : "Failed"}`);
2367
+ });
2368
+ setStatus(checkInstallStatus(workspacePath));
2369
+ setMessage(`Installation updated: ${results.join(", ")}`);
2370
+ setTimeout(() => {
2371
+ setMessage("");
2372
+ onComplete();
2373
+ }, 2e3);
2374
+ };
2375
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
2376
+ message && /* @__PURE__ */ jsx6(Text6, { color: "green", children: message }),
2377
+ /* @__PURE__ */ jsx6(
2378
+ SimpleSelect,
2379
+ {
2380
+ message: "Select integrations to install:",
2381
+ items: options.map((o) => ({
2382
+ value: o.value,
2383
+ label: o.label + (o.hint === "INSTALLED" ? " (Installed)" : ""),
2384
+ key: o.value
2385
+ })),
2386
+ isMulti: true,
2387
+ initialSelected,
2388
+ onSelect: () => {
2389
+ },
2390
+ onSubmit: handleSubmit,
2391
+ onCancel
2429
2392
  }
2430
- setStatusMsg(results.join("\n"));
2431
- setStep("done");
2432
- } catch (e) {
2433
- setStatusMsg(`Error: ${e}`);
2434
- setStep("done");
2435
- }
2393
+ )
2394
+ ] });
2395
+ };
2396
+ }
2397
+ });
2398
+
2399
+ // src/mcp/ui/InstallView.tsx
2400
+ import "react";
2401
+ import { Box as Box7, Text as Text7 } from "ink";
2402
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2403
+ var InstallView;
2404
+ var init_InstallView = __esm({
2405
+ "src/mcp/ui/InstallView.tsx"() {
2406
+ "use strict";
2407
+ init_InstallWizard();
2408
+ init_paths();
2409
+ InstallView = () => {
2410
+ const workspacePath = detectWorkspaceRoot();
2411
+ return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "magenta", children: [
2412
+ /* @__PURE__ */ jsx7(Text7, { bold: true, color: "magenta", children: " Installation & Configuration " }),
2413
+ /* @__PURE__ */ jsx7(Text7, { color: "dim", children: " Configure IDE integrations for VSCode, Claude, and Antigravity." }),
2414
+ /* @__PURE__ */ jsx7(Box7, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx7(
2415
+ InstallWizard,
2416
+ {
2417
+ workspacePath,
2418
+ onComplete: () => {
2419
+ },
2420
+ onCancel: () => {
2421
+ }
2422
+ }
2423
+ ) })
2424
+ ] });
2425
+ };
2426
+ }
2427
+ });
2428
+
2429
+ // src/mcp/ui/LogViewer.tsx
2430
+ import "react";
2431
+ import { Box as Box8, Text as Text8 } from "ink";
2432
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2433
+ var LogViewer;
2434
+ var init_LogViewer = __esm({
2435
+ "src/mcp/ui/LogViewer.tsx"() {
2436
+ "use strict";
2437
+ LogViewer = ({ logs, height }) => {
2438
+ const visibleLogs = logs.slice(-height);
2439
+ const emptyLines = Math.max(0, height - visibleLogs.length);
2440
+ const padding = Array(emptyLines).fill("");
2441
+ const formatLog = (log) => {
2442
+ if (log.includes("[ERROR]")) return /* @__PURE__ */ jsx8(Text8, { color: "red", children: log });
2443
+ if (log.includes("[WARN]")) return /* @__PURE__ */ jsx8(Text8, { color: "yellow", children: log });
2444
+ if (log.includes("[INFO]")) return /* @__PURE__ */ jsx8(Text8, { color: "green", children: log });
2445
+ if (log.includes("Success")) return /* @__PURE__ */ jsx8(Text8, { color: "green", children: log });
2446
+ return /* @__PURE__ */ jsx8(Text8, { children: log });
2436
2447
  };
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,
2448
+ return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "dim", paddingX: 1, height: height + 2, flexGrow: 1, children: [
2449
+ padding.map((_, i) => /* @__PURE__ */ jsx8(Text8, { children: " " }, `empty-${i}`)),
2450
+ visibleLogs.map((log, i) => /* @__PURE__ */ jsx8(Box8, { children: formatLog(log) }, `log-${i}`))
2451
+ ] });
2452
+ };
2453
+ }
2454
+ });
2455
+
2456
+ // src/mcp/ui/components/TabBar.tsx
2457
+ import "react";
2458
+ import { Box as Box9, Text as Text9, useInput as useInput2 } from "ink";
2459
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2460
+ var TabBar;
2461
+ var init_TabBar = __esm({
2462
+ "src/mcp/ui/components/TabBar.tsx"() {
2463
+ "use strict";
2464
+ TabBar = ({ tabs, activeTab, onChange }) => {
2465
+ useInput2((input, key) => {
2466
+ if (key.leftArrow) {
2467
+ const index = tabs.findIndex((t) => t.id === activeTab);
2468
+ const nextIndex = (index - 1 + tabs.length) % tabs.length;
2469
+ onChange(tabs[nextIndex].id);
2470
+ }
2471
+ if (key.rightArrow) {
2472
+ const index = tabs.findIndex((t) => t.id === activeTab);
2473
+ const nextIndex = (index + 1) % tabs.length;
2474
+ onChange(tabs[nextIndex].id);
2475
+ }
2476
+ const num = parseInt(input);
2477
+ if (!isNaN(num) && num > 0 && num <= tabs.length) {
2478
+ onChange(tabs[num - 1].id);
2479
+ }
2480
+ });
2481
+ return /* @__PURE__ */ jsxs8(Box9, { borderStyle: "single", paddingX: 1, borderColor: "gray", children: [
2482
+ tabs.map((tab, index) => {
2483
+ const isActive = tab.id === activeTab;
2484
+ return /* @__PURE__ */ jsx9(Box9, { marginRight: 2, children: /* @__PURE__ */ jsx9(
2485
+ Text9,
2443
2486
  {
2444
- items: [{ label: "Back to Dashboard", value: "back" }],
2445
- onSelect: onBack
2487
+ color: isActive ? "cyan" : "gray",
2488
+ bold: isActive,
2489
+ backgroundColor: isActive ? "black" : void 0,
2490
+ children: isActive ? `[ ${tab.label} ]` : ` ${tab.label} `
2446
2491
  }
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
- ) });
2492
+ ) }, tab.id);
2493
+ }),
2494
+ /* @__PURE__ */ jsx9(Box9, { flexGrow: 1 }),
2495
+ /* @__PURE__ */ jsx9(Text9, { color: "dim", children: "Use \u25C4/\u25BA arrows to navigate" })
2496
+ ] });
2462
2497
  };
2463
2498
  }
2464
2499
  });
@@ -2468,31 +2503,40 @@ var App_exports = {};
2468
2503
  __export(App_exports, {
2469
2504
  App: () => App
2470
2505
  });
2471
- import { useState as useState4, useEffect as useEffect3 } from "react";
2472
- import { useInput as useInput2, useApp } from "ink";
2506
+ import { useState as useState4, useEffect as useEffect4 } from "react";
2507
+ import { Box as Box10, useInput as useInput3, useApp } from "ink";
2473
2508
  import fs11 from "fs";
2474
- import { jsx as jsx10 } from "react/jsx-runtime";
2475
- var App;
2509
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2510
+ var TABS, App;
2476
2511
  var init_App = __esm({
2477
2512
  "src/mcp/ui/App.tsx"() {
2478
2513
  "use strict";
2479
- init_Dashboard();
2514
+ init_Overview();
2515
+ init_ProjectsView();
2516
+ init_InstallView();
2517
+ init_LogViewer();
2518
+ init_TabBar();
2480
2519
  init_config();
2481
2520
  init_detection();
2482
2521
  init_logger();
2483
2522
  init_server();
2484
- init_ConfigModal();
2485
- init_InstallModal();
2523
+ init_install();
2524
+ init_paths();
2525
+ TABS = [
2526
+ { id: "overview", label: "Overview" },
2527
+ { id: "projects", label: "Projects" },
2528
+ { id: "install", label: "Install" },
2529
+ { id: "logs", label: "Logs" }
2530
+ ];
2486
2531
  App = ({ onExit, initialPort }) => {
2487
2532
  const { exit } = useApp();
2488
- const [view, setView] = useState4("dashboard");
2533
+ const [activeTab, setActiveTab] = useState4("overview");
2489
2534
  const [logs, setLogs] = useState4([]);
2490
2535
  const [serverInfo, setServerInfo] = useState4({
2491
2536
  port: initialPort,
2492
2537
  pid: process.pid,
2493
2538
  running: false
2494
2539
  });
2495
- const [showHelp2, setShowHelp] = useState4(false);
2496
2540
  const config = loadMCPConfig();
2497
2541
  const projects = scanForProjects();
2498
2542
  const exposedProjects = projects.filter((p) => {
@@ -2501,9 +2545,15 @@ var init_App = __esm({
2501
2545
  );
2502
2546
  return cfg?.expose ?? config.defaults.includeNew;
2503
2547
  });
2504
- const exposedNames = exposedProjects.map((p) => p.name).slice(0, 5);
2505
- const exposedLabel = exposedNames.length > 0 ? exposedNames.join(", ") + (exposedProjects.length > 5 ? ` (+${exposedProjects.length - 5} more)` : "") : "(none)";
2506
- useEffect3(() => {
2548
+ const workspacePath = detectWorkspaceRoot();
2549
+ const installStatus = checkInstallStatus(workspacePath);
2550
+ const installedCount = [
2551
+ installStatus.antigravity,
2552
+ installStatus.claude,
2553
+ installStatus.vscodeGlobal,
2554
+ installStatus.vscodeWorkspace
2555
+ ].filter(Boolean).length;
2556
+ useEffect4(() => {
2507
2557
  const start = async () => {
2508
2558
  const status = getMCPServerStatus();
2509
2559
  if (!status.running) {
@@ -2511,17 +2561,15 @@ var init_App = __esm({
2511
2561
  const res = await startMCPServer({ interactive: true });
2512
2562
  setServerInfo((prev) => ({ ...prev, running: true, port: res.port, pid: res.pid }));
2513
2563
  } catch (e) {
2514
- setLogs((prev) => [...prev, `Error starting server: ${e}`]);
2564
+ setLogs((prev) => [...prev, `[ERROR] Error starting server: ${e}`]);
2515
2565
  }
2516
2566
  } else {
2517
2567
  setServerInfo((prev) => ({ ...prev, running: true, port: status.port || initialPort, pid: status.pid || process.pid }));
2518
2568
  }
2519
2569
  };
2520
2570
  start();
2521
- return () => {
2522
- };
2523
2571
  }, []);
2524
- useEffect3(() => {
2572
+ useEffect4(() => {
2525
2573
  const logPath = getLogFilePath();
2526
2574
  let lastSize = 0;
2527
2575
  if (fs11.existsSync(logPath)) {
@@ -2540,7 +2588,7 @@ var init_App = __esm({
2540
2588
  const newLines = newContent.split("\n").filter((l) => l.trim());
2541
2589
  setLogs((prev) => {
2542
2590
  const next = [...prev, ...newLines];
2543
- return next.slice(-50);
2591
+ return next.slice(-100);
2544
2592
  });
2545
2593
  lastSize = stats.size;
2546
2594
  }
@@ -2548,48 +2596,34 @@ var init_App = __esm({
2548
2596
  }, 500);
2549
2597
  return () => clearInterval(interval);
2550
2598
  }, []);
2551
- useInput2((input, key) => {
2599
+ useInput3((input, key) => {
2552
2600
  if (input === "q" || key.ctrl && input === "c") {
2553
2601
  stopMCPServer();
2554
2602
  onExit();
2555
2603
  exit();
2556
2604
  }
2557
- if (input === "p") {
2558
- setView("config");
2559
- }
2560
- if (input === "i") {
2561
- setView("install");
2562
- }
2563
- if (input === "c") {
2564
- setLogs([]);
2565
- }
2566
- if (input === "r") {
2567
- setLogs((prev) => [...prev, "[INFO] Config reload requested..."]);
2568
- }
2569
- if (input === "?") {
2570
- setShowHelp((prev) => !prev);
2571
- }
2572
- }, { isActive: true });
2605
+ });
2573
2606
  const termHeight = process.stdout.rows || 24;
2574
- const logHeight = Math.max(5, termHeight - 12);
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(
2582
- Dashboard,
2583
- {
2584
- logs,
2585
- exposedLabel,
2586
- port: serverInfo.port,
2587
- pid: serverInfo.pid,
2588
- running: serverInfo.running,
2589
- logHeight,
2590
- showHelp: showHelp2
2591
- }
2592
- );
2607
+ const contentHeight = termHeight - 8;
2608
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", padding: 0, height: termHeight, children: [
2609
+ /* @__PURE__ */ jsx10(TabBar, { tabs: TABS, activeTab, onChange: setActiveTab }),
2610
+ /* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexGrow: 1, children: [
2611
+ activeTab === "overview" && /* @__PURE__ */ jsx10(
2612
+ Overview,
2613
+ {
2614
+ serverStatus: serverInfo,
2615
+ stats: {
2616
+ exposedProjects: exposedProjects.length,
2617
+ totalProjects: projects.length,
2618
+ installedIntegrations: installedCount
2619
+ }
2620
+ }
2621
+ ),
2622
+ activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, {}),
2623
+ activeTab === "install" && /* @__PURE__ */ jsx10(InstallView, {}),
2624
+ activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight })
2625
+ ] })
2626
+ ] });
2593
2627
  };
2594
2628
  }
2595
2629
  });
@@ -2770,7 +2804,7 @@ __export(mcp_exports, {
2770
2804
  handleStartServer: () => handleStartServer,
2771
2805
  runMCP: () => runMCP
2772
2806
  });
2773
- import { intro, outro, select as select2, confirm as confirm2, note as note6, cancel, isCancel as isCancel5 } from "@clack/prompts";
2807
+ import { intro, outro, confirm as confirm2, note as note6, isCancel as isCancel5 } from "@clack/prompts";
2774
2808
  import pc7 from "picocolors";
2775
2809
  async function runMCP(subcommand2) {
2776
2810
  if (subcommand2) {
@@ -2796,12 +2830,14 @@ async function runMCP(subcommand2) {
2796
2830
  case "configure":
2797
2831
  await handleConfigure();
2798
2832
  return;
2833
+ case "menu":
2834
+ break;
2799
2835
  }
2800
2836
  }
2801
- intro(pc7.bgCyan(pc7.black(" RRCE MCP Hub ")));
2802
2837
  const workspacePath = detectWorkspaceRoot();
2803
2838
  const globalPathCheck = await ensureMCPGlobalPath();
2804
2839
  if (!globalPathCheck.configured) {
2840
+ intro(pc7.bgCyan(pc7.black(" MCP Setup ")));
2805
2841
  const configured = await handleConfigureGlobalPath();
2806
2842
  if (!configured) {
2807
2843
  outro(pc7.yellow("MCP requires a global storage path. Setup cancelled."));
@@ -2810,101 +2846,46 @@ async function runMCP(subcommand2) {
2810
2846
  }
2811
2847
  const installed = isInstalledAnywhere(workspacePath);
2812
2848
  if (!installed) {
2849
+ intro(pc7.bgCyan(pc7.black(" Welcome to MCP Hub ")));
2813
2850
  note6(
2814
- `${pc7.bold("Welcome to RRCE MCP Hub!")}
2815
-
2816
- MCP (Model Context Protocol) allows AI assistants to access your
2817
- project knowledge in real-time. Let's get you set up.`,
2851
+ `${pc7.bold("Set up Model Context Protocol")}
2852
+ Allow AI assistants to access your project context.`,
2818
2853
  "Getting Started"
2819
2854
  );
2820
2855
  const shouldInstall = await confirm2({
2821
- message: "Install MCP server to your IDE(s)?",
2856
+ message: "Install MCP server integrations now?",
2822
2857
  initialValue: true
2823
2858
  });
2824
2859
  if (shouldInstall && !isCancel5(shouldInstall)) {
2825
2860
  await runInstallWizard(workspacePath);
2826
- const config2 = loadMCPConfig();
2827
- const exposedCount2 = config2.projects.filter((p) => p.expose).length;
2828
- if (exposedCount2 === 0) {
2829
- await handleConfigure();
2830
- }
2831
2861
  const shouldStart = await confirm2({
2832
- message: "Start the MCP server now?",
2862
+ message: "Start the MCP Dashboard?",
2833
2863
  initialValue: true
2834
2864
  });
2835
2865
  if (shouldStart && !isCancel5(shouldStart)) {
2836
2866
  await handleStartServer();
2837
2867
  }
2868
+ } else {
2869
+ outro(pc7.dim('Setup skipped. Run "npx rrce-workflow mcp" later to restart.'));
2838
2870
  }
2839
- outro(pc7.green("MCP Hub setup complete!"));
2840
2871
  return;
2841
2872
  }
2842
- const config = loadMCPConfig();
2843
- const exposedCount = config.projects.filter((p) => p.expose).length;
2844
- if (exposedCount === 0 && !config.defaults.includeNew) {
2845
- note6("MCP is installed but no projects are exposed. Let's configure that.", "Configuration Needed");
2846
- await handleConfigure();
2847
- }
2848
- let running = true;
2849
- while (running) {
2850
- const serverStatus = getMCPServerStatus();
2851
- const serverLabel = serverStatus.running ? pc7.green("\u25CF Running") : pc7.dim("\u25CB Stopped");
2852
- const currentStatus = checkInstallStatus(workspacePath);
2853
- const installedCount = [currentStatus.antigravity, currentStatus.claude, currentStatus.vscodeGlobal, currentStatus.vscodeWorkspace].filter(Boolean).length;
2854
- const action = await select2({
2855
- message: "What would you like to do?",
2856
- options: [
2857
- { value: "start", label: `\u25B6\uFE0F Start MCP server`, hint: serverLabel },
2858
- { value: "configure", label: "\u2699\uFE0F Configure projects", hint: "Choose which projects to expose" },
2859
- { value: "install", label: "\u{1F4E5} Install to IDE", hint: `${installedCount} IDE(s) configured` },
2860
- { value: "status", label: "\u{1F4CB} View status", hint: "See details" },
2861
- { value: "help", label: "\u2753 Help", hint: "Learn about MCP Hub" },
2862
- { value: "exit", label: "\u21A9 Exit", hint: "Return to shell" }
2863
- ]
2864
- });
2865
- if (isCancel5(action)) {
2866
- cancel("MCP Hub closed.");
2867
- return;
2868
- }
2869
- switch (action) {
2870
- case "start":
2871
- await handleStartServer();
2872
- break;
2873
- case "configure":
2874
- await handleConfigure();
2875
- break;
2876
- case "install":
2877
- await runInstallWizard(workspacePath);
2878
- break;
2879
- case "status":
2880
- await handleShowStatus();
2881
- break;
2882
- case "help":
2883
- showHelp();
2884
- break;
2885
- case "exit":
2886
- running = false;
2887
- break;
2888
- }
2873
+ try {
2874
+ await handleStartServer();
2875
+ } catch (err) {
2876
+ console.error(err);
2877
+ outro(pc7.red("Failed to launch MCP Dashboard"));
2889
2878
  }
2890
- outro(pc7.green("MCP Hub closed."));
2891
2879
  }
2892
2880
  async function handleStopServer() {
2893
2881
  const { stopMCPServer: stopMCPServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
2894
2882
  const status = getMCPServerStatus();
2895
2883
  if (!status.running) {
2896
- note6("MCP server is not running.", "Status");
2897
- return;
2898
- }
2899
- const confirmed = await confirm2({
2900
- message: "Stop the MCP server?",
2901
- initialValue: true
2902
- });
2903
- if (isCancel5(confirmed) || !confirmed) {
2884
+ console.log(pc7.dim("MCP server is already stopped."));
2904
2885
  return;
2905
2886
  }
2906
2887
  stopMCPServer2();
2907
- note6(pc7.green("MCP server stopped."), "Server Stopped");
2888
+ console.log(pc7.green("MCP server stopped."));
2908
2889
  }
2909
2890
  var init_mcp = __esm({
2910
2891
  "src/mcp/index.ts"() {
@@ -2922,7 +2903,7 @@ var init_mcp = __esm({
2922
2903
  });
2923
2904
 
2924
2905
  // src/commands/wizard/setup-flow.ts
2925
- import { group, select as select3, multiselect as multiselect3, confirm as confirm3, spinner as spinner3, note as note7, outro as outro2, cancel as cancel2, isCancel as isCancel6 } from "@clack/prompts";
2906
+ import { group, select as select2, multiselect as multiselect3, confirm as confirm3, spinner as spinner3, note as note7, outro as outro2, cancel as cancel2, isCancel as isCancel6 } from "@clack/prompts";
2926
2907
  import pc8 from "picocolors";
2927
2908
  import * as fs12 from "fs";
2928
2909
  import * as path12 from "path";
@@ -2930,7 +2911,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
2930
2911
  const s = spinner3();
2931
2912
  const config = await group(
2932
2913
  {
2933
- storageMode: () => select3({
2914
+ storageMode: () => select2({
2934
2915
  message: "Where should workflow data be stored?",
2935
2916
  options: [
2936
2917
  { value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
@@ -3125,9 +3106,9 @@ linked_projects:
3125
3106
  }
3126
3107
  if (config.exposeToMCP) {
3127
3108
  try {
3128
- const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
3109
+ const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
3129
3110
  const { getWorkspaceName: getWorkspaceName2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
3130
- const mcpConfig = loadMCPConfig2();
3111
+ const mcpConfig = loadMCPConfig3();
3131
3112
  const currentProjectName = workspaceName;
3132
3113
  if (config.storageMode === "workspace") {
3133
3114
  setProjectConfig2(mcpConfig, currentProjectName, true);
@@ -3300,8 +3281,8 @@ linked_projects:
3300
3281
  });
3301
3282
  if (shouldExpose && !isCancel7(shouldExpose)) {
3302
3283
  try {
3303
- const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
3304
- const mcpConfig = loadMCPConfig2();
3284
+ const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
3285
+ const mcpConfig = loadMCPConfig3();
3305
3286
  for (const project of selectedProjects) {
3306
3287
  setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
3307
3288
  }
@@ -3478,7 +3459,7 @@ var wizard_exports = {};
3478
3459
  __export(wizard_exports, {
3479
3460
  runWizard: () => runWizard
3480
3461
  });
3481
- import { intro as intro2, select as select4, spinner as spinner7, note as note11, outro as outro6, isCancel as isCancel10 } from "@clack/prompts";
3462
+ import { intro as intro2, select as select3, spinner as spinner7, note as note11, outro as outro6, isCancel as isCancel10 } from "@clack/prompts";
3482
3463
  import pc12 from "picocolors";
3483
3464
  import * as fs16 from "fs";
3484
3465
  async function runWizard() {
@@ -3536,7 +3517,7 @@ Workspace: ${pc12.bold(workspaceName)}`,
3536
3517
  menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
3537
3518
  menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
3538
3519
  menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
3539
- const action = await select4({
3520
+ const action = await select3({
3540
3521
  message: "This workspace is already configured. What would you like to do?",
3541
3522
  options: menuOptions
3542
3523
  });
@@ -3584,7 +3565,7 @@ init_wizard();
3584
3565
 
3585
3566
  // src/commands/selector.ts
3586
3567
  init_prompts();
3587
- import { intro as intro3, select as select5, note as note12, cancel as cancel7, isCancel as isCancel11, outro as outro7 } from "@clack/prompts";
3568
+ import { intro as intro3, select as select4, note as note12, cancel as cancel7, isCancel as isCancel11, outro as outro7 } from "@clack/prompts";
3588
3569
  import pc13 from "picocolors";
3589
3570
  import * as path15 from "path";
3590
3571
  async function runSelector() {
@@ -3595,7 +3576,7 @@ async function runSelector() {
3595
3576
  cancel7("No agents found. Run `rrce-workflow` to set up.");
3596
3577
  process.exit(0);
3597
3578
  }
3598
- const selection = await select5({
3579
+ const selection = await select4({
3599
3580
  message: "Select an agent:",
3600
3581
  options: [
3601
3582
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.2.39",
3
+ "version": "0.2.40",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",