rrce-workflow 0.2.39 → 0.2.41
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/README.md +12 -1
- package/dist/index.js +350 -360
- 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
|
@@ -2113,153 +2113,30 @@ var init_Header = __esm({
|
|
|
2113
2113
|
}
|
|
2114
2114
|
});
|
|
2115
2115
|
|
|
2116
|
-
// src/mcp/ui/
|
|
2116
|
+
// src/mcp/ui/Overview.tsx
|
|
2117
2117
|
import "react";
|
|
2118
2118
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
2119
2119
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
2120
|
-
var
|
|
2121
|
-
var
|
|
2122
|
-
"src/mcp/ui/
|
|
2123
|
-
"use strict";
|
|
2124
|
-
StatusBoard = ({ exposedLabel, port, pid, running }) => {
|
|
2125
|
-
return /* @__PURE__ */ jsx2(Box2, { borderStyle: "single", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsxs(Text2, { children: [
|
|
2126
|
-
running ? /* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u25CF RUNNING" }) : /* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u25CF STOPPED" }),
|
|
2127
|
-
" ",
|
|
2128
|
-
"\u2502",
|
|
2129
|
-
" \u{1F4CB} ",
|
|
2130
|
-
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: exposedLabel }),
|
|
2131
|
-
" ",
|
|
2132
|
-
"\u2502",
|
|
2133
|
-
" Port: ",
|
|
2134
|
-
/* @__PURE__ */ jsx2(Text2, { color: "green", children: port }),
|
|
2135
|
-
" ",
|
|
2136
|
-
"\u2502",
|
|
2137
|
-
" PID: ",
|
|
2138
|
-
/* @__PURE__ */ jsx2(Text2, { color: "green", children: pid })
|
|
2139
|
-
] }) });
|
|
2140
|
-
};
|
|
2141
|
-
}
|
|
2142
|
-
});
|
|
2143
|
-
|
|
2144
|
-
// src/mcp/ui/LogViewer.tsx
|
|
2145
|
-
import "react";
|
|
2146
|
-
import { Box as Box3, Text as Text3 } from "ink";
|
|
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"() {
|
|
2120
|
+
var Overview;
|
|
2121
|
+
var init_Overview = __esm({
|
|
2122
|
+
"src/mcp/ui/Overview.tsx"() {
|
|
2171
2123
|
"use strict";
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
/* @__PURE__ */
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
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"
|
|
2124
|
+
init_Header();
|
|
2125
|
+
Overview = ({ serverStatus, stats }) => {
|
|
2126
|
+
return /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", flexGrow: 1, children: [
|
|
2127
|
+
/* @__PURE__ */ jsx2(Header, {}),
|
|
2128
|
+
/* @__PURE__ */ jsxs(Box2, { borderStyle: "round", padding: 1, borderColor: "white", flexDirection: "column", flexGrow: 1, children: [
|
|
2129
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, underline: true, children: "System Status" }),
|
|
2130
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, children: [
|
|
2131
|
+
/* @__PURE__ */ jsx2(Text2, { children: "Integrations Installed: " }),
|
|
2132
|
+
/* @__PURE__ */ jsx2(Text2, { color: stats.installedIntegrations > 0 ? "green" : "yellow", children: stats.installedIntegrations })
|
|
2224
2133
|
] }),
|
|
2225
|
-
/* @__PURE__ */
|
|
2226
|
-
"
|
|
2227
|
-
/* @__PURE__ */
|
|
2228
|
-
" - Stop Server & Exit"
|
|
2134
|
+
/* @__PURE__ */ jsxs(Box2, { children: [
|
|
2135
|
+
/* @__PURE__ */ jsx2(Text2, { children: "Server Port: " }),
|
|
2136
|
+
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: serverStatus.port })
|
|
2229
2137
|
] }),
|
|
2230
|
-
/* @__PURE__ */
|
|
2231
|
-
|
|
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"() {
|
|
2250
|
-
"use strict";
|
|
2251
|
-
init_Header();
|
|
2252
|
-
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, {})
|
|
2138
|
+
/* @__PURE__ */ jsx2(Box2, { marginTop: 1, children: /* @__PURE__ */ jsx2(Text2, { color: "dim", children: "Press 'q' to stop server and exit." }) })
|
|
2139
|
+
] })
|
|
2263
2140
|
] });
|
|
2264
2141
|
};
|
|
2265
2142
|
}
|
|
@@ -2267,8 +2144,8 @@ var init_Dashboard = __esm({
|
|
|
2267
2144
|
|
|
2268
2145
|
// src/mcp/ui/components/SimpleSelect.tsx
|
|
2269
2146
|
import { useState } from "react";
|
|
2270
|
-
import { Box as
|
|
2271
|
-
import { jsx as
|
|
2147
|
+
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
2148
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2272
2149
|
function SimpleSelect({
|
|
2273
2150
|
items,
|
|
2274
2151
|
onSelect,
|
|
@@ -2311,18 +2188,18 @@ function SimpleSelect({
|
|
|
2311
2188
|
onCancel?.();
|
|
2312
2189
|
}
|
|
2313
2190
|
});
|
|
2314
|
-
return /* @__PURE__ */
|
|
2315
|
-
message && /* @__PURE__ */
|
|
2191
|
+
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
|
|
2192
|
+
message && /* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { bold: true, children: message }) }),
|
|
2316
2193
|
items.map((item, index) => {
|
|
2317
2194
|
const isSelected = index === selectedIndex;
|
|
2318
2195
|
const isChecked = isMulti && selectedValues.has(item.value);
|
|
2319
|
-
return /* @__PURE__ */
|
|
2320
|
-
/* @__PURE__ */
|
|
2321
|
-
isMulti && /* @__PURE__ */
|
|
2322
|
-
/* @__PURE__ */
|
|
2196
|
+
return /* @__PURE__ */ jsxs2(Box3, { children: [
|
|
2197
|
+
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
|
|
2198
|
+
isMulti && /* @__PURE__ */ jsx3(Text3, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
|
|
2199
|
+
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "cyan" : "white", children: item.label })
|
|
2323
2200
|
] }, item.key || String(item.value));
|
|
2324
2201
|
}),
|
|
2325
|
-
/* @__PURE__ */
|
|
2202
|
+
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx3(Text3, { color: "gray", children: isMulti ? "Space to toggle, Enter to confirm, Esc to cancel" : "Enter to select, Esc to cancel" }) })
|
|
2326
2203
|
] });
|
|
2327
2204
|
}
|
|
2328
2205
|
var init_SimpleSelect = __esm({
|
|
@@ -2331,19 +2208,18 @@ var init_SimpleSelect = __esm({
|
|
|
2331
2208
|
}
|
|
2332
2209
|
});
|
|
2333
2210
|
|
|
2334
|
-
// src/mcp/ui/
|
|
2211
|
+
// src/mcp/ui/ProjectsView.tsx
|
|
2335
2212
|
import { useState as useState2 } from "react";
|
|
2336
|
-
import { Box as
|
|
2337
|
-
import { jsx as
|
|
2338
|
-
var
|
|
2339
|
-
var
|
|
2340
|
-
"src/mcp/ui/
|
|
2213
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
2214
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2215
|
+
var ProjectsView;
|
|
2216
|
+
var init_ProjectsView = __esm({
|
|
2217
|
+
"src/mcp/ui/ProjectsView.tsx"() {
|
|
2341
2218
|
"use strict";
|
|
2342
2219
|
init_SimpleSelect();
|
|
2343
2220
|
init_config();
|
|
2344
2221
|
init_detection();
|
|
2345
|
-
|
|
2346
|
-
ConfigModal = ({ onBack }) => {
|
|
2222
|
+
ProjectsView = ({ onConfigChange }) => {
|
|
2347
2223
|
const [config, setConfig] = useState2(loadMCPConfig());
|
|
2348
2224
|
const allProjects = scanForProjects();
|
|
2349
2225
|
const projectItems = allProjects.map((p) => {
|
|
@@ -2371,94 +2247,248 @@ var init_ConfigModal = __esm({
|
|
|
2371
2247
|
project.name,
|
|
2372
2248
|
isSelected,
|
|
2373
2249
|
void 0,
|
|
2374
|
-
// Keep existing permissions or defaults
|
|
2375
2250
|
project.path
|
|
2376
|
-
// Ensure path is stored
|
|
2377
2251
|
);
|
|
2378
2252
|
}
|
|
2379
2253
|
});
|
|
2380
2254
|
saveMCPConfig(newConfig);
|
|
2381
|
-
|
|
2255
|
+
setConfig(newConfig);
|
|
2256
|
+
if (onConfigChange) onConfigChange();
|
|
2382
2257
|
};
|
|
2383
|
-
return /* @__PURE__ */
|
|
2384
|
-
|
|
2385
|
-
{
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2258
|
+
return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
2259
|
+
/* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: " Exposed Projects " }),
|
|
2260
|
+
/* @__PURE__ */ jsx4(Text4, { color: "dim", children: " Select projects to expose via the MCP server. Use Space to toggle, Enter to save." }),
|
|
2261
|
+
/* @__PURE__ */ jsx4(Box4, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx4(
|
|
2262
|
+
SimpleSelect,
|
|
2263
|
+
{
|
|
2264
|
+
message: "",
|
|
2265
|
+
items: projectItems,
|
|
2266
|
+
isMulti: true,
|
|
2267
|
+
initialSelected,
|
|
2268
|
+
onSelect: () => {
|
|
2269
|
+
},
|
|
2270
|
+
onSubmit: handleSubmit,
|
|
2271
|
+
onCancel: () => {
|
|
2272
|
+
}
|
|
2391
2273
|
},
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
) });
|
|
2274
|
+
JSON.stringify(initialSelected)
|
|
2275
|
+
) })
|
|
2276
|
+
] });
|
|
2396
2277
|
};
|
|
2397
2278
|
}
|
|
2398
2279
|
});
|
|
2399
2280
|
|
|
2400
|
-
// src/mcp/ui/
|
|
2281
|
+
// src/mcp/ui/components/InstallWizard.tsx
|
|
2401
2282
|
import { useState as useState3 } from "react";
|
|
2402
|
-
import { Box as
|
|
2403
|
-
import { jsx as
|
|
2404
|
-
var
|
|
2405
|
-
var
|
|
2406
|
-
"src/mcp/ui/
|
|
2283
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
2284
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2285
|
+
var InstallWizard;
|
|
2286
|
+
var init_InstallWizard = __esm({
|
|
2287
|
+
"src/mcp/ui/components/InstallWizard.tsx"() {
|
|
2407
2288
|
"use strict";
|
|
2408
2289
|
init_SimpleSelect();
|
|
2409
2290
|
init_install();
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
const [
|
|
2413
|
-
const
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2291
|
+
InstallWizard = ({ workspacePath, onComplete, onCancel }) => {
|
|
2292
|
+
const [status, setStatus] = useState3(checkInstallStatus(workspacePath));
|
|
2293
|
+
const [message, setMessage] = useState3("");
|
|
2294
|
+
const options = [
|
|
2295
|
+
{
|
|
2296
|
+
value: "antigravity",
|
|
2297
|
+
label: "Antigravity IDE",
|
|
2298
|
+
hint: status.antigravity ? "INSTALLED" : "Not installed"
|
|
2299
|
+
},
|
|
2300
|
+
{
|
|
2301
|
+
value: "vscode-global",
|
|
2302
|
+
label: "VSCode (Global Settings)",
|
|
2303
|
+
hint: status.vscodeGlobal ? "INSTALLED" : "Not installed"
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
value: "vscode-workspace",
|
|
2307
|
+
label: "VSCode (Workspace Config)",
|
|
2308
|
+
hint: status.vscodeWorkspace ? "INSTALLED" : "Not installed"
|
|
2309
|
+
},
|
|
2310
|
+
{
|
|
2311
|
+
value: "claude",
|
|
2312
|
+
label: "Claude Desktop",
|
|
2313
|
+
hint: status.claude ? "INSTALLED" : "Not installed"
|
|
2314
|
+
}
|
|
2419
2315
|
];
|
|
2420
|
-
const
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2316
|
+
const initialSelected = [
|
|
2317
|
+
...status.antigravity ? ["antigravity"] : [],
|
|
2318
|
+
...status.vscodeGlobal ? ["vscode-global"] : [],
|
|
2319
|
+
...status.vscodeWorkspace ? ["vscode-workspace"] : [],
|
|
2320
|
+
...status.claude ? ["claude"] : []
|
|
2321
|
+
];
|
|
2322
|
+
const handleSubmit = (selectedIds) => {
|
|
2323
|
+
const targets = selectedIds;
|
|
2324
|
+
let results = [];
|
|
2325
|
+
targets.forEach((target) => {
|
|
2326
|
+
const success = installToConfig(target, workspacePath);
|
|
2327
|
+
const label = getTargetLabel(target);
|
|
2328
|
+
results.push(`${label}: ${success ? "Success" : "Failed"}`);
|
|
2329
|
+
});
|
|
2330
|
+
setStatus(checkInstallStatus(workspacePath));
|
|
2331
|
+
setMessage(`Installation updated: ${results.join(", ")}`);
|
|
2332
|
+
setTimeout(() => {
|
|
2333
|
+
setMessage("");
|
|
2334
|
+
onComplete();
|
|
2335
|
+
}, 2e3);
|
|
2336
|
+
};
|
|
2337
|
+
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
2338
|
+
message && /* @__PURE__ */ jsx5(Text5, { color: "green", children: message }),
|
|
2339
|
+
/* @__PURE__ */ jsx5(
|
|
2340
|
+
SimpleSelect,
|
|
2341
|
+
{
|
|
2342
|
+
message: "Select integrations to install:",
|
|
2343
|
+
items: options.map((o) => ({
|
|
2344
|
+
value: o.value,
|
|
2345
|
+
label: o.label + (o.hint === "INSTALLED" ? " (Installed)" : ""),
|
|
2346
|
+
key: o.value
|
|
2347
|
+
})),
|
|
2348
|
+
isMulti: true,
|
|
2349
|
+
initialSelected,
|
|
2350
|
+
onSelect: () => {
|
|
2351
|
+
},
|
|
2352
|
+
onSubmit: handleSubmit,
|
|
2353
|
+
onCancel
|
|
2429
2354
|
}
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2355
|
+
)
|
|
2356
|
+
] });
|
|
2357
|
+
};
|
|
2358
|
+
}
|
|
2359
|
+
});
|
|
2360
|
+
|
|
2361
|
+
// src/mcp/ui/InstallView.tsx
|
|
2362
|
+
import "react";
|
|
2363
|
+
import { Box as Box6, Text as Text6 } from "ink";
|
|
2364
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2365
|
+
var InstallView;
|
|
2366
|
+
var init_InstallView = __esm({
|
|
2367
|
+
"src/mcp/ui/InstallView.tsx"() {
|
|
2368
|
+
"use strict";
|
|
2369
|
+
init_InstallWizard();
|
|
2370
|
+
init_paths();
|
|
2371
|
+
InstallView = () => {
|
|
2372
|
+
const workspacePath = detectWorkspaceRoot();
|
|
2373
|
+
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "magenta", children: [
|
|
2374
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: "magenta", children: " Installation & Configuration " }),
|
|
2375
|
+
/* @__PURE__ */ jsx6(Text6, { color: "dim", children: " Configure IDE integrations for VSCode, Claude, and Antigravity." }),
|
|
2376
|
+
/* @__PURE__ */ jsx6(Box6, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx6(
|
|
2377
|
+
InstallWizard,
|
|
2378
|
+
{
|
|
2379
|
+
workspacePath,
|
|
2380
|
+
onComplete: () => {
|
|
2381
|
+
},
|
|
2382
|
+
onCancel: () => {
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
) })
|
|
2386
|
+
] });
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
});
|
|
2390
|
+
|
|
2391
|
+
// src/mcp/ui/LogViewer.tsx
|
|
2392
|
+
import "react";
|
|
2393
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
2394
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2395
|
+
var LogViewer;
|
|
2396
|
+
var init_LogViewer = __esm({
|
|
2397
|
+
"src/mcp/ui/LogViewer.tsx"() {
|
|
2398
|
+
"use strict";
|
|
2399
|
+
LogViewer = ({ logs, height }) => {
|
|
2400
|
+
const visibleLogs = logs.slice(-height);
|
|
2401
|
+
const emptyLines = Math.max(0, height - visibleLogs.length);
|
|
2402
|
+
const padding = Array(emptyLines).fill("");
|
|
2403
|
+
const formatLog = (log) => {
|
|
2404
|
+
if (log.includes("[ERROR]")) return /* @__PURE__ */ jsx7(Text7, { color: "red", children: log });
|
|
2405
|
+
if (log.includes("[WARN]")) return /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: log });
|
|
2406
|
+
if (log.includes("[INFO]")) return /* @__PURE__ */ jsx7(Text7, { color: "green", children: log });
|
|
2407
|
+
if (log.includes("Success")) return /* @__PURE__ */ jsx7(Text7, { color: "green", children: log });
|
|
2408
|
+
return /* @__PURE__ */ jsx7(Text7, { children: log });
|
|
2436
2409
|
};
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2410
|
+
return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "dim", paddingX: 1, height: height + 2, flexGrow: 1, children: [
|
|
2411
|
+
padding.map((_, i) => /* @__PURE__ */ jsx7(Text7, { children: " " }, `empty-${i}`)),
|
|
2412
|
+
visibleLogs.map((log, i) => /* @__PURE__ */ jsx7(Box7, { children: formatLog(log) }, `log-${i}`))
|
|
2413
|
+
] });
|
|
2414
|
+
};
|
|
2415
|
+
}
|
|
2416
|
+
});
|
|
2417
|
+
|
|
2418
|
+
// src/mcp/ui/StatusBoard.tsx
|
|
2419
|
+
import "react";
|
|
2420
|
+
import { Box as Box8, Text as Text8 } from "ink";
|
|
2421
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2422
|
+
var StatusBoard;
|
|
2423
|
+
var init_StatusBoard = __esm({
|
|
2424
|
+
"src/mcp/ui/StatusBoard.tsx"() {
|
|
2425
|
+
"use strict";
|
|
2426
|
+
StatusBoard = ({ exposedLabel, port, pid, running }) => {
|
|
2427
|
+
return /* @__PURE__ */ jsx8(Box8, { borderStyle: "single", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsxs7(Text8, { children: [
|
|
2428
|
+
running ? /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF RUNNING" }) : /* @__PURE__ */ jsx8(Text8, { color: "red", children: "\u25CF STOPPED" }),
|
|
2429
|
+
" ",
|
|
2430
|
+
"\u2502",
|
|
2431
|
+
" \u{1F4CB} ",
|
|
2432
|
+
/* @__PURE__ */ jsx8(Text8, { color: "yellow", children: exposedLabel }),
|
|
2433
|
+
" ",
|
|
2434
|
+
"\u2502",
|
|
2435
|
+
" Port: ",
|
|
2436
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: port }),
|
|
2437
|
+
" ",
|
|
2438
|
+
"\u2502",
|
|
2439
|
+
" PID: ",
|
|
2440
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: pid })
|
|
2441
|
+
] }) });
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
});
|
|
2445
|
+
|
|
2446
|
+
// src/mcp/ui/components/TabBar.tsx
|
|
2447
|
+
import "react";
|
|
2448
|
+
import { Box as Box9, Text as Text9, useInput as useInput2 } from "ink";
|
|
2449
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2450
|
+
var TabBar;
|
|
2451
|
+
var init_TabBar = __esm({
|
|
2452
|
+
"src/mcp/ui/components/TabBar.tsx"() {
|
|
2453
|
+
"use strict";
|
|
2454
|
+
TabBar = ({ tabs, activeTab, onChange }) => {
|
|
2455
|
+
useInput2((input, key) => {
|
|
2456
|
+
if (key.leftArrow) {
|
|
2457
|
+
const index = tabs.findIndex((t) => t.id === activeTab);
|
|
2458
|
+
if (index !== -1) {
|
|
2459
|
+
const nextIndex = (index - 1 + tabs.length) % tabs.length;
|
|
2460
|
+
onChange(tabs[nextIndex]?.id || tabs[0].id);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
if (key.rightArrow) {
|
|
2464
|
+
const index = tabs.findIndex((t) => t.id === activeTab);
|
|
2465
|
+
if (index !== -1) {
|
|
2466
|
+
const nextIndex = (index + 1) % tabs.length;
|
|
2467
|
+
onChange(tabs[nextIndex]?.id || tabs[0].id);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
const num = parseInt(input);
|
|
2471
|
+
if (!isNaN(num) && num > 0 && num <= tabs.length) {
|
|
2472
|
+
const tab = tabs[num - 1];
|
|
2473
|
+
if (tab) onChange(tab.id);
|
|
2474
|
+
}
|
|
2475
|
+
});
|
|
2476
|
+
return /* @__PURE__ */ jsxs8(Box9, { borderStyle: "single", paddingX: 1, borderColor: "gray", children: [
|
|
2477
|
+
tabs.map((tab, index) => {
|
|
2478
|
+
const isActive = tab.id === activeTab;
|
|
2479
|
+
return /* @__PURE__ */ jsx9(Box9, { marginRight: 2, children: /* @__PURE__ */ jsx9(
|
|
2480
|
+
Text9,
|
|
2443
2481
|
{
|
|
2444
|
-
|
|
2445
|
-
|
|
2482
|
+
color: isActive ? "cyan" : "white",
|
|
2483
|
+
bold: isActive,
|
|
2484
|
+
backgroundColor: isActive ? "black" : void 0,
|
|
2485
|
+
children: isActive ? `[ ${tab.label} ]` : ` ${tab.label} `
|
|
2446
2486
|
}
|
|
2447
|
-
) })
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
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
|
-
) });
|
|
2487
|
+
) }, tab.id);
|
|
2488
|
+
}),
|
|
2489
|
+
/* @__PURE__ */ jsx9(Box9, { flexGrow: 1 }),
|
|
2490
|
+
/* @__PURE__ */ jsx9(Text9, { color: "dim", children: "Use \u25C4/\u25BA arrows to navigate" })
|
|
2491
|
+
] });
|
|
2462
2492
|
};
|
|
2463
2493
|
}
|
|
2464
2494
|
});
|
|
@@ -2468,31 +2498,42 @@ var App_exports = {};
|
|
|
2468
2498
|
__export(App_exports, {
|
|
2469
2499
|
App: () => App
|
|
2470
2500
|
});
|
|
2471
|
-
import { useState as useState4, useEffect as
|
|
2472
|
-
import { useInput as
|
|
2501
|
+
import { useState as useState4, useEffect as useEffect4 } from "react";
|
|
2502
|
+
import { Box as Box10, useInput as useInput3, useApp } from "ink";
|
|
2473
2503
|
import fs11 from "fs";
|
|
2474
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2475
|
-
var App;
|
|
2504
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2505
|
+
var TABS, App;
|
|
2476
2506
|
var init_App = __esm({
|
|
2477
2507
|
"src/mcp/ui/App.tsx"() {
|
|
2478
2508
|
"use strict";
|
|
2479
|
-
|
|
2509
|
+
init_Overview();
|
|
2510
|
+
init_ProjectsView();
|
|
2511
|
+
init_InstallView();
|
|
2512
|
+
init_LogViewer();
|
|
2513
|
+
init_StatusBoard();
|
|
2514
|
+
init_TabBar();
|
|
2480
2515
|
init_config();
|
|
2481
2516
|
init_detection();
|
|
2482
2517
|
init_logger();
|
|
2483
2518
|
init_server();
|
|
2484
|
-
|
|
2485
|
-
|
|
2519
|
+
init_install();
|
|
2520
|
+
init_paths();
|
|
2521
|
+
TABS = [
|
|
2522
|
+
{ id: "overview", label: "Overview" },
|
|
2523
|
+
{ id: "logs", label: "Logs" },
|
|
2524
|
+
{ id: "projects", label: "Projects" },
|
|
2525
|
+
{ id: "install", label: "Install" }
|
|
2526
|
+
];
|
|
2486
2527
|
App = ({ onExit, initialPort }) => {
|
|
2487
2528
|
const { exit } = useApp();
|
|
2488
|
-
const [
|
|
2529
|
+
const [activeTab, setActiveTab] = useState4("logs");
|
|
2489
2530
|
const [logs, setLogs] = useState4([]);
|
|
2490
2531
|
const [serverInfo, setServerInfo] = useState4({
|
|
2491
2532
|
port: initialPort,
|
|
2492
2533
|
pid: process.pid,
|
|
2493
2534
|
running: false
|
|
2494
2535
|
});
|
|
2495
|
-
const [
|
|
2536
|
+
const [configVersion, setConfigVersion] = useState4(0);
|
|
2496
2537
|
const config = loadMCPConfig();
|
|
2497
2538
|
const projects = scanForProjects();
|
|
2498
2539
|
const exposedProjects = projects.filter((p) => {
|
|
@@ -2501,9 +2542,15 @@ var init_App = __esm({
|
|
|
2501
2542
|
);
|
|
2502
2543
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
2503
2544
|
});
|
|
2504
|
-
const
|
|
2505
|
-
const
|
|
2506
|
-
|
|
2545
|
+
const workspacePath = detectWorkspaceRoot();
|
|
2546
|
+
const installStatus = checkInstallStatus(workspacePath);
|
|
2547
|
+
const installedCount = [
|
|
2548
|
+
installStatus.antigravity,
|
|
2549
|
+
installStatus.claude,
|
|
2550
|
+
installStatus.vscodeGlobal,
|
|
2551
|
+
installStatus.vscodeWorkspace
|
|
2552
|
+
].filter(Boolean).length;
|
|
2553
|
+
useEffect4(() => {
|
|
2507
2554
|
const start = async () => {
|
|
2508
2555
|
const status = getMCPServerStatus();
|
|
2509
2556
|
if (!status.running) {
|
|
@@ -2511,17 +2558,15 @@ var init_App = __esm({
|
|
|
2511
2558
|
const res = await startMCPServer({ interactive: true });
|
|
2512
2559
|
setServerInfo((prev) => ({ ...prev, running: true, port: res.port, pid: res.pid }));
|
|
2513
2560
|
} catch (e) {
|
|
2514
|
-
setLogs((prev) => [...prev, `Error starting server: ${e}`]);
|
|
2561
|
+
setLogs((prev) => [...prev, `[ERROR] Error starting server: ${e}`]);
|
|
2515
2562
|
}
|
|
2516
2563
|
} else {
|
|
2517
2564
|
setServerInfo((prev) => ({ ...prev, running: true, port: status.port || initialPort, pid: status.pid || process.pid }));
|
|
2518
2565
|
}
|
|
2519
2566
|
};
|
|
2520
2567
|
start();
|
|
2521
|
-
return () => {
|
|
2522
|
-
};
|
|
2523
2568
|
}, []);
|
|
2524
|
-
|
|
2569
|
+
useEffect4(() => {
|
|
2525
2570
|
const logPath = getLogFilePath();
|
|
2526
2571
|
let lastSize = 0;
|
|
2527
2572
|
if (fs11.existsSync(logPath)) {
|
|
@@ -2540,7 +2585,7 @@ var init_App = __esm({
|
|
|
2540
2585
|
const newLines = newContent.split("\n").filter((l) => l.trim());
|
|
2541
2586
|
setLogs((prev) => {
|
|
2542
2587
|
const next = [...prev, ...newLines];
|
|
2543
|
-
return next.slice(-
|
|
2588
|
+
return next.slice(-100);
|
|
2544
2589
|
});
|
|
2545
2590
|
lastSize = stats.size;
|
|
2546
2591
|
}
|
|
@@ -2548,48 +2593,46 @@ var init_App = __esm({
|
|
|
2548
2593
|
}, 500);
|
|
2549
2594
|
return () => clearInterval(interval);
|
|
2550
2595
|
}, []);
|
|
2551
|
-
|
|
2596
|
+
useInput3((input, key) => {
|
|
2552
2597
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2553
2598
|
stopMCPServer();
|
|
2554
2599
|
onExit();
|
|
2555
2600
|
exit();
|
|
2556
2601
|
}
|
|
2557
|
-
|
|
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 });
|
|
2602
|
+
});
|
|
2573
2603
|
const termHeight = process.stdout.rows || 24;
|
|
2574
|
-
const
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
}
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2604
|
+
const contentHeight = termHeight - 8;
|
|
2605
|
+
const handleConfigChange = () => {
|
|
2606
|
+
setConfigVersion((prev) => prev + 1);
|
|
2607
|
+
};
|
|
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, { onConfigChange: handleConfigChange }),
|
|
2623
|
+
activeTab === "install" && /* @__PURE__ */ jsx10(InstallView, {}),
|
|
2624
|
+
activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight })
|
|
2625
|
+
] }),
|
|
2626
|
+
/* @__PURE__ */ jsx10(Box10, { marginTop: 0, children: /* @__PURE__ */ jsx10(
|
|
2627
|
+
StatusBoard,
|
|
2628
|
+
{
|
|
2629
|
+
exposedLabel: `${exposedProjects.length} / ${projects.length} projects`,
|
|
2630
|
+
port: serverInfo.port,
|
|
2631
|
+
pid: serverInfo.pid,
|
|
2632
|
+
running: serverInfo.running
|
|
2633
|
+
}
|
|
2634
|
+
) })
|
|
2635
|
+
] });
|
|
2593
2636
|
};
|
|
2594
2637
|
}
|
|
2595
2638
|
});
|
|
@@ -2770,7 +2813,7 @@ __export(mcp_exports, {
|
|
|
2770
2813
|
handleStartServer: () => handleStartServer,
|
|
2771
2814
|
runMCP: () => runMCP
|
|
2772
2815
|
});
|
|
2773
|
-
import { intro, outro,
|
|
2816
|
+
import { intro, outro, confirm as confirm2, note as note6, isCancel as isCancel5 } from "@clack/prompts";
|
|
2774
2817
|
import pc7 from "picocolors";
|
|
2775
2818
|
async function runMCP(subcommand2) {
|
|
2776
2819
|
if (subcommand2) {
|
|
@@ -2796,12 +2839,14 @@ async function runMCP(subcommand2) {
|
|
|
2796
2839
|
case "configure":
|
|
2797
2840
|
await handleConfigure();
|
|
2798
2841
|
return;
|
|
2842
|
+
case "menu":
|
|
2843
|
+
break;
|
|
2799
2844
|
}
|
|
2800
2845
|
}
|
|
2801
|
-
intro(pc7.bgCyan(pc7.black(" RRCE MCP Hub ")));
|
|
2802
2846
|
const workspacePath = detectWorkspaceRoot();
|
|
2803
2847
|
const globalPathCheck = await ensureMCPGlobalPath();
|
|
2804
2848
|
if (!globalPathCheck.configured) {
|
|
2849
|
+
intro(pc7.bgCyan(pc7.black(" MCP Setup ")));
|
|
2805
2850
|
const configured = await handleConfigureGlobalPath();
|
|
2806
2851
|
if (!configured) {
|
|
2807
2852
|
outro(pc7.yellow("MCP requires a global storage path. Setup cancelled."));
|
|
@@ -2810,101 +2855,46 @@ async function runMCP(subcommand2) {
|
|
|
2810
2855
|
}
|
|
2811
2856
|
const installed = isInstalledAnywhere(workspacePath);
|
|
2812
2857
|
if (!installed) {
|
|
2858
|
+
intro(pc7.bgCyan(pc7.black(" Welcome to MCP Hub ")));
|
|
2813
2859
|
note6(
|
|
2814
|
-
`${pc7.bold("
|
|
2815
|
-
|
|
2816
|
-
MCP (Model Context Protocol) allows AI assistants to access your
|
|
2817
|
-
project knowledge in real-time. Let's get you set up.`,
|
|
2860
|
+
`${pc7.bold("Set up Model Context Protocol")}
|
|
2861
|
+
Allow AI assistants to access your project context.`,
|
|
2818
2862
|
"Getting Started"
|
|
2819
2863
|
);
|
|
2820
2864
|
const shouldInstall = await confirm2({
|
|
2821
|
-
message: "Install MCP server
|
|
2865
|
+
message: "Install MCP server integrations now?",
|
|
2822
2866
|
initialValue: true
|
|
2823
2867
|
});
|
|
2824
2868
|
if (shouldInstall && !isCancel5(shouldInstall)) {
|
|
2825
2869
|
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
2870
|
const shouldStart = await confirm2({
|
|
2832
|
-
message: "Start the MCP
|
|
2871
|
+
message: "Start the MCP Dashboard?",
|
|
2833
2872
|
initialValue: true
|
|
2834
2873
|
});
|
|
2835
2874
|
if (shouldStart && !isCancel5(shouldStart)) {
|
|
2836
2875
|
await handleStartServer();
|
|
2837
2876
|
}
|
|
2877
|
+
} else {
|
|
2878
|
+
outro(pc7.dim('Setup skipped. Run "npx rrce-workflow mcp" later to restart.'));
|
|
2838
2879
|
}
|
|
2839
|
-
outro(pc7.green("MCP Hub setup complete!"));
|
|
2840
2880
|
return;
|
|
2841
2881
|
}
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
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
|
-
}
|
|
2882
|
+
try {
|
|
2883
|
+
await handleStartServer();
|
|
2884
|
+
} catch (err) {
|
|
2885
|
+
console.error(err);
|
|
2886
|
+
outro(pc7.red("Failed to launch MCP Dashboard"));
|
|
2889
2887
|
}
|
|
2890
|
-
outro(pc7.green("MCP Hub closed."));
|
|
2891
2888
|
}
|
|
2892
2889
|
async function handleStopServer() {
|
|
2893
2890
|
const { stopMCPServer: stopMCPServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2894
2891
|
const status = getMCPServerStatus();
|
|
2895
2892
|
if (!status.running) {
|
|
2896
|
-
|
|
2897
|
-
return;
|
|
2898
|
-
}
|
|
2899
|
-
const confirmed = await confirm2({
|
|
2900
|
-
message: "Stop the MCP server?",
|
|
2901
|
-
initialValue: true
|
|
2902
|
-
});
|
|
2903
|
-
if (isCancel5(confirmed) || !confirmed) {
|
|
2893
|
+
console.log(pc7.dim("MCP server is already stopped."));
|
|
2904
2894
|
return;
|
|
2905
2895
|
}
|
|
2906
2896
|
stopMCPServer2();
|
|
2907
|
-
|
|
2897
|
+
console.log(pc7.green("MCP server stopped."));
|
|
2908
2898
|
}
|
|
2909
2899
|
var init_mcp = __esm({
|
|
2910
2900
|
"src/mcp/index.ts"() {
|
|
@@ -2922,7 +2912,7 @@ var init_mcp = __esm({
|
|
|
2922
2912
|
});
|
|
2923
2913
|
|
|
2924
2914
|
// src/commands/wizard/setup-flow.ts
|
|
2925
|
-
import { group, select as
|
|
2915
|
+
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
2916
|
import pc8 from "picocolors";
|
|
2927
2917
|
import * as fs12 from "fs";
|
|
2928
2918
|
import * as path12 from "path";
|
|
@@ -2930,7 +2920,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
2930
2920
|
const s = spinner3();
|
|
2931
2921
|
const config = await group(
|
|
2932
2922
|
{
|
|
2933
|
-
storageMode: () =>
|
|
2923
|
+
storageMode: () => select2({
|
|
2934
2924
|
message: "Where should workflow data be stored?",
|
|
2935
2925
|
options: [
|
|
2936
2926
|
{ value: "global", label: "Global (~/.rrce-workflow/)", hint: "Cross-project access, clean workspace" },
|
|
@@ -3125,9 +3115,9 @@ linked_projects:
|
|
|
3125
3115
|
}
|
|
3126
3116
|
if (config.exposeToMCP) {
|
|
3127
3117
|
try {
|
|
3128
|
-
const { loadMCPConfig:
|
|
3118
|
+
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3129
3119
|
const { getWorkspaceName: getWorkspaceName2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
3130
|
-
const mcpConfig =
|
|
3120
|
+
const mcpConfig = loadMCPConfig3();
|
|
3131
3121
|
const currentProjectName = workspaceName;
|
|
3132
3122
|
if (config.storageMode === "workspace") {
|
|
3133
3123
|
setProjectConfig2(mcpConfig, currentProjectName, true);
|
|
@@ -3300,8 +3290,8 @@ linked_projects:
|
|
|
3300
3290
|
});
|
|
3301
3291
|
if (shouldExpose && !isCancel7(shouldExpose)) {
|
|
3302
3292
|
try {
|
|
3303
|
-
const { loadMCPConfig:
|
|
3304
|
-
const mcpConfig =
|
|
3293
|
+
const { loadMCPConfig: loadMCPConfig3, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3294
|
+
const mcpConfig = loadMCPConfig3();
|
|
3305
3295
|
for (const project of selectedProjects) {
|
|
3306
3296
|
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
3307
3297
|
}
|
|
@@ -3478,7 +3468,7 @@ var wizard_exports = {};
|
|
|
3478
3468
|
__export(wizard_exports, {
|
|
3479
3469
|
runWizard: () => runWizard
|
|
3480
3470
|
});
|
|
3481
|
-
import { intro as intro2, select as
|
|
3471
|
+
import { intro as intro2, select as select3, spinner as spinner7, note as note11, outro as outro6, isCancel as isCancel10 } from "@clack/prompts";
|
|
3482
3472
|
import pc12 from "picocolors";
|
|
3483
3473
|
import * as fs16 from "fs";
|
|
3484
3474
|
async function runWizard() {
|
|
@@ -3536,7 +3526,7 @@ Workspace: ${pc12.bold(workspaceName)}`,
|
|
|
3536
3526
|
menuOptions.push({ value: "update", label: "\u{1F4E6} Update from package", hint: "Get latest prompts & templates" });
|
|
3537
3527
|
menuOptions.push({ value: "reconfigure", label: "\u{1F527} Reconfigure project", hint: "Change storage mode, tools, etc." });
|
|
3538
3528
|
menuOptions.push({ value: "exit", label: "\u21A9 Exit" });
|
|
3539
|
-
const action = await
|
|
3529
|
+
const action = await select3({
|
|
3540
3530
|
message: "This workspace is already configured. What would you like to do?",
|
|
3541
3531
|
options: menuOptions
|
|
3542
3532
|
});
|
|
@@ -3584,7 +3574,7 @@ init_wizard();
|
|
|
3584
3574
|
|
|
3585
3575
|
// src/commands/selector.ts
|
|
3586
3576
|
init_prompts();
|
|
3587
|
-
import { intro as intro3, select as
|
|
3577
|
+
import { intro as intro3, select as select4, note as note12, cancel as cancel7, isCancel as isCancel11, outro as outro7 } from "@clack/prompts";
|
|
3588
3578
|
import pc13 from "picocolors";
|
|
3589
3579
|
import * as path15 from "path";
|
|
3590
3580
|
async function runSelector() {
|
|
@@ -3595,7 +3585,7 @@ async function runSelector() {
|
|
|
3595
3585
|
cancel7("No agents found. Run `rrce-workflow` to set up.");
|
|
3596
3586
|
process.exit(0);
|
|
3597
3587
|
}
|
|
3598
|
-
const selection = await
|
|
3588
|
+
const selection = await select4({
|
|
3599
3589
|
message: "Select an agent:",
|
|
3600
3590
|
options: [
|
|
3601
3591
|
{
|