rrce-workflow 0.3.10 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +665 -817
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2708,10 +2708,6 @@ function getExposedProjects() {
|
|
|
2708
2708
|
}
|
|
2709
2709
|
return potentialProjects.filter((project) => isProjectExposed(config, project.name, project.sourcePath || project.path));
|
|
2710
2710
|
}
|
|
2711
|
-
function getRAGIndexPath(project) {
|
|
2712
|
-
const scanRoot = project.path || project.dataPath;
|
|
2713
|
-
return path17.join(project.knowledgePath || path17.join(scanRoot, ".rrce-workflow", "knowledge"), "embeddings.json");
|
|
2714
|
-
}
|
|
2715
2711
|
function getCodeIndexPath(project) {
|
|
2716
2712
|
const scanRoot = project.path || project.dataPath;
|
|
2717
2713
|
return path17.join(project.knowledgePath || path17.join(scanRoot, ".rrce-workflow", "knowledge"), "code-embeddings.json");
|
|
@@ -4221,238 +4217,9 @@ var init_Header = __esm({
|
|
|
4221
4217
|
}
|
|
4222
4218
|
});
|
|
4223
4219
|
|
|
4224
|
-
// src/
|
|
4225
|
-
import { useMemo } from "react";
|
|
4226
|
-
import { Box as Box2, Text as Text2 } from "ink";
|
|
4227
|
-
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
4228
|
-
var Overview;
|
|
4229
|
-
var init_Overview = __esm({
|
|
4230
|
-
"src/mcp/ui/Overview.tsx"() {
|
|
4231
|
-
"use strict";
|
|
4232
|
-
init_Header();
|
|
4233
|
-
init_prompts2();
|
|
4234
|
-
Overview = ({ serverStatus, stats }) => {
|
|
4235
|
-
const agents = useMemo(() => getAllPrompts(), []);
|
|
4236
|
-
return /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", flexGrow: 1, children: [
|
|
4237
|
-
/* @__PURE__ */ jsx2(Header, {}),
|
|
4238
|
-
/* @__PURE__ */ jsxs(Box2, { borderStyle: "round", padding: 1, borderColor: "white", flexDirection: "column", flexGrow: 1, children: [
|
|
4239
|
-
/* @__PURE__ */ jsxs(Box2, { justifyContent: "space-between", children: [
|
|
4240
|
-
/* @__PURE__ */ jsxs(Box2, { flexDirection: "column", children: [
|
|
4241
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, underline: true, children: "System Status" }),
|
|
4242
|
-
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, children: [
|
|
4243
|
-
/* @__PURE__ */ jsx2(Text2, { children: "Integrations Installed: " }),
|
|
4244
|
-
/* @__PURE__ */ jsx2(Text2, { color: stats.installedIntegrations > 0 ? "green" : "yellow", children: stats.installedIntegrations })
|
|
4245
|
-
] }),
|
|
4246
|
-
/* @__PURE__ */ jsxs(Box2, { children: [
|
|
4247
|
-
/* @__PURE__ */ jsx2(Text2, { children: "Server Port: " }),
|
|
4248
|
-
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: serverStatus.port })
|
|
4249
|
-
] })
|
|
4250
|
-
] }),
|
|
4251
|
-
/* @__PURE__ */ jsxs(Box2, { flexDirection: "column", marginLeft: 4, children: [
|
|
4252
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, underline: true, children: "Quick Start" }),
|
|
4253
|
-
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
4254
|
-
/* @__PURE__ */ jsx2(Text2, { children: '1. Install "MCP" extension in VSCode / Antigravity' }),
|
|
4255
|
-
/* @__PURE__ */ jsx2(Text2, { children: "2. Configure Extension to use this server:" }),
|
|
4256
|
-
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: " (This is handled automatically by 'Install to IDE')" }),
|
|
4257
|
-
/* @__PURE__ */ jsx2(Text2, { children: "3. In your Agent IDE, ask:" }),
|
|
4258
|
-
/* @__PURE__ */ jsx2(Text2, { color: "cyan", children: ' "Use the rrce tools to analyze this project"' })
|
|
4259
|
-
] })
|
|
4260
|
-
] })
|
|
4261
|
-
] }),
|
|
4262
|
-
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, borderStyle: "single", borderColor: "gray", flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
4263
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, children: "Available Agents & Instructions:" }),
|
|
4264
|
-
agents.map((agent) => /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
4265
|
-
/* @__PURE__ */ jsxs(Text2, { color: "yellow", children: [
|
|
4266
|
-
"\u27A4 ",
|
|
4267
|
-
agent.name,
|
|
4268
|
-
" ",
|
|
4269
|
-
/* @__PURE__ */ jsxs(Text2, { color: "dim", children: [
|
|
4270
|
-
"(",
|
|
4271
|
-
agent.id,
|
|
4272
|
-
")"
|
|
4273
|
-
] })
|
|
4274
|
-
] }),
|
|
4275
|
-
/* @__PURE__ */ jsxs(Text2, { color: "white", children: [
|
|
4276
|
-
" ",
|
|
4277
|
-
agent.description
|
|
4278
|
-
] }),
|
|
4279
|
-
agent.arguments.length > 0 && /* @__PURE__ */ jsxs(Text2, { color: "dim", children: [
|
|
4280
|
-
" Args: ",
|
|
4281
|
-
agent.arguments.map((a) => a.name + (a.required ? "*" : "")).join(", ")
|
|
4282
|
-
] }),
|
|
4283
|
-
/* @__PURE__ */ jsxs(Text2, { color: "cyan", children: [
|
|
4284
|
-
' Instruction: "Use the ',
|
|
4285
|
-
agent.name,
|
|
4286
|
-
' to..."'
|
|
4287
|
-
] })
|
|
4288
|
-
] }, agent.id))
|
|
4289
|
-
] }),
|
|
4290
|
-
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
4291
|
-
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: "Controls:" }),
|
|
4292
|
-
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: " \u2022 Press 'r' to restart server" }),
|
|
4293
|
-
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: " \u2022 Use 1-4 or \u25C4/\u25BA to navigate tabs" }),
|
|
4294
|
-
/* @__PURE__ */ jsx2(Text2, { color: "dim", children: " \u2022 Press 'q' to stop server and exit" })
|
|
4295
|
-
] })
|
|
4296
|
-
] })
|
|
4297
|
-
] });
|
|
4298
|
-
};
|
|
4299
|
-
}
|
|
4300
|
-
});
|
|
4301
|
-
|
|
4302
|
-
// src/mcp/ui/components/SimpleSelect.tsx
|
|
4303
|
-
import { useState } from "react";
|
|
4304
|
-
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
4305
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4306
|
-
function SimpleSelect({
|
|
4307
|
-
items,
|
|
4308
|
-
onSelect,
|
|
4309
|
-
isMulti = false,
|
|
4310
|
-
initialSelected = [],
|
|
4311
|
-
onSubmit,
|
|
4312
|
-
onCancel,
|
|
4313
|
-
message
|
|
4314
|
-
}) {
|
|
4315
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
4316
|
-
const [selectedValues, setSelectedValues] = useState(new Set(initialSelected));
|
|
4317
|
-
useInput((input, key) => {
|
|
4318
|
-
if (key.upArrow) {
|
|
4319
|
-
setSelectedIndex((prev) => prev > 0 ? prev - 1 : items.length - 1);
|
|
4320
|
-
}
|
|
4321
|
-
if (key.downArrow) {
|
|
4322
|
-
setSelectedIndex((prev) => prev < items.length - 1 ? prev + 1 : 0);
|
|
4323
|
-
}
|
|
4324
|
-
if (input === " " && isMulti) {
|
|
4325
|
-
const item = items[selectedIndex];
|
|
4326
|
-
if (item) {
|
|
4327
|
-
const newSet = new Set(selectedValues);
|
|
4328
|
-
if (newSet.has(item.value)) {
|
|
4329
|
-
newSet.delete(item.value);
|
|
4330
|
-
} else {
|
|
4331
|
-
newSet.add(item.value);
|
|
4332
|
-
}
|
|
4333
|
-
setSelectedValues(newSet);
|
|
4334
|
-
}
|
|
4335
|
-
}
|
|
4336
|
-
if (key.return) {
|
|
4337
|
-
if (isMulti) {
|
|
4338
|
-
onSubmit?.(Array.from(selectedValues));
|
|
4339
|
-
} else {
|
|
4340
|
-
const item = items[selectedIndex];
|
|
4341
|
-
if (item) onSelect(item);
|
|
4342
|
-
}
|
|
4343
|
-
}
|
|
4344
|
-
if (key.escape) {
|
|
4345
|
-
onCancel?.();
|
|
4346
|
-
}
|
|
4347
|
-
});
|
|
4348
|
-
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
|
|
4349
|
-
message && /* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { bold: true, children: message }) }),
|
|
4350
|
-
items.map((item, index) => {
|
|
4351
|
-
const isSelected = index === selectedIndex;
|
|
4352
|
-
const isChecked = isMulti && selectedValues.has(item.value);
|
|
4353
|
-
return /* @__PURE__ */ jsxs2(Box3, { children: [
|
|
4354
|
-
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
|
|
4355
|
-
isMulti && /* @__PURE__ */ jsx3(Text3, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
|
|
4356
|
-
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "cyan" : "white", children: item.label })
|
|
4357
|
-
] }, item.key || String(item.value));
|
|
4358
|
-
}),
|
|
4359
|
-
/* @__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" }) })
|
|
4360
|
-
] });
|
|
4361
|
-
}
|
|
4362
|
-
var init_SimpleSelect = __esm({
|
|
4363
|
-
"src/mcp/ui/components/SimpleSelect.tsx"() {
|
|
4364
|
-
"use strict";
|
|
4365
|
-
}
|
|
4366
|
-
});
|
|
4367
|
-
|
|
4368
|
-
// src/mcp/ui/lib/tasks-fs.ts
|
|
4220
|
+
// src/lib/drift-service.ts
|
|
4369
4221
|
import * as fs17 from "fs";
|
|
4370
4222
|
import * as path19 from "path";
|
|
4371
|
-
function detectStorageModeFromConfig(workspaceRoot) {
|
|
4372
|
-
const configPath = getConfigPath(workspaceRoot);
|
|
4373
|
-
try {
|
|
4374
|
-
const rrceHome = getEffectiveGlobalBase();
|
|
4375
|
-
if (configPath.startsWith(rrceHome)) {
|
|
4376
|
-
return "global";
|
|
4377
|
-
}
|
|
4378
|
-
if (fs17.existsSync(configPath)) {
|
|
4379
|
-
const content = fs17.readFileSync(configPath, "utf-8");
|
|
4380
|
-
if (content.includes("mode: workspace")) return "workspace";
|
|
4381
|
-
if (content.includes("mode: global")) return "global";
|
|
4382
|
-
}
|
|
4383
|
-
} catch {
|
|
4384
|
-
}
|
|
4385
|
-
return "global";
|
|
4386
|
-
}
|
|
4387
|
-
function getEffectiveGlobalBase() {
|
|
4388
|
-
const dummy = resolveDataPath("global", "__rrce_dummy__", "");
|
|
4389
|
-
return path19.dirname(path19.dirname(dummy));
|
|
4390
|
-
}
|
|
4391
|
-
function getProjectRRCEData(project) {
|
|
4392
|
-
const workspaceRoot = project.sourcePath || project.path;
|
|
4393
|
-
const mode = detectStorageModeFromConfig(workspaceRoot);
|
|
4394
|
-
return resolveDataPath(mode, project.name, workspaceRoot);
|
|
4395
|
-
}
|
|
4396
|
-
function listProjectTasks(project) {
|
|
4397
|
-
const rrceData = getProjectRRCEData(project);
|
|
4398
|
-
const tasksPath = path19.join(rrceData, "tasks");
|
|
4399
|
-
if (!fs17.existsSync(tasksPath)) {
|
|
4400
|
-
return { projectName: project.name, tasksPath, tasks: [] };
|
|
4401
|
-
}
|
|
4402
|
-
const tasks = [];
|
|
4403
|
-
try {
|
|
4404
|
-
const entries = fs17.readdirSync(tasksPath, { withFileTypes: true });
|
|
4405
|
-
for (const entry of entries) {
|
|
4406
|
-
if (!entry.isDirectory()) continue;
|
|
4407
|
-
const metaPath = path19.join(tasksPath, entry.name, "meta.json");
|
|
4408
|
-
if (!fs17.existsSync(metaPath)) continue;
|
|
4409
|
-
try {
|
|
4410
|
-
const raw = fs17.readFileSync(metaPath, "utf-8");
|
|
4411
|
-
const meta = JSON.parse(raw);
|
|
4412
|
-
if (!meta.task_slug) meta.task_slug = entry.name;
|
|
4413
|
-
tasks.push(meta);
|
|
4414
|
-
} catch {
|
|
4415
|
-
}
|
|
4416
|
-
}
|
|
4417
|
-
} catch {
|
|
4418
|
-
}
|
|
4419
|
-
tasks.sort((a, b) => {
|
|
4420
|
-
const aTime = Date.parse(a.updated_at || a.created_at || "") || 0;
|
|
4421
|
-
const bTime = Date.parse(b.updated_at || b.created_at || "") || 0;
|
|
4422
|
-
if (aTime !== bTime) return bTime - aTime;
|
|
4423
|
-
return String(a.task_slug).localeCompare(String(b.task_slug));
|
|
4424
|
-
});
|
|
4425
|
-
return { projectName: project.name, tasksPath, tasks };
|
|
4426
|
-
}
|
|
4427
|
-
function updateTaskStatus(project, taskSlug, status) {
|
|
4428
|
-
const rrceData = getProjectRRCEData(project);
|
|
4429
|
-
const metaPath = path19.join(rrceData, "tasks", taskSlug, "meta.json");
|
|
4430
|
-
if (!fs17.existsSync(metaPath)) {
|
|
4431
|
-
return { ok: false, error: `meta.json not found for task '${taskSlug}'` };
|
|
4432
|
-
}
|
|
4433
|
-
try {
|
|
4434
|
-
const meta = JSON.parse(fs17.readFileSync(metaPath, "utf-8"));
|
|
4435
|
-
const next = {
|
|
4436
|
-
...meta,
|
|
4437
|
-
status,
|
|
4438
|
-
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4439
|
-
};
|
|
4440
|
-
fs17.writeFileSync(metaPath, JSON.stringify(next, null, 2));
|
|
4441
|
-
return { ok: true, meta: next };
|
|
4442
|
-
} catch (e) {
|
|
4443
|
-
return { ok: false, error: String(e) };
|
|
4444
|
-
}
|
|
4445
|
-
}
|
|
4446
|
-
var init_tasks_fs = __esm({
|
|
4447
|
-
"src/mcp/ui/lib/tasks-fs.ts"() {
|
|
4448
|
-
"use strict";
|
|
4449
|
-
init_paths();
|
|
4450
|
-
}
|
|
4451
|
-
});
|
|
4452
|
-
|
|
4453
|
-
// src/lib/drift-service.ts
|
|
4454
|
-
import * as fs18 from "fs";
|
|
4455
|
-
import * as path20 from "path";
|
|
4456
4223
|
import * as crypto2 from "crypto";
|
|
4457
4224
|
var DriftService;
|
|
4458
4225
|
var init_drift_service = __esm({
|
|
@@ -4461,26 +4228,26 @@ var init_drift_service = __esm({
|
|
|
4461
4228
|
DriftService = class {
|
|
4462
4229
|
static CHECKSUM_FILENAME = ".rrce-checksums.json";
|
|
4463
4230
|
static calculateHash(filePath) {
|
|
4464
|
-
const content =
|
|
4231
|
+
const content = fs17.readFileSync(filePath);
|
|
4465
4232
|
return crypto2.createHash("md5").update(content).digest("hex");
|
|
4466
4233
|
}
|
|
4467
4234
|
static getManifestPath(projectPath) {
|
|
4468
|
-
return
|
|
4235
|
+
return path19.join(projectPath, this.CHECKSUM_FILENAME);
|
|
4469
4236
|
}
|
|
4470
4237
|
static loadManifest(projectPath) {
|
|
4471
4238
|
const manifestPath = this.getManifestPath(projectPath);
|
|
4472
|
-
if (!
|
|
4239
|
+
if (!fs17.existsSync(manifestPath)) {
|
|
4473
4240
|
return {};
|
|
4474
4241
|
}
|
|
4475
4242
|
try {
|
|
4476
|
-
return JSON.parse(
|
|
4243
|
+
return JSON.parse(fs17.readFileSync(manifestPath, "utf8"));
|
|
4477
4244
|
} catch (e) {
|
|
4478
4245
|
return {};
|
|
4479
4246
|
}
|
|
4480
4247
|
}
|
|
4481
4248
|
static saveManifest(projectPath, manifest) {
|
|
4482
4249
|
const manifestPath = this.getManifestPath(projectPath);
|
|
4483
|
-
|
|
4250
|
+
fs17.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
4484
4251
|
}
|
|
4485
4252
|
/**
|
|
4486
4253
|
* Generates a manifest for the current state of files in the project
|
|
@@ -4488,9 +4255,9 @@ var init_drift_service = __esm({
|
|
|
4488
4255
|
static generateManifest(projectPath, files) {
|
|
4489
4256
|
const manifest = {};
|
|
4490
4257
|
for (const file of files) {
|
|
4491
|
-
const fullPath =
|
|
4492
|
-
if (
|
|
4493
|
-
const stats =
|
|
4258
|
+
const fullPath = path19.join(projectPath, file);
|
|
4259
|
+
if (fs17.existsSync(fullPath)) {
|
|
4260
|
+
const stats = fs17.statSync(fullPath);
|
|
4494
4261
|
manifest[file] = {
|
|
4495
4262
|
hash: this.calculateHash(fullPath),
|
|
4496
4263
|
mtime: stats.mtimeMs
|
|
@@ -4506,11 +4273,11 @@ var init_drift_service = __esm({
|
|
|
4506
4273
|
const manifest = this.loadManifest(projectPath);
|
|
4507
4274
|
const modifiedFiles = [];
|
|
4508
4275
|
for (const [relPath, entry] of Object.entries(manifest)) {
|
|
4509
|
-
const fullPath =
|
|
4510
|
-
if (!
|
|
4276
|
+
const fullPath = path19.join(projectPath, relPath);
|
|
4277
|
+
if (!fs17.existsSync(fullPath)) {
|
|
4511
4278
|
continue;
|
|
4512
4279
|
}
|
|
4513
|
-
const stats =
|
|
4280
|
+
const stats = fs17.statSync(fullPath);
|
|
4514
4281
|
if (stats.mtimeMs === entry.mtime) {
|
|
4515
4282
|
continue;
|
|
4516
4283
|
}
|
|
@@ -4556,16 +4323,16 @@ __export(ConfigContext_exports, {
|
|
|
4556
4323
|
ConfigProvider: () => ConfigProvider,
|
|
4557
4324
|
useConfig: () => useConfig
|
|
4558
4325
|
});
|
|
4559
|
-
import { createContext, useContext, useState
|
|
4560
|
-
import * as
|
|
4561
|
-
import * as
|
|
4562
|
-
import { jsx as
|
|
4326
|
+
import { createContext, useContext, useState, useCallback, useMemo, useEffect } from "react";
|
|
4327
|
+
import * as fs18 from "fs";
|
|
4328
|
+
import * as path20 from "path";
|
|
4329
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
4563
4330
|
function getPackageVersion() {
|
|
4564
4331
|
try {
|
|
4565
4332
|
const agentCoreDir = getAgentCoreDir();
|
|
4566
|
-
const packageJsonPath =
|
|
4567
|
-
if (
|
|
4568
|
-
return JSON.parse(
|
|
4333
|
+
const packageJsonPath = path20.join(path20.dirname(agentCoreDir), "package.json");
|
|
4334
|
+
if (fs18.existsSync(packageJsonPath)) {
|
|
4335
|
+
return JSON.parse(fs18.readFileSync(packageJsonPath, "utf8")).version;
|
|
4569
4336
|
}
|
|
4570
4337
|
} catch (e) {
|
|
4571
4338
|
}
|
|
@@ -4589,9 +4356,9 @@ var init_ConfigContext = __esm({
|
|
|
4589
4356
|
init_prompts();
|
|
4590
4357
|
ConfigContext = createContext(null);
|
|
4591
4358
|
ConfigProvider = ({ children }) => {
|
|
4592
|
-
const [config, setConfig] =
|
|
4593
|
-
const [projects, setProjects] =
|
|
4594
|
-
const [driftReports, setDriftReports] =
|
|
4359
|
+
const [config, setConfig] = useState(() => loadMCPConfig());
|
|
4360
|
+
const [projects, setProjects] = useState(() => scanForProjects());
|
|
4361
|
+
const [driftReports, setDriftReports] = useState({});
|
|
4595
4362
|
const refresh = useCallback(() => {
|
|
4596
4363
|
const newConfig = loadMCPConfig();
|
|
4597
4364
|
const newProjects = scanForProjects();
|
|
@@ -4608,17 +4375,17 @@ var init_ConfigContext = __esm({
|
|
|
4608
4375
|
}
|
|
4609
4376
|
setDriftReports(reports);
|
|
4610
4377
|
}, [projects, config]);
|
|
4611
|
-
|
|
4378
|
+
useEffect(() => {
|
|
4612
4379
|
checkAllDrift();
|
|
4613
4380
|
}, [checkAllDrift]);
|
|
4614
|
-
const exposedProjects =
|
|
4381
|
+
const exposedProjects = useMemo(
|
|
4615
4382
|
() => projects.filter((p) => {
|
|
4616
4383
|
const cfg = findProjectConfig(config, { name: p.name, path: p.path });
|
|
4617
4384
|
return cfg?.expose ?? config.defaults.includeNew;
|
|
4618
4385
|
}),
|
|
4619
4386
|
[projects, config]
|
|
4620
4387
|
);
|
|
4621
|
-
const value =
|
|
4388
|
+
const value = useMemo(() => ({
|
|
4622
4389
|
config,
|
|
4623
4390
|
projects,
|
|
4624
4391
|
exposedProjects,
|
|
@@ -4626,94 +4393,297 @@ var init_ConfigContext = __esm({
|
|
|
4626
4393
|
refresh,
|
|
4627
4394
|
checkAllDrift
|
|
4628
4395
|
}), [config, projects, exposedProjects, driftReports, refresh, checkAllDrift]);
|
|
4629
|
-
return /* @__PURE__ */
|
|
4396
|
+
return /* @__PURE__ */ jsx2(ConfigContext.Provider, { value, children });
|
|
4630
4397
|
};
|
|
4631
4398
|
}
|
|
4632
4399
|
});
|
|
4633
4400
|
|
|
4634
|
-
// src/mcp/ui/
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
pending: "yellow",
|
|
4651
|
-
in_progress: "yellow",
|
|
4652
|
-
blocked: "red",
|
|
4653
|
-
complete: "green"
|
|
4654
|
-
};
|
|
4655
|
-
return colors[status] || "white";
|
|
4656
|
-
};
|
|
4657
|
-
getChecklistProgress = (checklist) => {
|
|
4658
|
-
if (!checklist || checklist.length === 0) {
|
|
4659
|
-
return { completed: 0, total: 0, percentage: 0 };
|
|
4660
|
-
}
|
|
4661
|
-
const completed = checklist.filter((item) => item.status === "done").length;
|
|
4662
|
-
return {
|
|
4663
|
-
completed,
|
|
4664
|
-
total: checklist.length,
|
|
4665
|
-
percentage: Math.round(completed / checklist.length * 100)
|
|
4666
|
-
};
|
|
4667
|
-
};
|
|
4668
|
-
getCheckbox = (status) => {
|
|
4669
|
-
return status === "done" ? "\u2611" : "\u2610";
|
|
4670
|
-
};
|
|
4671
|
-
getProgressBar = (percentage, length = 10) => {
|
|
4672
|
-
const filled = Math.floor(percentage / 100 * length);
|
|
4673
|
-
const empty = length - filled;
|
|
4674
|
-
return "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
4675
|
-
};
|
|
4676
|
-
getFolderIcon = (isOpen) => {
|
|
4677
|
-
return isOpen ? "\u{1F4C2}" : "\u{1F4C1}";
|
|
4678
|
-
};
|
|
4401
|
+
// src/mcp/ui/lib/tasks-fs.ts
|
|
4402
|
+
import * as fs19 from "fs";
|
|
4403
|
+
import * as path21 from "path";
|
|
4404
|
+
function detectStorageModeFromConfig(workspaceRoot) {
|
|
4405
|
+
const configPath = getConfigPath(workspaceRoot);
|
|
4406
|
+
try {
|
|
4407
|
+
const rrceHome = getEffectiveGlobalBase();
|
|
4408
|
+
if (configPath.startsWith(rrceHome)) {
|
|
4409
|
+
return "global";
|
|
4410
|
+
}
|
|
4411
|
+
if (fs19.existsSync(configPath)) {
|
|
4412
|
+
const content = fs19.readFileSync(configPath, "utf-8");
|
|
4413
|
+
if (content.includes("mode: workspace")) return "workspace";
|
|
4414
|
+
if (content.includes("mode: global")) return "global";
|
|
4415
|
+
}
|
|
4416
|
+
} catch {
|
|
4679
4417
|
}
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
// src/mcp/ui/ProjectsView.tsx
|
|
4683
|
-
import { useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
4684
|
-
import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
|
|
4685
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4686
|
-
function nextStatus(current) {
|
|
4687
|
-
const idx = STATUS_CYCLE.indexOf(current || "");
|
|
4688
|
-
if (idx === -1) return STATUS_CYCLE[0];
|
|
4689
|
-
return STATUS_CYCLE[(idx + 1) % STATUS_CYCLE.length];
|
|
4418
|
+
return "global";
|
|
4690
4419
|
}
|
|
4691
|
-
function
|
|
4692
|
-
|
|
4420
|
+
function getEffectiveGlobalBase() {
|
|
4421
|
+
const dummy = resolveDataPath("global", "__rrce_dummy__", "");
|
|
4422
|
+
return path21.dirname(path21.dirname(dummy));
|
|
4693
4423
|
}
|
|
4694
|
-
function
|
|
4695
|
-
const
|
|
4696
|
-
const
|
|
4697
|
-
return
|
|
4424
|
+
function getProjectRRCEData(project) {
|
|
4425
|
+
const workspaceRoot = project.sourcePath || project.path;
|
|
4426
|
+
const mode = detectStorageModeFromConfig(workspaceRoot);
|
|
4427
|
+
return resolveDataPath(mode, project.name, workspaceRoot);
|
|
4698
4428
|
}
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4429
|
+
function listProjectTasks(project) {
|
|
4430
|
+
const rrceData = getProjectRRCEData(project);
|
|
4431
|
+
const tasksPath = path21.join(rrceData, "tasks");
|
|
4432
|
+
if (!fs19.existsSync(tasksPath)) {
|
|
4433
|
+
return { projectName: project.name, tasksPath, tasks: [] };
|
|
4434
|
+
}
|
|
4435
|
+
const tasks = [];
|
|
4436
|
+
try {
|
|
4437
|
+
const entries = fs19.readdirSync(tasksPath, { withFileTypes: true });
|
|
4438
|
+
for (const entry of entries) {
|
|
4439
|
+
if (!entry.isDirectory()) continue;
|
|
4440
|
+
const metaPath = path21.join(tasksPath, entry.name, "meta.json");
|
|
4441
|
+
if (!fs19.existsSync(metaPath)) continue;
|
|
4442
|
+
try {
|
|
4443
|
+
const raw = fs19.readFileSync(metaPath, "utf-8");
|
|
4444
|
+
const meta = JSON.parse(raw);
|
|
4445
|
+
if (!meta.task_slug) meta.task_slug = entry.name;
|
|
4446
|
+
tasks.push(meta);
|
|
4447
|
+
} catch {
|
|
4448
|
+
}
|
|
4449
|
+
}
|
|
4450
|
+
} catch {
|
|
4451
|
+
}
|
|
4452
|
+
tasks.sort((a, b) => {
|
|
4453
|
+
const aTime = Date.parse(a.updated_at || a.created_at || "") || 0;
|
|
4454
|
+
const bTime = Date.parse(b.updated_at || b.created_at || "") || 0;
|
|
4455
|
+
if (aTime !== bTime) return bTime - aTime;
|
|
4456
|
+
return String(a.task_slug).localeCompare(String(b.task_slug));
|
|
4457
|
+
});
|
|
4458
|
+
return { projectName: project.name, tasksPath, tasks };
|
|
4459
|
+
}
|
|
4460
|
+
function updateTaskStatus(project, taskSlug, status) {
|
|
4461
|
+
const rrceData = getProjectRRCEData(project);
|
|
4462
|
+
const metaPath = path21.join(rrceData, "tasks", taskSlug, "meta.json");
|
|
4463
|
+
if (!fs19.existsSync(metaPath)) {
|
|
4464
|
+
return { ok: false, error: `meta.json not found for task '${taskSlug}'` };
|
|
4465
|
+
}
|
|
4466
|
+
try {
|
|
4467
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
4468
|
+
const next = {
|
|
4469
|
+
...meta,
|
|
4470
|
+
status,
|
|
4471
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4472
|
+
};
|
|
4473
|
+
fs19.writeFileSync(metaPath, JSON.stringify(next, null, 2));
|
|
4474
|
+
return { ok: true, meta: next };
|
|
4475
|
+
} catch (e) {
|
|
4476
|
+
return { ok: false, error: String(e) };
|
|
4477
|
+
}
|
|
4478
|
+
}
|
|
4479
|
+
var init_tasks_fs = __esm({
|
|
4480
|
+
"src/mcp/ui/lib/tasks-fs.ts"() {
|
|
4481
|
+
"use strict";
|
|
4482
|
+
init_paths();
|
|
4483
|
+
}
|
|
4484
|
+
});
|
|
4485
|
+
|
|
4486
|
+
// src/mcp/ui/Overview.tsx
|
|
4487
|
+
import { useMemo as useMemo2 } from "react";
|
|
4488
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
4489
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
4490
|
+
var Overview;
|
|
4491
|
+
var init_Overview = __esm({
|
|
4492
|
+
"src/mcp/ui/Overview.tsx"() {
|
|
4493
|
+
"use strict";
|
|
4494
|
+
init_Header();
|
|
4495
|
+
init_ConfigContext();
|
|
4705
4496
|
init_tasks_fs();
|
|
4497
|
+
Overview = ({ serverStatus, stats, logs }) => {
|
|
4498
|
+
const { projects } = useConfig();
|
|
4499
|
+
const activeTasks = useMemo2(() => {
|
|
4500
|
+
const active = [];
|
|
4501
|
+
for (const p of projects) {
|
|
4502
|
+
const { tasks } = listProjectTasks(p);
|
|
4503
|
+
const inProgress = tasks.filter((t) => t.status === "in_progress");
|
|
4504
|
+
for (const t of inProgress) {
|
|
4505
|
+
active.push({ project: p.name, title: t.title || t.task_slug, slug: t.task_slug });
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
return active;
|
|
4509
|
+
}, [projects]);
|
|
4510
|
+
const recentLogs = useMemo2(() => {
|
|
4511
|
+
return logs.slice(-5).reverse();
|
|
4512
|
+
}, [logs]);
|
|
4513
|
+
return /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", flexGrow: 1, children: [
|
|
4514
|
+
/* @__PURE__ */ jsx3(Header, {}),
|
|
4515
|
+
/* @__PURE__ */ jsxs(Box2, { borderStyle: "round", paddingX: 1, borderColor: "white", flexDirection: "column", flexGrow: 1, children: [
|
|
4516
|
+
/* @__PURE__ */ jsxs(Box2, { justifyContent: "space-between", children: [
|
|
4517
|
+
/* @__PURE__ */ jsxs(Box2, { flexDirection: "column", width: "50%", children: [
|
|
4518
|
+
/* @__PURE__ */ jsx3(Text2, { bold: true, color: "cyan", children: "\u{1F680} System Cockpit" }),
|
|
4519
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, children: [
|
|
4520
|
+
/* @__PURE__ */ jsx3(Text2, { children: "Integrations: " }),
|
|
4521
|
+
/* @__PURE__ */ jsxs(Text2, { color: stats.installedIntegrations > 0 ? "green" : "yellow", children: [
|
|
4522
|
+
stats.installedIntegrations,
|
|
4523
|
+
" active"
|
|
4524
|
+
] })
|
|
4525
|
+
] }),
|
|
4526
|
+
/* @__PURE__ */ jsxs(Box2, { children: [
|
|
4527
|
+
/* @__PURE__ */ jsx3(Text2, { children: "MCP Server: " }),
|
|
4528
|
+
/* @__PURE__ */ jsx3(Text2, { color: "green", children: "Running" }),
|
|
4529
|
+
/* @__PURE__ */ jsxs(Text2, { color: "dim", children: [
|
|
4530
|
+
" (Port: ",
|
|
4531
|
+
serverStatus.port,
|
|
4532
|
+
")"
|
|
4533
|
+
] })
|
|
4534
|
+
] }),
|
|
4535
|
+
/* @__PURE__ */ jsxs(Box2, { children: [
|
|
4536
|
+
/* @__PURE__ */ jsx3(Text2, { children: "Projects: " }),
|
|
4537
|
+
/* @__PURE__ */ jsxs(Text2, { children: [
|
|
4538
|
+
stats.exposedProjects,
|
|
4539
|
+
" / ",
|
|
4540
|
+
stats.totalProjects,
|
|
4541
|
+
" exposed"
|
|
4542
|
+
] })
|
|
4543
|
+
] })
|
|
4544
|
+
] }),
|
|
4545
|
+
/* @__PURE__ */ jsxs(Box2, { flexDirection: "column", width: "50%", paddingLeft: 2, children: [
|
|
4546
|
+
/* @__PURE__ */ jsx3(Text2, { bold: true, color: "magenta", children: "\u26A1 Slash Commands" }),
|
|
4547
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
4548
|
+
/* @__PURE__ */ jsxs(Text2, { color: "cyan", children: [
|
|
4549
|
+
"/rrce_init ",
|
|
4550
|
+
/* @__PURE__ */ jsx3(Text2, { color: "dim", children: "- Setup workspace" })
|
|
4551
|
+
] }),
|
|
4552
|
+
/* @__PURE__ */ jsxs(Text2, { color: "cyan", children: [
|
|
4553
|
+
"/rrce_research ",
|
|
4554
|
+
/* @__PURE__ */ jsx3(Text2, { color: "dim", children: "- Clarify requirements" })
|
|
4555
|
+
] }),
|
|
4556
|
+
/* @__PURE__ */ jsxs(Text2, { color: "cyan", children: [
|
|
4557
|
+
"/rrce_plan ",
|
|
4558
|
+
/* @__PURE__ */ jsx3(Text2, { color: "dim", children: "- Generate plan" })
|
|
4559
|
+
] }),
|
|
4560
|
+
/* @__PURE__ */ jsxs(Text2, { color: "cyan", children: [
|
|
4561
|
+
"/rrce_execute ",
|
|
4562
|
+
/* @__PURE__ */ jsx3(Text2, { color: "dim", children: "- Run executor" })
|
|
4563
|
+
] })
|
|
4564
|
+
] })
|
|
4565
|
+
] })
|
|
4566
|
+
] }),
|
|
4567
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, borderStyle: "single", borderColor: "blue", flexDirection: "column", paddingX: 1, children: [
|
|
4568
|
+
/* @__PURE__ */ jsx3(Text2, { bold: true, color: "blue", children: "\u{1F3C3} Active Tasks" }),
|
|
4569
|
+
activeTasks.length === 0 ? /* @__PURE__ */ jsx3(Box2, { paddingY: 1, children: /* @__PURE__ */ jsx3(Text2, { color: "dim", children: "No tasks currently in progress." }) }) : activeTasks.slice(0, 3).map((t, i) => /* @__PURE__ */ jsxs(Box2, { marginTop: i === 0 ? 0 : 0, children: [
|
|
4570
|
+
/* @__PURE__ */ jsxs(Text2, { color: "yellow", children: [
|
|
4571
|
+
"\u{1F504} ",
|
|
4572
|
+
t.project,
|
|
4573
|
+
": "
|
|
4574
|
+
] }),
|
|
4575
|
+
/* @__PURE__ */ jsx3(Text2, { children: t.title })
|
|
4576
|
+
] }, `${t.project}-${t.slug}`)),
|
|
4577
|
+
activeTasks.length > 3 && /* @__PURE__ */ jsxs(Text2, { color: "dim", children: [
|
|
4578
|
+
" ...and ",
|
|
4579
|
+
activeTasks.length - 3,
|
|
4580
|
+
" more"
|
|
4581
|
+
] })
|
|
4582
|
+
] }),
|
|
4583
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 1, borderStyle: "single", borderColor: "dim", flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
4584
|
+
/* @__PURE__ */ jsx3(Text2, { bold: true, color: "dim", children: "\u{1F4DC} Recent Activity" }),
|
|
4585
|
+
/* @__PURE__ */ jsx3(Box2, { flexDirection: "column", marginTop: 0, children: recentLogs.length === 0 ? /* @__PURE__ */ jsx3(Text2, { color: "dim", children: "Waiting for activity..." }) : recentLogs.map((log, i) => /* @__PURE__ */ jsx3(Text2, { color: "white", wrap: "truncate-end", children: log.length > 80 ? log.substring(0, 77) + "..." : log }, i)) })
|
|
4586
|
+
] }),
|
|
4587
|
+
/* @__PURE__ */ jsxs(Box2, { marginTop: 0, justifyContent: "space-between", children: [
|
|
4588
|
+
/* @__PURE__ */ jsx3(Box2, { children: /* @__PURE__ */ jsx3(Text2, { color: "dim", children: "r:Restart q:Quit 1-4/\u25C4 \u25BA:Tabs" }) }),
|
|
4589
|
+
/* @__PURE__ */ jsx3(Box2, { children: /* @__PURE__ */ jsx3(Text2, { color: "dim", children: "RRCE MCP Hub v0.3.7" }) })
|
|
4590
|
+
] })
|
|
4591
|
+
] })
|
|
4592
|
+
] });
|
|
4593
|
+
};
|
|
4594
|
+
}
|
|
4595
|
+
});
|
|
4596
|
+
|
|
4597
|
+
// src/mcp/ui/components/SimpleSelect.tsx
|
|
4598
|
+
import { useState as useState2 } from "react";
|
|
4599
|
+
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
4600
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4601
|
+
function SimpleSelect({
|
|
4602
|
+
items,
|
|
4603
|
+
onSelect,
|
|
4604
|
+
isMulti = false,
|
|
4605
|
+
initialSelected = [],
|
|
4606
|
+
onSubmit,
|
|
4607
|
+
onCancel,
|
|
4608
|
+
message
|
|
4609
|
+
}) {
|
|
4610
|
+
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
4611
|
+
const [selectedValues, setSelectedValues] = useState2(new Set(initialSelected));
|
|
4612
|
+
useInput((input, key) => {
|
|
4613
|
+
if (key.upArrow) {
|
|
4614
|
+
setSelectedIndex((prev) => prev > 0 ? prev - 1 : items.length - 1);
|
|
4615
|
+
}
|
|
4616
|
+
if (key.downArrow) {
|
|
4617
|
+
setSelectedIndex((prev) => prev < items.length - 1 ? prev + 1 : 0);
|
|
4618
|
+
}
|
|
4619
|
+
if (input === " " && isMulti) {
|
|
4620
|
+
const item = items[selectedIndex];
|
|
4621
|
+
if (item) {
|
|
4622
|
+
const newSet = new Set(selectedValues);
|
|
4623
|
+
if (newSet.has(item.value)) {
|
|
4624
|
+
newSet.delete(item.value);
|
|
4625
|
+
} else {
|
|
4626
|
+
newSet.add(item.value);
|
|
4627
|
+
}
|
|
4628
|
+
setSelectedValues(newSet);
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
if (key.return) {
|
|
4632
|
+
if (isMulti) {
|
|
4633
|
+
onSubmit?.(Array.from(selectedValues));
|
|
4634
|
+
} else {
|
|
4635
|
+
const item = items[selectedIndex];
|
|
4636
|
+
if (item) onSelect(item);
|
|
4637
|
+
}
|
|
4638
|
+
}
|
|
4639
|
+
if (key.escape) {
|
|
4640
|
+
onCancel?.();
|
|
4641
|
+
}
|
|
4642
|
+
});
|
|
4643
|
+
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
|
|
4644
|
+
message && /* @__PURE__ */ jsx4(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx4(Text3, { bold: true, children: message }) }),
|
|
4645
|
+
items.map((item, index) => {
|
|
4646
|
+
const isSelected = index === selectedIndex;
|
|
4647
|
+
const isChecked = isMulti && selectedValues.has(item.value);
|
|
4648
|
+
return /* @__PURE__ */ jsxs2(Box3, { children: [
|
|
4649
|
+
/* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
|
|
4650
|
+
isMulti && /* @__PURE__ */ jsx4(Text3, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
|
|
4651
|
+
/* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: item.label })
|
|
4652
|
+
] }, item.key || String(item.value));
|
|
4653
|
+
}),
|
|
4654
|
+
/* @__PURE__ */ jsx4(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text3, { color: "gray", children: isMulti ? "Space to toggle, Enter to confirm, Esc to cancel" : "Enter to select, Esc to cancel" }) })
|
|
4655
|
+
] });
|
|
4656
|
+
}
|
|
4657
|
+
var init_SimpleSelect = __esm({
|
|
4658
|
+
"src/mcp/ui/components/SimpleSelect.tsx"() {
|
|
4659
|
+
"use strict";
|
|
4660
|
+
}
|
|
4661
|
+
});
|
|
4662
|
+
|
|
4663
|
+
// src/mcp/ui/ProjectsView.tsx
|
|
4664
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
4665
|
+
import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
|
|
4666
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4667
|
+
function projectKey(p) {
|
|
4668
|
+
return p.sourcePath ?? p.path;
|
|
4669
|
+
}
|
|
4670
|
+
function formatProjectLabel(p) {
|
|
4671
|
+
const root = p.sourcePath ?? p.path;
|
|
4672
|
+
return `${p.name} (${p.source})${root ? ` - ${root}` : ""}`;
|
|
4673
|
+
}
|
|
4674
|
+
var ProjectsView;
|
|
4675
|
+
var init_ProjectsView = __esm({
|
|
4676
|
+
"src/mcp/ui/ProjectsView.tsx"() {
|
|
4677
|
+
"use strict";
|
|
4678
|
+
init_SimpleSelect();
|
|
4679
|
+
init_config();
|
|
4706
4680
|
init_ConfigContext();
|
|
4707
|
-
|
|
4708
|
-
|
|
4681
|
+
init_indexing_jobs();
|
|
4682
|
+
init_config_utils();
|
|
4709
4683
|
ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange }) => {
|
|
4710
4684
|
const { driftReports, checkAllDrift } = useConfig();
|
|
4711
4685
|
const [config, setConfig] = useState3(initialConfig);
|
|
4712
|
-
const [
|
|
4713
|
-
const [expanded, setExpanded] = useState3(() => /* @__PURE__ */ new Set());
|
|
4714
|
-
const [selectedIndex, setSelectedIndex] = useState3(0);
|
|
4715
|
-
const [taskCache, setTaskCache] = useState3({});
|
|
4716
|
-
const [errorLine, setErrorLine] = useState3(null);
|
|
4686
|
+
const [indexingStats, setIndexingStats] = useState3({});
|
|
4717
4687
|
const sortedProjects = useMemo3(() => {
|
|
4718
4688
|
return [...allProjects].sort((a, b) => {
|
|
4719
4689
|
const byName = a.name.localeCompare(b.name);
|
|
@@ -4721,113 +4691,70 @@ var init_ProjectsView = __esm({
|
|
|
4721
4691
|
return projectKey(a).localeCompare(projectKey(b));
|
|
4722
4692
|
});
|
|
4723
4693
|
}, [allProjects]);
|
|
4724
|
-
|
|
4725
|
-
const
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4694
|
+
useEffect3(() => {
|
|
4695
|
+
const updateStats = () => {
|
|
4696
|
+
const next = {};
|
|
4697
|
+
for (const p of allProjects) {
|
|
4698
|
+
let projConfig = findProjectConfig(config, { name: p.name, path: p.path });
|
|
4699
|
+
if (!projConfig && p.source === "global") {
|
|
4700
|
+
projConfig = config.projects.find((c) => c.name === p.name);
|
|
4701
|
+
}
|
|
4702
|
+
const enabled = projConfig?.semanticSearch?.enabled || p.semanticSearchEnabled || false;
|
|
4703
|
+
const prog = indexingJobs.getProgress(p.name);
|
|
4704
|
+
next[p.name] = { enabled, ...prog };
|
|
4705
|
+
}
|
|
4706
|
+
setIndexingStats(next);
|
|
4707
|
+
};
|
|
4708
|
+
updateStats();
|
|
4709
|
+
const interval = setInterval(updateStats, 2e3);
|
|
4710
|
+
return () => clearInterval(interval);
|
|
4711
|
+
}, [allProjects, config]);
|
|
4735
4712
|
useInput2((input, key) => {
|
|
4736
|
-
if (input === "t") {
|
|
4737
|
-
setErrorLine(null);
|
|
4738
|
-
setMode((prev) => prev === "expose" ? "tasks" : "expose");
|
|
4739
|
-
return;
|
|
4740
|
-
}
|
|
4741
4713
|
if (input === "u") {
|
|
4742
4714
|
checkAllDrift();
|
|
4743
4715
|
return;
|
|
4744
4716
|
}
|
|
4745
|
-
if (
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
defaults
|
|
4750
|
-
|
|
4751
|
-
includeNew: !config.defaults.includeNew
|
|
4752
|
-
}
|
|
4753
|
-
};
|
|
4754
|
-
saveMCPConfig(newConfig);
|
|
4755
|
-
setConfig(newConfig);
|
|
4756
|
-
onConfigChange?.();
|
|
4757
|
-
}
|
|
4758
|
-
return;
|
|
4759
|
-
}
|
|
4760
|
-
if (mode === "tasks") {
|
|
4761
|
-
if (input === "R") {
|
|
4762
|
-
setErrorLine(null);
|
|
4763
|
-
refreshAllTasks();
|
|
4764
|
-
return;
|
|
4765
|
-
}
|
|
4766
|
-
if (key.upArrow) {
|
|
4767
|
-
setSelectedIndex((prev) => prev > 0 ? prev - 1 : Math.max(0, flattenedRows.length - 1));
|
|
4768
|
-
return;
|
|
4769
|
-
}
|
|
4770
|
-
if (key.downArrow) {
|
|
4771
|
-
setSelectedIndex((prev) => prev < flattenedRows.length - 1 ? prev + 1 : 0);
|
|
4772
|
-
return;
|
|
4773
|
-
}
|
|
4774
|
-
if (key.return) {
|
|
4775
|
-
const row = flattenedRows[selectedIndex];
|
|
4776
|
-
if (row?.kind === "project") {
|
|
4777
|
-
const k = projectKey(row.project);
|
|
4778
|
-
const next = new Set(expanded);
|
|
4779
|
-
if (next.has(k)) {
|
|
4780
|
-
next.delete(k);
|
|
4781
|
-
} else {
|
|
4782
|
-
next.add(k);
|
|
4783
|
-
refreshTasksForProject(row.project);
|
|
4784
|
-
}
|
|
4785
|
-
setExpanded(next);
|
|
4717
|
+
if (input === "a") {
|
|
4718
|
+
const newConfig = {
|
|
4719
|
+
...config,
|
|
4720
|
+
defaults: {
|
|
4721
|
+
...config.defaults,
|
|
4722
|
+
includeNew: !config.defaults.includeNew
|
|
4786
4723
|
}
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
if (row?.kind === "task") {
|
|
4792
|
-
setErrorLine(null);
|
|
4793
|
-
const desired = nextStatus(row.task.status);
|
|
4794
|
-
const result = updateTaskStatus(row.project, row.task.task_slug, desired);
|
|
4795
|
-
if (!result.ok) {
|
|
4796
|
-
setErrorLine(`Failed to update status: ${result.error}`);
|
|
4797
|
-
return;
|
|
4798
|
-
}
|
|
4799
|
-
setTaskCache((prev) => {
|
|
4800
|
-
const k = projectKey(row.project);
|
|
4801
|
-
const tasks = prev[k] || [];
|
|
4802
|
-
const updated = tasks.map((t) => t.task_slug === row.task.task_slug ? result.meta : t);
|
|
4803
|
-
return { ...prev, [k]: updated };
|
|
4804
|
-
});
|
|
4805
|
-
}
|
|
4806
|
-
return;
|
|
4807
|
-
}
|
|
4724
|
+
};
|
|
4725
|
+
saveMCPConfig(newConfig);
|
|
4726
|
+
setConfig(newConfig);
|
|
4727
|
+
onConfigChange?.();
|
|
4808
4728
|
}
|
|
4809
4729
|
});
|
|
4810
|
-
useEffect3(() => {
|
|
4811
|
-
setSelectedIndex((prev) => {
|
|
4812
|
-
if (flattenedRows.length === 0) return 0;
|
|
4813
|
-
return Math.min(prev, flattenedRows.length - 1);
|
|
4814
|
-
});
|
|
4815
|
-
}, [mode, allProjects, expanded, taskCache]);
|
|
4816
4730
|
const projectItems = useMemo3(() => {
|
|
4817
|
-
return
|
|
4731
|
+
return sortedProjects.map((p) => {
|
|
4818
4732
|
const projectConfig = config.projects.find(
|
|
4819
4733
|
(c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
|
|
4820
4734
|
);
|
|
4821
4735
|
const isExposed = projectConfig ? projectConfig.expose : config.defaults.includeNew;
|
|
4822
4736
|
const drift = driftReports[p.path];
|
|
4737
|
+
const idx = indexingStats[p.name];
|
|
4738
|
+
let label = formatProjectLabel(p);
|
|
4739
|
+
if (idx?.state === "running") {
|
|
4740
|
+
label += ` [\u27F3 Indexing ${idx.itemsDone}/${idx.itemsTotal ?? "?"}]`;
|
|
4741
|
+
} else if (idx?.state === "failed") {
|
|
4742
|
+
label += ` [\u2715 Index Fail]`;
|
|
4743
|
+
} else if (idx?.enabled && idx?.state === "complete") {
|
|
4744
|
+
label += ` [\u2713 Indexed]`;
|
|
4745
|
+
}
|
|
4746
|
+
if (drift?.hasDrift) {
|
|
4747
|
+
label += ` \u26A0`;
|
|
4748
|
+
}
|
|
4823
4749
|
return {
|
|
4824
|
-
label
|
|
4750
|
+
label,
|
|
4825
4751
|
value: p.path,
|
|
4826
4752
|
key: p.path,
|
|
4827
|
-
exposed: isExposed
|
|
4753
|
+
exposed: isExposed,
|
|
4754
|
+
indexing: idx
|
|
4828
4755
|
};
|
|
4829
4756
|
});
|
|
4830
|
-
}, [
|
|
4757
|
+
}, [sortedProjects, config, driftReports, indexingStats]);
|
|
4831
4758
|
const initialSelected = useMemo3(() => {
|
|
4832
4759
|
return projectItems.filter((p) => p.exposed).map((p) => p.value);
|
|
4833
4760
|
}, [projectItems]);
|
|
@@ -4852,11 +4779,140 @@ var init_ProjectsView = __esm({
|
|
|
4852
4779
|
setConfig(newConfig);
|
|
4853
4780
|
onConfigChange?.();
|
|
4854
4781
|
};
|
|
4855
|
-
|
|
4782
|
+
return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
|
|
4783
|
+
/* @__PURE__ */ jsxs3(Box4, { justifyContent: "space-between", children: [
|
|
4784
|
+
/* @__PURE__ */ jsxs3(Box4, { children: [
|
|
4785
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "cyan", children: " Projects " }),
|
|
4786
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " \u2022 " }),
|
|
4787
|
+
/* @__PURE__ */ jsxs3(Text4, { color: config.defaults.includeNew ? "green" : "red", children: [
|
|
4788
|
+
"Auto-expose: ",
|
|
4789
|
+
config.defaults.includeNew ? "ON" : "OFF"
|
|
4790
|
+
] })
|
|
4791
|
+
] }),
|
|
4792
|
+
/* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Text4, { color: "dim", children: "a:Toggle Auto u:Drift Space:Select Enter:Save" }) })
|
|
4793
|
+
] }),
|
|
4794
|
+
/* @__PURE__ */ jsx5(Text4, { color: "dim", children: " Manage which projects are exposed to the MCP server. Indexing status shown in-line." }),
|
|
4795
|
+
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx5(
|
|
4796
|
+
SimpleSelect,
|
|
4797
|
+
{
|
|
4798
|
+
message: "",
|
|
4799
|
+
items: projectItems,
|
|
4800
|
+
isMulti: true,
|
|
4801
|
+
initialSelected,
|
|
4802
|
+
onSelect: () => {
|
|
4803
|
+
},
|
|
4804
|
+
onSubmit: handleSubmit,
|
|
4805
|
+
onCancel: () => {
|
|
4806
|
+
}
|
|
4807
|
+
},
|
|
4808
|
+
JSON.stringify(initialSelected) + config.defaults.includeNew + JSON.stringify(indexingStats)
|
|
4809
|
+
) }),
|
|
4810
|
+
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, borderStyle: "single", borderColor: "dim", paddingX: 1, children: /* @__PURE__ */ jsx5(Text4, { color: "dim", children: "Use 'rrce-workflow wizard' to manage project exposures and settings." }) })
|
|
4811
|
+
] });
|
|
4812
|
+
};
|
|
4813
|
+
}
|
|
4814
|
+
});
|
|
4815
|
+
|
|
4816
|
+
// src/mcp/ui/ui-helpers.ts
|
|
4817
|
+
var getStatusIcon, getStatusColor, getChecklistProgress, getCheckbox, getProgressBar, getFolderIcon;
|
|
4818
|
+
var init_ui_helpers = __esm({
|
|
4819
|
+
"src/mcp/ui/ui-helpers.ts"() {
|
|
4820
|
+
"use strict";
|
|
4821
|
+
getStatusIcon = (status) => {
|
|
4822
|
+
const icons = {
|
|
4823
|
+
pending: "\u23F3",
|
|
4824
|
+
in_progress: "\u{1F504}",
|
|
4825
|
+
blocked: "\u{1F6AB}",
|
|
4826
|
+
complete: "\u2705"
|
|
4827
|
+
};
|
|
4828
|
+
return icons[status] || "\u25CB";
|
|
4829
|
+
};
|
|
4830
|
+
getStatusColor = (status) => {
|
|
4831
|
+
const colors = {
|
|
4832
|
+
pending: "yellow",
|
|
4833
|
+
in_progress: "yellow",
|
|
4834
|
+
blocked: "red",
|
|
4835
|
+
complete: "green"
|
|
4836
|
+
};
|
|
4837
|
+
return colors[status] || "white";
|
|
4838
|
+
};
|
|
4839
|
+
getChecklistProgress = (checklist) => {
|
|
4840
|
+
if (!checklist || checklist.length === 0) {
|
|
4841
|
+
return { completed: 0, total: 0, percentage: 0 };
|
|
4842
|
+
}
|
|
4843
|
+
const completed = checklist.filter((item) => item.status === "done").length;
|
|
4844
|
+
return {
|
|
4845
|
+
completed,
|
|
4846
|
+
total: checklist.length,
|
|
4847
|
+
percentage: Math.round(completed / checklist.length * 100)
|
|
4848
|
+
};
|
|
4849
|
+
};
|
|
4850
|
+
getCheckbox = (status) => {
|
|
4851
|
+
return status === "done" ? "\u2611" : "\u2610";
|
|
4852
|
+
};
|
|
4853
|
+
getProgressBar = (percentage, length = 10) => {
|
|
4854
|
+
const filled = Math.floor(percentage / 100 * length);
|
|
4855
|
+
const empty = length - filled;
|
|
4856
|
+
return "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
4857
|
+
};
|
|
4858
|
+
getFolderIcon = (isOpen) => {
|
|
4859
|
+
return isOpen ? "\u{1F4C2}" : "\u{1F4C1}";
|
|
4860
|
+
};
|
|
4861
|
+
}
|
|
4862
|
+
});
|
|
4863
|
+
|
|
4864
|
+
// src/mcp/ui/TasksView.tsx
|
|
4865
|
+
import { useEffect as useEffect4, useMemo as useMemo4, useState as useState4 } from "react";
|
|
4866
|
+
import { Box as Box5, Text as Text5, useInput as useInput3 } from "ink";
|
|
4867
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4868
|
+
function nextStatus(current) {
|
|
4869
|
+
const idx = STATUS_CYCLE.indexOf(current || "");
|
|
4870
|
+
if (idx === -1) return STATUS_CYCLE[0];
|
|
4871
|
+
return STATUS_CYCLE[(idx + 1) % STATUS_CYCLE.length];
|
|
4872
|
+
}
|
|
4873
|
+
function projectKey2(p) {
|
|
4874
|
+
return p.sourcePath ?? p.path;
|
|
4875
|
+
}
|
|
4876
|
+
function formatProjectLabel2(p) {
|
|
4877
|
+
return `${p.name} (${p.source})`;
|
|
4878
|
+
}
|
|
4879
|
+
var STATUS_CYCLE, TasksView;
|
|
4880
|
+
var init_TasksView = __esm({
|
|
4881
|
+
"src/mcp/ui/TasksView.tsx"() {
|
|
4882
|
+
"use strict";
|
|
4883
|
+
init_tasks_fs();
|
|
4884
|
+
init_ConfigContext();
|
|
4885
|
+
init_ui_helpers();
|
|
4886
|
+
STATUS_CYCLE = ["pending", "in_progress", "blocked", "complete"];
|
|
4887
|
+
TasksView = ({ projects: allProjects }) => {
|
|
4888
|
+
const { driftReports } = useConfig();
|
|
4889
|
+
const [expanded, setExpanded] = useState4(() => /* @__PURE__ */ new Set());
|
|
4890
|
+
const [selectedIndex, setSelectedIndex] = useState4(0);
|
|
4891
|
+
const [taskCache, setTaskCache] = useState4({});
|
|
4892
|
+
const [errorLine, setErrorLine] = useState4(null);
|
|
4893
|
+
const sortedProjects = useMemo4(() => {
|
|
4894
|
+
return [...allProjects].sort((a, b) => {
|
|
4895
|
+
const byName = a.name.localeCompare(b.name);
|
|
4896
|
+
if (byName !== 0) return byName;
|
|
4897
|
+
return projectKey2(a).localeCompare(projectKey2(b));
|
|
4898
|
+
});
|
|
4899
|
+
}, [allProjects]);
|
|
4900
|
+
const refreshTasksForProject = (project) => {
|
|
4901
|
+
const res = listProjectTasks(project);
|
|
4902
|
+
setTaskCache((prev) => ({ ...prev, [projectKey2(project)]: res.tasks }));
|
|
4903
|
+
};
|
|
4904
|
+
const refreshAllTasks = () => {
|
|
4905
|
+
const next = {};
|
|
4906
|
+
for (const p of sortedProjects) {
|
|
4907
|
+
next[projectKey2(p)] = listProjectTasks(p).tasks;
|
|
4908
|
+
}
|
|
4909
|
+
setTaskCache(next);
|
|
4910
|
+
};
|
|
4911
|
+
const flattenedRows = useMemo4(() => {
|
|
4856
4912
|
const rows = [];
|
|
4857
4913
|
for (const p of sortedProjects) {
|
|
4858
4914
|
rows.push({ kind: "project", project: p });
|
|
4859
|
-
const k =
|
|
4915
|
+
const k = projectKey2(p);
|
|
4860
4916
|
if (!expanded.has(k)) continue;
|
|
4861
4917
|
const tasks = taskCache[k] || [];
|
|
4862
4918
|
for (const t of tasks) {
|
|
@@ -4868,133 +4924,154 @@ var init_ProjectsView = __esm({
|
|
|
4868
4924
|
}
|
|
4869
4925
|
return rows;
|
|
4870
4926
|
}, [sortedProjects, expanded, taskCache]);
|
|
4927
|
+
useInput3((input, key) => {
|
|
4928
|
+
if (input === "R") {
|
|
4929
|
+
setErrorLine(null);
|
|
4930
|
+
refreshAllTasks();
|
|
4931
|
+
return;
|
|
4932
|
+
}
|
|
4933
|
+
if (key.upArrow) {
|
|
4934
|
+
setSelectedIndex((prev) => prev > 0 ? prev - 1 : Math.max(0, flattenedRows.length - 1));
|
|
4935
|
+
return;
|
|
4936
|
+
}
|
|
4937
|
+
if (key.downArrow) {
|
|
4938
|
+
setSelectedIndex((prev) => prev < flattenedRows.length - 1 ? prev + 1 : 0);
|
|
4939
|
+
return;
|
|
4940
|
+
}
|
|
4941
|
+
if (key.return) {
|
|
4942
|
+
const row = flattenedRows[selectedIndex];
|
|
4943
|
+
if (row?.kind === "project") {
|
|
4944
|
+
const k = projectKey2(row.project);
|
|
4945
|
+
const next = new Set(expanded);
|
|
4946
|
+
if (next.has(k)) {
|
|
4947
|
+
next.delete(k);
|
|
4948
|
+
} else {
|
|
4949
|
+
next.add(k);
|
|
4950
|
+
refreshTasksForProject(row.project);
|
|
4951
|
+
}
|
|
4952
|
+
setExpanded(next);
|
|
4953
|
+
}
|
|
4954
|
+
return;
|
|
4955
|
+
}
|
|
4956
|
+
if (input === "s") {
|
|
4957
|
+
const row = flattenedRows[selectedIndex];
|
|
4958
|
+
if (row?.kind === "task") {
|
|
4959
|
+
setErrorLine(null);
|
|
4960
|
+
const desired = nextStatus(row.task.status);
|
|
4961
|
+
const result = updateTaskStatus(row.project, row.task.task_slug, desired);
|
|
4962
|
+
if (!result.ok) {
|
|
4963
|
+
setErrorLine(`Failed to update status: ${result.error}`);
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4966
|
+
setTaskCache((prev) => {
|
|
4967
|
+
const k = projectKey2(row.project);
|
|
4968
|
+
const tasks = prev[k] || [];
|
|
4969
|
+
const updated = tasks.map((t) => t.task_slug === row.task.task_slug ? result.meta : t);
|
|
4970
|
+
return { ...prev, [k]: updated };
|
|
4971
|
+
});
|
|
4972
|
+
}
|
|
4973
|
+
return;
|
|
4974
|
+
}
|
|
4975
|
+
});
|
|
4976
|
+
useEffect4(() => {
|
|
4977
|
+
setSelectedIndex((prev) => {
|
|
4978
|
+
if (flattenedRows.length === 0) return 0;
|
|
4979
|
+
return Math.min(prev, flattenedRows.length - 1);
|
|
4980
|
+
});
|
|
4981
|
+
}, [flattenedRows]);
|
|
4871
4982
|
const selectedRow = flattenedRows[selectedIndex];
|
|
4872
4983
|
const selectedTask = selectedRow?.kind === "task" && selectedRow.task.task_slug !== "__none__" ? selectedRow.task : null;
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
/* @__PURE__ */
|
|
4876
|
-
/* @__PURE__ */
|
|
4877
|
-
/* @__PURE__ */
|
|
4878
|
-
|
|
4879
|
-
/* @__PURE__ */ jsx5(Text4, { color: config.defaults.includeNew ? "green" : "red", children: config.defaults.includeNew ? "ON" : "OFF" }),
|
|
4880
|
-
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " (Press 'a' to toggle)" })
|
|
4881
|
-
] })
|
|
4882
|
-
] }),
|
|
4883
|
-
/* @__PURE__ */ jsx5(Text4, { color: "dim", children: " Space toggles, Enter saves. Press 't' to switch to Tasks Mode." }),
|
|
4884
|
-
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx5(
|
|
4885
|
-
SimpleSelect,
|
|
4886
|
-
{
|
|
4887
|
-
message: "",
|
|
4888
|
-
items: projectItems,
|
|
4889
|
-
isMulti: true,
|
|
4890
|
-
initialSelected,
|
|
4891
|
-
onSelect: () => {
|
|
4892
|
-
},
|
|
4893
|
-
onSubmit: handleSubmit,
|
|
4894
|
-
onCancel: () => {
|
|
4895
|
-
}
|
|
4896
|
-
},
|
|
4897
|
-
JSON.stringify(initialSelected) + config.defaults.includeNew
|
|
4898
|
-
) })
|
|
4899
|
-
] });
|
|
4900
|
-
}
|
|
4901
|
-
return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
|
|
4902
|
-
/* @__PURE__ */ jsxs3(Box4, { justifyContent: "space-between", children: [
|
|
4903
|
-
/* @__PURE__ */ jsxs3(Box4, { children: [
|
|
4904
|
-
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "cyan", children: "\u2699 Tasks Mode" }),
|
|
4905
|
-
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " \u2022 " }),
|
|
4906
|
-
/* @__PURE__ */ jsxs3(Text4, { children: [
|
|
4984
|
+
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
|
|
4985
|
+
/* @__PURE__ */ jsxs4(Box5, { justifyContent: "space-between", children: [
|
|
4986
|
+
/* @__PURE__ */ jsxs4(Box5, { children: [
|
|
4987
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u2699 Tasks" }),
|
|
4988
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \u2022 " }),
|
|
4989
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
4907
4990
|
sortedProjects.length,
|
|
4908
4991
|
" projects"
|
|
4909
4992
|
] }),
|
|
4910
|
-
/* @__PURE__ */
|
|
4911
|
-
/* @__PURE__ */
|
|
4993
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \u2022 " }),
|
|
4994
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
4912
4995
|
Object.values(taskCache).flat().length,
|
|
4913
4996
|
" tasks"
|
|
4914
4997
|
] })
|
|
4915
4998
|
] }),
|
|
4916
|
-
/* @__PURE__ */
|
|
4999
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2191/\u2193:Nav Enter:Expand s:Status R:Refresh" })
|
|
4917
5000
|
] }),
|
|
4918
|
-
errorLine && /* @__PURE__ */
|
|
4919
|
-
/* @__PURE__ */
|
|
4920
|
-
/* @__PURE__ */
|
|
4921
|
-
flattenedRows.length === 0 ? /* @__PURE__ */
|
|
5001
|
+
errorLine && /* @__PURE__ */ jsx6(Box5, { marginTop: 0, children: /* @__PURE__ */ jsx6(Text5, { color: "red", children: errorLine }) }),
|
|
5002
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, flexDirection: "row", flexGrow: 1, children: [
|
|
5003
|
+
/* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", width: "55%", children: [
|
|
5004
|
+
flattenedRows.length === 0 ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "No projects detected." }) : flattenedRows.map((row, idx) => {
|
|
4922
5005
|
const isSel = idx === selectedIndex;
|
|
4923
5006
|
if (row.kind === "project") {
|
|
4924
|
-
const k =
|
|
5007
|
+
const k = projectKey2(row.project);
|
|
4925
5008
|
const isOpen = expanded.has(k);
|
|
4926
5009
|
const count = (taskCache[k] || []).length;
|
|
4927
5010
|
const drift = driftReports[row.project.path];
|
|
4928
|
-
return /* @__PURE__ */
|
|
4929
|
-
/* @__PURE__ */
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
formatProjectLabel(row.project, drift)
|
|
4935
|
-
] }),
|
|
4936
|
-
drift?.hasDrift && /* @__PURE__ */ jsx5(Text4, { color: "magenta", children: " \u26A0" }),
|
|
4937
|
-
/* @__PURE__ */ jsxs3(Text4, { color: "dim", children: [
|
|
4938
|
-
" ",
|
|
4939
|
-
count > 0 ? `(${count})` : ""
|
|
4940
|
-
] })
|
|
5011
|
+
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box5, { children: [
|
|
5012
|
+
/* @__PURE__ */ jsx6(Text5, { color: isSel ? "cyan" : "white", children: isSel ? "> " : " " }),
|
|
5013
|
+
/* @__PURE__ */ jsxs4(Text5, { color: isSel ? "cyan" : "white", children: [
|
|
5014
|
+
getFolderIcon(isOpen),
|
|
5015
|
+
" ",
|
|
5016
|
+
formatProjectLabel2(row.project)
|
|
4941
5017
|
] }),
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
"
|
|
4945
|
-
|
|
4946
|
-
|
|
5018
|
+
drift?.hasDrift && /* @__PURE__ */ jsx6(Text5, { color: "magenta", children: " \u26A0" }),
|
|
5019
|
+
/* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
|
|
5020
|
+
" ",
|
|
5021
|
+
count > 0 ? `(${count})` : ""
|
|
5022
|
+
] })
|
|
5023
|
+
] }) }, `p:${k}`);
|
|
4947
5024
|
}
|
|
4948
5025
|
const taskLabel = row.task.title || row.task.task_slug;
|
|
4949
5026
|
const status = row.task.status || "";
|
|
4950
|
-
return /* @__PURE__ */
|
|
4951
|
-
/* @__PURE__ */
|
|
4952
|
-
/* @__PURE__ */
|
|
4953
|
-
/* @__PURE__ */
|
|
4954
|
-
row.task.task_slug !== "__none__" && /* @__PURE__ */
|
|
4955
|
-
] }, `t:${
|
|
5027
|
+
return /* @__PURE__ */ jsxs4(Box5, { children: [
|
|
5028
|
+
/* @__PURE__ */ jsx6(Text5, { color: isSel ? "cyan" : "white", children: isSel ? "> " : " " }),
|
|
5029
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: " - " }),
|
|
5030
|
+
/* @__PURE__ */ jsx6(Text5, { color: isSel ? "cyan" : "white", children: taskLabel }),
|
|
5031
|
+
row.task.task_slug !== "__none__" && /* @__PURE__ */ jsx6(Text5, { backgroundColor: getStatusColor(status), color: "black", children: ` ${getStatusIcon(status)} ${status.toUpperCase().replace("_", " ")} ` })
|
|
5032
|
+
] }, `t:${projectKey2(row.project)}:${row.task.task_slug}`);
|
|
4956
5033
|
}),
|
|
4957
|
-
/* @__PURE__ */
|
|
5034
|
+
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { color: "gray", children: "\u25B2/\u25BC navigate \u2022 Enter expand/collapse \u2022 s cycle status \u2022 R refresh" }) })
|
|
4958
5035
|
] }),
|
|
4959
|
-
/* @__PURE__ */
|
|
4960
|
-
/* @__PURE__ */
|
|
4961
|
-
/* @__PURE__ */
|
|
4962
|
-
/* @__PURE__ */
|
|
4963
|
-
] }) : /* @__PURE__ */
|
|
4964
|
-
/* @__PURE__ */
|
|
4965
|
-
selectedTask.summary && /* @__PURE__ */
|
|
4966
|
-
/* @__PURE__ */
|
|
4967
|
-
/* @__PURE__ */
|
|
4968
|
-
/* @__PURE__ */
|
|
4969
|
-
/* @__PURE__ */
|
|
4970
|
-
/* @__PURE__ */
|
|
5036
|
+
/* @__PURE__ */ jsx6(Box5, { flexDirection: "column", width: "45%", paddingLeft: 2, children: !selectedTask ? /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", justifyContent: "center", alignItems: "center", gap: 1, children: [
|
|
5037
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "dim", children: "\u2500 No Task Selected \u2500" }),
|
|
5038
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Use \u2191/\u2193 to navigate, Enter to expand projects" }),
|
|
5039
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Press 's' to cycle task status" })
|
|
5040
|
+
] }) : /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
5041
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: selectedTask.title || selectedTask.task_slug }),
|
|
5042
|
+
selectedTask.summary && /* @__PURE__ */ jsx6(Text5, { children: selectedTask.summary }),
|
|
5043
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, borderStyle: "single", borderColor: "dim", padding: 1, flexDirection: "column", children: [
|
|
5044
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u{1F4CB} Status" }),
|
|
5045
|
+
/* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 0, children: [
|
|
5046
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5047
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Status:" }),
|
|
4971
5048
|
" ",
|
|
4972
|
-
/* @__PURE__ */
|
|
5049
|
+
/* @__PURE__ */ jsx6(Text5, { children: selectedTask.status || "unknown" })
|
|
4973
5050
|
] }),
|
|
4974
|
-
/* @__PURE__ */
|
|
4975
|
-
/* @__PURE__ */
|
|
5051
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5052
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Updated:" }),
|
|
4976
5053
|
" ",
|
|
4977
|
-
/* @__PURE__ */
|
|
5054
|
+
/* @__PURE__ */ jsx6(Text5, { children: selectedTask.updated_at || "\u2014" })
|
|
4978
5055
|
] }),
|
|
4979
|
-
/* @__PURE__ */
|
|
4980
|
-
/* @__PURE__ */
|
|
5056
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5057
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Tags:" }),
|
|
4981
5058
|
" ",
|
|
4982
5059
|
" ",
|
|
4983
5060
|
(() => {
|
|
4984
5061
|
const tags = selectedTask.tags || [];
|
|
4985
|
-
return tags.length > 0 ? tags.map((tag, i) => /* @__PURE__ */
|
|
4986
|
-
/* @__PURE__ */
|
|
4987
|
-
i < tags.length - 1 && /* @__PURE__ */
|
|
4988
|
-
] }, tag)) : /* @__PURE__ */
|
|
5062
|
+
return tags.length > 0 ? tags.map((tag, i) => /* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5063
|
+
/* @__PURE__ */ jsx6(Text5, { color: "cyan", children: tag }),
|
|
5064
|
+
i < tags.length - 1 && /* @__PURE__ */ jsx6(Text5, { color: "dim", children: ", " })
|
|
5065
|
+
] }, tag)) : /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" });
|
|
4989
5066
|
})()
|
|
4990
5067
|
] })
|
|
4991
5068
|
] })
|
|
4992
5069
|
] }),
|
|
4993
|
-
/* @__PURE__ */
|
|
4994
|
-
/* @__PURE__ */
|
|
4995
|
-
selectedTask.checklist && selectedTask.checklist.length > 0 && /* @__PURE__ */
|
|
4996
|
-
/* @__PURE__ */
|
|
4997
|
-
/* @__PURE__ */
|
|
5070
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, borderStyle: "single", borderColor: "dim", padding: 1, flexDirection: "column", children: [
|
|
5071
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u{1F4CB} Checklist" }),
|
|
5072
|
+
selectedTask.checklist && selectedTask.checklist.length > 0 && /* @__PURE__ */ jsx6(Box5, { marginTop: 0, flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box5, { children: [
|
|
5073
|
+
/* @__PURE__ */ jsx6(Text5, { backgroundColor: "white", children: getProgressBar(getChecklistProgress(selectedTask.checklist).percentage) }),
|
|
5074
|
+
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
4998
5075
|
" ",
|
|
4999
5076
|
" ",
|
|
5000
5077
|
getChecklistProgress(selectedTask.checklist).completed,
|
|
@@ -5005,31 +5082,31 @@ var init_ProjectsView = __esm({
|
|
|
5005
5082
|
"%)"
|
|
5006
5083
|
] })
|
|
5007
5084
|
] }) }),
|
|
5008
|
-
(selectedTask.checklist || []).length === 0 ? /* @__PURE__ */
|
|
5009
|
-
/* @__PURE__ */
|
|
5085
|
+
(selectedTask.checklist || []).length === 0 ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : (selectedTask.checklist || []).slice(0, 12).map((c, i) => /* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5086
|
+
/* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
|
|
5010
5087
|
getCheckbox(c.status || "pending"),
|
|
5011
5088
|
" "
|
|
5012
5089
|
] }),
|
|
5013
5090
|
c.label || c.id || "item"
|
|
5014
5091
|
] }, c.id || i))
|
|
5015
5092
|
] }),
|
|
5016
|
-
/* @__PURE__ */
|
|
5017
|
-
/* @__PURE__ */
|
|
5018
|
-
!selectedTask.agents ? /* @__PURE__ */
|
|
5019
|
-
/* @__PURE__ */
|
|
5093
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, borderStyle: "single", borderColor: "dim", padding: 1, flexDirection: "column", children: [
|
|
5094
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u{1F916} Agents" }),
|
|
5095
|
+
!selectedTask.agents ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : Object.entries(selectedTask.agents).map(([agent, info]) => /* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5096
|
+
/* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
|
|
5020
5097
|
"- ",
|
|
5021
5098
|
agent,
|
|
5022
5099
|
": "
|
|
5023
5100
|
] }),
|
|
5024
|
-
info?.status === "complete" && /* @__PURE__ */
|
|
5025
|
-
info?.status === "in_progress" && /* @__PURE__ */
|
|
5026
|
-
info?.status === "pending" && /* @__PURE__ */
|
|
5027
|
-
info?.blocked && /* @__PURE__ */
|
|
5028
|
-
/* @__PURE__ */
|
|
5101
|
+
info?.status === "complete" && /* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u2713" }),
|
|
5102
|
+
info?.status === "in_progress" && /* @__PURE__ */ jsx6(Text5, { color: "yellow", children: "\u27F3" }),
|
|
5103
|
+
info?.status === "pending" && /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u25CB" }),
|
|
5104
|
+
info?.blocked && /* @__PURE__ */ jsx6(Text5, { color: "red", children: "\u2715" }),
|
|
5105
|
+
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
5029
5106
|
" ",
|
|
5030
5107
|
info?.status || "\u2014"
|
|
5031
5108
|
] }),
|
|
5032
|
-
info?.artifact && /* @__PURE__ */
|
|
5109
|
+
info?.artifact && /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
5033
5110
|
"(",
|
|
5034
5111
|
info.artifact,
|
|
5035
5112
|
")"
|
|
@@ -5043,126 +5120,10 @@ var init_ProjectsView = __esm({
|
|
|
5043
5120
|
}
|
|
5044
5121
|
});
|
|
5045
5122
|
|
|
5046
|
-
// src/mcp/ui/
|
|
5047
|
-
import { useState as useState4 } from "react";
|
|
5048
|
-
import { Box as Box5, Text as Text5 } from "ink";
|
|
5049
|
-
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
5050
|
-
var InstallWizard;
|
|
5051
|
-
var init_InstallWizard = __esm({
|
|
5052
|
-
"src/mcp/ui/components/InstallWizard.tsx"() {
|
|
5053
|
-
"use strict";
|
|
5054
|
-
init_SimpleSelect();
|
|
5055
|
-
init_install();
|
|
5056
|
-
InstallWizard = ({ workspacePath, onComplete, onCancel }) => {
|
|
5057
|
-
const [status, setStatus] = useState4(checkInstallStatus(workspacePath));
|
|
5058
|
-
const [message, setMessage] = useState4("");
|
|
5059
|
-
const options = [
|
|
5060
|
-
{
|
|
5061
|
-
value: "opencode",
|
|
5062
|
-
label: "OpenCode",
|
|
5063
|
-
hint: status.opencode ? "INSTALLED" : "Not installed"
|
|
5064
|
-
},
|
|
5065
|
-
{
|
|
5066
|
-
value: "antigravity",
|
|
5067
|
-
label: "Antigravity IDE",
|
|
5068
|
-
hint: status.antigravity ? "INSTALLED" : "Not installed"
|
|
5069
|
-
},
|
|
5070
|
-
{
|
|
5071
|
-
value: "vscode-global",
|
|
5072
|
-
label: "VSCode (Global Settings)",
|
|
5073
|
-
hint: status.vscodeGlobal ? "INSTALLED" : "Not installed"
|
|
5074
|
-
},
|
|
5075
|
-
{
|
|
5076
|
-
value: "vscode-workspace",
|
|
5077
|
-
label: "VSCode (Workspace Config)",
|
|
5078
|
-
hint: status.vscodeWorkspace ? "INSTALLED" : "Not installed"
|
|
5079
|
-
},
|
|
5080
|
-
{
|
|
5081
|
-
value: "claude",
|
|
5082
|
-
label: "Claude Desktop",
|
|
5083
|
-
hint: status.claude ? "INSTALLED" : "Not installed"
|
|
5084
|
-
}
|
|
5085
|
-
];
|
|
5086
|
-
const initialSelected = [
|
|
5087
|
-
...status.opencode ? ["opencode"] : [],
|
|
5088
|
-
...status.antigravity ? ["antigravity"] : [],
|
|
5089
|
-
...status.vscodeGlobal ? ["vscode-global"] : [],
|
|
5090
|
-
...status.vscodeWorkspace ? ["vscode-workspace"] : [],
|
|
5091
|
-
...status.claude ? ["claude"] : []
|
|
5092
|
-
];
|
|
5093
|
-
const handleSubmit = (selectedIds) => {
|
|
5094
|
-
const targets = selectedIds;
|
|
5095
|
-
let results = [];
|
|
5096
|
-
targets.forEach((target) => {
|
|
5097
|
-
const success = installToConfig(target, workspacePath);
|
|
5098
|
-
const label = getTargetLabel(target);
|
|
5099
|
-
results.push(`${label}: ${success ? "Success" : "Failed"}`);
|
|
5100
|
-
});
|
|
5101
|
-
setStatus(checkInstallStatus(workspacePath));
|
|
5102
|
-
setMessage(`Installation updated: ${results.join(", ")}`);
|
|
5103
|
-
setTimeout(() => {
|
|
5104
|
-
setMessage("");
|
|
5105
|
-
onComplete();
|
|
5106
|
-
}, 2e3);
|
|
5107
|
-
};
|
|
5108
|
-
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
5109
|
-
message && /* @__PURE__ */ jsx6(Text5, { color: "green", children: message }),
|
|
5110
|
-
/* @__PURE__ */ jsx6(
|
|
5111
|
-
SimpleSelect,
|
|
5112
|
-
{
|
|
5113
|
-
message: "Select integrations to install:",
|
|
5114
|
-
items: options.map((o) => ({
|
|
5115
|
-
value: o.value,
|
|
5116
|
-
label: o.label + (o.hint === "INSTALLED" ? " (Installed)" : ""),
|
|
5117
|
-
key: o.value
|
|
5118
|
-
})),
|
|
5119
|
-
isMulti: true,
|
|
5120
|
-
initialSelected,
|
|
5121
|
-
onSelect: () => {
|
|
5122
|
-
},
|
|
5123
|
-
onSubmit: handleSubmit,
|
|
5124
|
-
onCancel
|
|
5125
|
-
}
|
|
5126
|
-
)
|
|
5127
|
-
] });
|
|
5128
|
-
};
|
|
5129
|
-
}
|
|
5130
|
-
});
|
|
5131
|
-
|
|
5132
|
-
// src/mcp/ui/InstallView.tsx
|
|
5123
|
+
// src/mcp/ui/LogViewer.tsx
|
|
5133
5124
|
import "react";
|
|
5134
5125
|
import { Box as Box6, Text as Text6 } from "ink";
|
|
5135
5126
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
5136
|
-
var InstallView;
|
|
5137
|
-
var init_InstallView = __esm({
|
|
5138
|
-
"src/mcp/ui/InstallView.tsx"() {
|
|
5139
|
-
"use strict";
|
|
5140
|
-
init_InstallWizard();
|
|
5141
|
-
init_paths();
|
|
5142
|
-
InstallView = () => {
|
|
5143
|
-
const workspacePath = detectWorkspaceRoot();
|
|
5144
|
-
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "magenta", flexGrow: 1, children: [
|
|
5145
|
-
/* @__PURE__ */ jsx7(Text6, { bold: true, color: "magenta", children: " Installation & Configuration " }),
|
|
5146
|
-
/* @__PURE__ */ jsx7(Text6, { color: "dim", children: " Configure IDE integrations for OpenCode, VSCode, Claude, and Antigravity." }),
|
|
5147
|
-
/* @__PURE__ */ jsx7(Box6, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx7(
|
|
5148
|
-
InstallWizard,
|
|
5149
|
-
{
|
|
5150
|
-
workspacePath,
|
|
5151
|
-
onComplete: () => {
|
|
5152
|
-
},
|
|
5153
|
-
onCancel: () => {
|
|
5154
|
-
}
|
|
5155
|
-
}
|
|
5156
|
-
) })
|
|
5157
|
-
] });
|
|
5158
|
-
};
|
|
5159
|
-
}
|
|
5160
|
-
});
|
|
5161
|
-
|
|
5162
|
-
// src/mcp/ui/LogViewer.tsx
|
|
5163
|
-
import "react";
|
|
5164
|
-
import { Box as Box7, Text as Text7 } from "ink";
|
|
5165
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5166
5127
|
var LogViewer;
|
|
5167
5128
|
var init_LogViewer = __esm({
|
|
5168
5129
|
"src/mcp/ui/LogViewer.tsx"() {
|
|
@@ -5172,16 +5133,16 @@ var init_LogViewer = __esm({
|
|
|
5172
5133
|
const emptyLines = Math.max(0, height - visibleLogs.length);
|
|
5173
5134
|
const padding = Array(emptyLines).fill("");
|
|
5174
5135
|
const formatLog = (log) => {
|
|
5175
|
-
if (log.includes("[RAG]")) return /* @__PURE__ */
|
|
5176
|
-
if (log.includes("[ERROR]")) return /* @__PURE__ */
|
|
5177
|
-
if (log.includes("[WARN]")) return /* @__PURE__ */
|
|
5178
|
-
if (log.includes("[INFO]")) return /* @__PURE__ */
|
|
5179
|
-
if (log.includes("Success")) return /* @__PURE__ */
|
|
5180
|
-
return /* @__PURE__ */
|
|
5136
|
+
if (log.includes("[RAG]")) return /* @__PURE__ */ jsx7(Text6, { color: "cyan", children: log });
|
|
5137
|
+
if (log.includes("[ERROR]")) return /* @__PURE__ */ jsx7(Text6, { color: "red", children: log });
|
|
5138
|
+
if (log.includes("[WARN]")) return /* @__PURE__ */ jsx7(Text6, { color: "yellow", children: log });
|
|
5139
|
+
if (log.includes("[INFO]")) return /* @__PURE__ */ jsx7(Text6, { color: "green", children: log });
|
|
5140
|
+
if (log.includes("Success")) return /* @__PURE__ */ jsx7(Text6, { color: "green", children: log });
|
|
5141
|
+
return /* @__PURE__ */ jsx7(Text6, { children: log });
|
|
5181
5142
|
};
|
|
5182
|
-
return /* @__PURE__ */
|
|
5183
|
-
padding.map((_, i) => /* @__PURE__ */
|
|
5184
|
-
visibleLogs.map((log, i) => /* @__PURE__ */
|
|
5143
|
+
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "dim", paddingX: 1, height: height + 2, flexGrow: 1, children: [
|
|
5144
|
+
padding.map((_, i) => /* @__PURE__ */ jsx7(Text6, { children: " " }, `empty-${i}`)),
|
|
5145
|
+
visibleLogs.map((log, i) => /* @__PURE__ */ jsx7(Box6, { children: formatLog(log) }, `log-${i}`))
|
|
5185
5146
|
] });
|
|
5186
5147
|
};
|
|
5187
5148
|
}
|
|
@@ -5189,28 +5150,28 @@ var init_LogViewer = __esm({
|
|
|
5189
5150
|
|
|
5190
5151
|
// src/mcp/ui/StatusBoard.tsx
|
|
5191
5152
|
import "react";
|
|
5192
|
-
import { Box as
|
|
5193
|
-
import { jsx as
|
|
5153
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
5154
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5194
5155
|
var StatusBoard;
|
|
5195
5156
|
var init_StatusBoard = __esm({
|
|
5196
5157
|
"src/mcp/ui/StatusBoard.tsx"() {
|
|
5197
5158
|
"use strict";
|
|
5198
5159
|
StatusBoard = ({ exposedLabel, port, pid, running, hasDrift }) => {
|
|
5199
|
-
return /* @__PURE__ */
|
|
5200
|
-
running ? /* @__PURE__ */
|
|
5160
|
+
return /* @__PURE__ */ jsx8(Box7, { borderStyle: "single", borderColor: "cyan", paddingX: 1, flexGrow: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
|
|
5161
|
+
running ? /* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CF RUNNING" }) : /* @__PURE__ */ jsx8(Text7, { color: "red", children: "\u25CF STOPPED" }),
|
|
5201
5162
|
" ",
|
|
5202
5163
|
"\u2502",
|
|
5203
5164
|
" \u{1F4CB} ",
|
|
5204
|
-
/* @__PURE__ */
|
|
5165
|
+
/* @__PURE__ */ jsx8(Text7, { color: "yellow", children: exposedLabel }),
|
|
5205
5166
|
" ",
|
|
5206
5167
|
"\u2502",
|
|
5207
5168
|
" Port: ",
|
|
5208
|
-
/* @__PURE__ */
|
|
5169
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: port }),
|
|
5209
5170
|
" ",
|
|
5210
5171
|
"\u2502",
|
|
5211
5172
|
" PID: ",
|
|
5212
|
-
/* @__PURE__ */
|
|
5213
|
-
hasDrift && /* @__PURE__ */
|
|
5173
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: pid }),
|
|
5174
|
+
hasDrift && /* @__PURE__ */ jsxs6(Text7, { color: "magenta", bold: true, children: [
|
|
5214
5175
|
" ",
|
|
5215
5176
|
"\u2502",
|
|
5216
5177
|
" \u2B06 UPDATE AVAILABLE"
|
|
@@ -5220,121 +5181,16 @@ var init_StatusBoard = __esm({
|
|
|
5220
5181
|
}
|
|
5221
5182
|
});
|
|
5222
5183
|
|
|
5223
|
-
// src/mcp/ui/IndexingStatus.tsx
|
|
5224
|
-
import { useState as useState5, useEffect as useEffect5 } from "react";
|
|
5225
|
-
import { Box as Box9, Text as Text9 } from "ink";
|
|
5226
|
-
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5227
|
-
var IndexingStatus;
|
|
5228
|
-
var init_IndexingStatus = __esm({
|
|
5229
|
-
"src/mcp/ui/IndexingStatus.tsx"() {
|
|
5230
|
-
"use strict";
|
|
5231
|
-
init_indexing_jobs();
|
|
5232
|
-
init_rag();
|
|
5233
|
-
init_resources();
|
|
5234
|
-
init_config_utils();
|
|
5235
|
-
IndexingStatus = ({ projects, config }) => {
|
|
5236
|
-
const [stats, setStats] = useState5([]);
|
|
5237
|
-
const [loading, setLoading] = useState5(true);
|
|
5238
|
-
useEffect5(() => {
|
|
5239
|
-
const fetchStats = async () => {
|
|
5240
|
-
const newStats = [];
|
|
5241
|
-
for (const project of projects) {
|
|
5242
|
-
let projConfig = findProjectConfig(config, { name: project.name, path: project.path });
|
|
5243
|
-
if (!projConfig && project.source === "global") {
|
|
5244
|
-
projConfig = config.projects.find((p) => p.name === project.name);
|
|
5245
|
-
}
|
|
5246
|
-
const enabled = projConfig?.semanticSearch?.enabled || project.semanticSearchEnabled || false;
|
|
5247
|
-
if (!enabled) {
|
|
5248
|
-
const prog = indexingJobs.getProgress(project.name);
|
|
5249
|
-
newStats.push({
|
|
5250
|
-
projectName: project.name,
|
|
5251
|
-
enabled: false,
|
|
5252
|
-
state: prog.state,
|
|
5253
|
-
itemsDone: prog.itemsDone,
|
|
5254
|
-
itemsTotal: prog.itemsTotal,
|
|
5255
|
-
currentItem: prog.currentItem,
|
|
5256
|
-
totalFiles: 0,
|
|
5257
|
-
totalChunks: 0
|
|
5258
|
-
});
|
|
5259
|
-
continue;
|
|
5260
|
-
}
|
|
5261
|
-
try {
|
|
5262
|
-
const indexPath = getRAGIndexPath(project);
|
|
5263
|
-
const rag = new RAGService(indexPath, "dummy");
|
|
5264
|
-
const s = rag.getStats();
|
|
5265
|
-
const prog = indexingJobs.getProgress(project.name);
|
|
5266
|
-
newStats.push({
|
|
5267
|
-
projectName: project.name,
|
|
5268
|
-
enabled: true,
|
|
5269
|
-
state: prog.state,
|
|
5270
|
-
itemsDone: prog.itemsDone,
|
|
5271
|
-
itemsTotal: prog.itemsTotal,
|
|
5272
|
-
currentItem: prog.currentItem,
|
|
5273
|
-
totalFiles: s.totalFiles,
|
|
5274
|
-
totalChunks: s.totalChunks,
|
|
5275
|
-
lastFullIndex: s.lastFullIndex
|
|
5276
|
-
});
|
|
5277
|
-
} catch (e) {
|
|
5278
|
-
const prog = indexingJobs.getProgress(project.name);
|
|
5279
|
-
newStats.push({
|
|
5280
|
-
projectName: project.name,
|
|
5281
|
-
enabled: true,
|
|
5282
|
-
state: prog.state,
|
|
5283
|
-
itemsDone: prog.itemsDone,
|
|
5284
|
-
itemsTotal: prog.itemsTotal,
|
|
5285
|
-
currentItem: prog.currentItem,
|
|
5286
|
-
totalFiles: 0,
|
|
5287
|
-
totalChunks: 0,
|
|
5288
|
-
error: String(e)
|
|
5289
|
-
});
|
|
5290
|
-
}
|
|
5291
|
-
}
|
|
5292
|
-
setStats(newStats);
|
|
5293
|
-
setLoading(false);
|
|
5294
|
-
};
|
|
5295
|
-
fetchStats();
|
|
5296
|
-
const interval = setInterval(fetchStats, 5e3);
|
|
5297
|
-
return () => clearInterval(interval);
|
|
5298
|
-
}, [projects, config]);
|
|
5299
|
-
if (loading && stats.length === 0) {
|
|
5300
|
-
return /* @__PURE__ */ jsx10(Text9, { children: "Loading indexing status..." });
|
|
5301
|
-
}
|
|
5302
|
-
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "blue", flexGrow: 1, children: [
|
|
5303
|
-
/* @__PURE__ */ jsx10(Text9, { bold: true, color: "blue", children: " RAG Indexing Status " }),
|
|
5304
|
-
/* @__PURE__ */ jsxs8(Box9, { marginTop: 1, flexDirection: "column", children: [
|
|
5305
|
-
/* @__PURE__ */ jsxs8(Box9, { children: [
|
|
5306
|
-
/* @__PURE__ */ jsx10(Box9, { width: 25, children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "Project" }) }),
|
|
5307
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "Status" }) }),
|
|
5308
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "State" }) }),
|
|
5309
|
-
/* @__PURE__ */ jsx10(Box9, { width: 18, children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "Progress" }) }),
|
|
5310
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "Indexed Files" }) }),
|
|
5311
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "Total Chunks" }) }),
|
|
5312
|
-
/* @__PURE__ */ jsx10(Box9, { children: /* @__PURE__ */ jsx10(Text9, { underline: true, children: "Last Index" }) })
|
|
5313
|
-
] }),
|
|
5314
|
-
stats.length === 0 ? /* @__PURE__ */ jsx10(Text9, { color: "dim", children: "No exposed projects found." }) : stats.map((s) => /* @__PURE__ */ jsxs8(Box9, { marginTop: 0, children: [
|
|
5315
|
-
/* @__PURE__ */ jsx10(Box9, { width: 25, children: /* @__PURE__ */ jsx10(Text9, { color: "white", children: s.projectName }) }),
|
|
5316
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { color: s.state === "running" ? "yellow" : s.state === "failed" ? "red" : s.enabled ? "green" : "dim", children: s.enabled ? s.state : "disabled" }) }),
|
|
5317
|
-
/* @__PURE__ */ jsx10(Box9, { width: 18, children: /* @__PURE__ */ jsx10(Text9, { children: s.state === "running" ? `${s.itemsDone}/${s.itemsTotal ?? "?"}` : "-" }) }),
|
|
5318
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { children: s.enabled ? s.totalFiles : "-" }) }),
|
|
5319
|
-
/* @__PURE__ */ jsx10(Box9, { width: 15, children: /* @__PURE__ */ jsx10(Text9, { children: s.enabled ? s.totalChunks : "-" }) }),
|
|
5320
|
-
/* @__PURE__ */ jsx10(Box9, { children: /* @__PURE__ */ jsx10(Text9, { children: s.lastFullIndex ? new Date(s.lastFullIndex).toLocaleTimeString() : "-" }) })
|
|
5321
|
-
] }, s.projectName))
|
|
5322
|
-
] })
|
|
5323
|
-
] });
|
|
5324
|
-
};
|
|
5325
|
-
}
|
|
5326
|
-
});
|
|
5327
|
-
|
|
5328
5184
|
// src/mcp/ui/components/TabBar.tsx
|
|
5329
5185
|
import "react";
|
|
5330
|
-
import { Box as
|
|
5331
|
-
import { jsx as
|
|
5186
|
+
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
5187
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5332
5188
|
var TabBar;
|
|
5333
5189
|
var init_TabBar = __esm({
|
|
5334
5190
|
"src/mcp/ui/components/TabBar.tsx"() {
|
|
5335
5191
|
"use strict";
|
|
5336
5192
|
TabBar = ({ tabs, activeTab, onChange }) => {
|
|
5337
|
-
|
|
5193
|
+
useInput4((input, key) => {
|
|
5338
5194
|
if (key.leftArrow) {
|
|
5339
5195
|
const index = tabs.findIndex((t) => t.id === activeTab);
|
|
5340
5196
|
if (index !== -1) {
|
|
@@ -5355,11 +5211,11 @@ var init_TabBar = __esm({
|
|
|
5355
5211
|
if (tab) onChange(tab.id);
|
|
5356
5212
|
}
|
|
5357
5213
|
});
|
|
5358
|
-
return /* @__PURE__ */
|
|
5214
|
+
return /* @__PURE__ */ jsxs7(Box8, { borderStyle: "single", paddingX: 1, borderColor: "gray", children: [
|
|
5359
5215
|
tabs.map((tab, index) => {
|
|
5360
5216
|
const isActive = tab.id === activeTab;
|
|
5361
|
-
return /* @__PURE__ */
|
|
5362
|
-
|
|
5217
|
+
return /* @__PURE__ */ jsx9(Box8, { marginRight: 2, children: /* @__PURE__ */ jsx9(
|
|
5218
|
+
Text8,
|
|
5363
5219
|
{
|
|
5364
5220
|
color: isActive ? "cyan" : "white",
|
|
5365
5221
|
bold: isActive,
|
|
@@ -5368,8 +5224,8 @@ var init_TabBar = __esm({
|
|
|
5368
5224
|
}
|
|
5369
5225
|
) }, tab.id);
|
|
5370
5226
|
}),
|
|
5371
|
-
/* @__PURE__ */
|
|
5372
|
-
/* @__PURE__ */
|
|
5227
|
+
/* @__PURE__ */ jsx9(Box8, { flexGrow: 1 }),
|
|
5228
|
+
/* @__PURE__ */ jsx9(Text8, { color: "dim", children: "Use \u25C4/\u25BA arrows to navigate" })
|
|
5373
5229
|
] });
|
|
5374
5230
|
};
|
|
5375
5231
|
}
|
|
@@ -5380,62 +5236,54 @@ var App_exports = {};
|
|
|
5380
5236
|
__export(App_exports, {
|
|
5381
5237
|
App: () => App
|
|
5382
5238
|
});
|
|
5383
|
-
import { useState as
|
|
5384
|
-
import { Box as
|
|
5239
|
+
import { useState as useState5, useEffect as useEffect6, useMemo as useMemo5, useCallback as useCallback3 } from "react";
|
|
5240
|
+
import { Box as Box9, useInput as useInput5, useApp } from "ink";
|
|
5385
5241
|
import fs20 from "fs";
|
|
5386
|
-
import { jsx as
|
|
5242
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5387
5243
|
var App;
|
|
5388
5244
|
var init_App = __esm({
|
|
5389
5245
|
"src/mcp/ui/App.tsx"() {
|
|
5390
5246
|
"use strict";
|
|
5391
5247
|
init_Overview();
|
|
5392
5248
|
init_ProjectsView();
|
|
5393
|
-
|
|
5249
|
+
init_TasksView();
|
|
5394
5250
|
init_LogViewer();
|
|
5395
5251
|
init_StatusBoard();
|
|
5396
|
-
init_IndexingStatus();
|
|
5397
5252
|
init_TabBar();
|
|
5398
|
-
init_config();
|
|
5399
5253
|
init_config_utils();
|
|
5400
|
-
init_detection();
|
|
5401
5254
|
init_logger();
|
|
5402
5255
|
init_server();
|
|
5403
|
-
init_resources();
|
|
5404
|
-
init_install();
|
|
5405
5256
|
init_paths();
|
|
5257
|
+
init_install();
|
|
5406
5258
|
init_ConfigContext();
|
|
5407
5259
|
App = ({ onExit, initialPort }) => {
|
|
5408
5260
|
const { exit } = useApp();
|
|
5409
5261
|
const { config, projects, exposedProjects, driftReports, refresh: refreshData } = useConfig();
|
|
5410
|
-
const [activeTab, setActiveTab] =
|
|
5411
|
-
const [logs, setLogs] =
|
|
5412
|
-
const [serverInfo, setServerInfo] =
|
|
5262
|
+
const [activeTab, setActiveTab] = useState5("overview");
|
|
5263
|
+
const [logs, setLogs] = useState5([]);
|
|
5264
|
+
const [serverInfo, setServerInfo] = useState5({
|
|
5413
5265
|
port: initialPort,
|
|
5414
5266
|
pid: process.pid,
|
|
5415
5267
|
running: false
|
|
5416
5268
|
});
|
|
5417
|
-
const isRAGEnabled =
|
|
5269
|
+
const isRAGEnabled = useMemo5(() => {
|
|
5418
5270
|
return exposedProjects.some((p) => {
|
|
5419
5271
|
const cfg = findProjectConfig(config, { name: p.name, path: p.path });
|
|
5420
5272
|
return cfg?.semanticSearch?.enabled || p.semanticSearchEnabled;
|
|
5421
5273
|
});
|
|
5422
5274
|
}, [exposedProjects, config]);
|
|
5423
|
-
const hasAnyDrift =
|
|
5275
|
+
const hasAnyDrift = useMemo5(
|
|
5424
5276
|
() => Object.values(driftReports).some((r) => r.hasDrift),
|
|
5425
5277
|
[driftReports]
|
|
5426
5278
|
);
|
|
5427
|
-
const tabs =
|
|
5428
|
-
|
|
5279
|
+
const tabs = useMemo5(() => {
|
|
5280
|
+
return [
|
|
5429
5281
|
{ id: "overview", label: "Overview" },
|
|
5430
5282
|
{ id: "logs", label: "Logs" },
|
|
5431
|
-
{ id: "
|
|
5432
|
-
{ id: "
|
|
5283
|
+
{ id: "tasks", label: "Tasks" },
|
|
5284
|
+
{ id: "projects", label: "Projects" }
|
|
5433
5285
|
];
|
|
5434
|
-
|
|
5435
|
-
baseTabs.splice(3, 0, { id: "indexing", label: "Indexing" });
|
|
5436
|
-
}
|
|
5437
|
-
return baseTabs;
|
|
5438
|
-
}, [isRAGEnabled]);
|
|
5286
|
+
}, []);
|
|
5439
5287
|
const workspacePath = detectWorkspaceRoot();
|
|
5440
5288
|
const installStatus = checkInstallStatus(workspacePath);
|
|
5441
5289
|
const installedCount = [
|
|
@@ -5487,7 +5335,7 @@ var init_App = __esm({
|
|
|
5487
5335
|
}, 500);
|
|
5488
5336
|
return () => clearInterval(interval);
|
|
5489
5337
|
}, []);
|
|
5490
|
-
|
|
5338
|
+
useInput5(async (input, key) => {
|
|
5491
5339
|
if (input === "q" || key.ctrl && input === "c") {
|
|
5492
5340
|
stopMCPServer();
|
|
5493
5341
|
onExit();
|
|
@@ -5511,10 +5359,10 @@ var init_App = __esm({
|
|
|
5511
5359
|
const handleConfigChange = useCallback3(() => {
|
|
5512
5360
|
refreshData();
|
|
5513
5361
|
}, [refreshData]);
|
|
5514
|
-
return /* @__PURE__ */
|
|
5515
|
-
/* @__PURE__ */
|
|
5516
|
-
/* @__PURE__ */
|
|
5517
|
-
activeTab === "overview" && /* @__PURE__ */
|
|
5362
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", padding: 0, height: termHeight, children: [
|
|
5363
|
+
/* @__PURE__ */ jsx10(TabBar, { tabs, activeTab, onChange: setActiveTab }),
|
|
5364
|
+
/* @__PURE__ */ jsxs8(Box9, { marginTop: 1, flexGrow: 1, children: [
|
|
5365
|
+
activeTab === "overview" && /* @__PURE__ */ jsx10(
|
|
5518
5366
|
Overview,
|
|
5519
5367
|
{
|
|
5520
5368
|
serverStatus: serverInfo,
|
|
@@ -5522,15 +5370,15 @@ var init_App = __esm({
|
|
|
5522
5370
|
exposedProjects: exposedProjects.length,
|
|
5523
5371
|
totalProjects: projects.length,
|
|
5524
5372
|
installedIntegrations: installedCount
|
|
5525
|
-
}
|
|
5373
|
+
},
|
|
5374
|
+
logs
|
|
5526
5375
|
}
|
|
5527
5376
|
),
|
|
5528
|
-
activeTab === "
|
|
5529
|
-
activeTab === "
|
|
5530
|
-
activeTab === "
|
|
5531
|
-
activeTab === "logs" && /* @__PURE__ */ jsx12(LogViewer, { logs, height: contentHeight })
|
|
5377
|
+
activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight }),
|
|
5378
|
+
activeTab === "tasks" && /* @__PURE__ */ jsx10(TasksView, { projects }),
|
|
5379
|
+
activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { config, projects, onConfigChange: handleConfigChange })
|
|
5532
5380
|
] }),
|
|
5533
|
-
/* @__PURE__ */
|
|
5381
|
+
/* @__PURE__ */ jsx10(Box9, { marginTop: 0, children: /* @__PURE__ */ jsx10(
|
|
5534
5382
|
StatusBoard,
|
|
5535
5383
|
{
|
|
5536
5384
|
exposedLabel: `${exposedProjects.length} / ${projects.length} projects`,
|
|
@@ -5548,7 +5396,7 @@ var init_App = __esm({
|
|
|
5548
5396
|
// src/mcp/commands/start.ts
|
|
5549
5397
|
import { confirm as confirm3, isCancel as isCancel5, text } from "@clack/prompts";
|
|
5550
5398
|
async function handleStartServer() {
|
|
5551
|
-
const
|
|
5399
|
+
const React11 = await import("react");
|
|
5552
5400
|
const { render } = await import("ink");
|
|
5553
5401
|
const { App: App2 } = await Promise.resolve().then(() => (init_App(), App_exports));
|
|
5554
5402
|
const { ConfigProvider: ConfigProvider2 } = await Promise.resolve().then(() => (init_ConfigContext(), ConfigContext_exports));
|
|
@@ -5591,10 +5439,10 @@ async function handleStartServer() {
|
|
|
5591
5439
|
}
|
|
5592
5440
|
process.stdin.resume();
|
|
5593
5441
|
const app = render(
|
|
5594
|
-
|
|
5442
|
+
React11.createElement(
|
|
5595
5443
|
ConfigProvider2,
|
|
5596
5444
|
null,
|
|
5597
|
-
|
|
5445
|
+
React11.createElement(App2, {
|
|
5598
5446
|
initialPort,
|
|
5599
5447
|
onExit: () => {
|
|
5600
5448
|
}
|
|
@@ -6407,8 +6255,8 @@ linked_projects:
|
|
|
6407
6255
|
async function registerWithMCP(config, workspacePath, workspaceName) {
|
|
6408
6256
|
if (!config.exposeToMCP) return;
|
|
6409
6257
|
try {
|
|
6410
|
-
const { loadMCPConfig:
|
|
6411
|
-
const mcpConfig =
|
|
6258
|
+
const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6259
|
+
const mcpConfig = loadMCPConfig2();
|
|
6412
6260
|
setProjectConfig2(
|
|
6413
6261
|
mcpConfig,
|
|
6414
6262
|
workspaceName,
|
|
@@ -6801,8 +6649,8 @@ linked_projects:
|
|
|
6801
6649
|
});
|
|
6802
6650
|
if (shouldExpose && !isCancel9(shouldExpose)) {
|
|
6803
6651
|
try {
|
|
6804
|
-
const { loadMCPConfig:
|
|
6805
|
-
const mcpConfig =
|
|
6652
|
+
const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6653
|
+
const mcpConfig = loadMCPConfig2();
|
|
6806
6654
|
for (const project of selectedProjects) {
|
|
6807
6655
|
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
6808
6656
|
}
|