rrce-workflow 0.3.10 → 0.3.12
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 +717 -830
- 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");
|
|
@@ -4217,242 +4213,13 @@ var Header;
|
|
|
4217
4213
|
var init_Header = __esm({
|
|
4218
4214
|
"src/mcp/ui/Header.tsx"() {
|
|
4219
4215
|
"use strict";
|
|
4220
|
-
Header = () => /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingBottom: 1, children: /* @__PURE__ */ jsx(Box, { borderStyle: "double", borderColor: "
|
|
4221
|
-
}
|
|
4222
|
-
});
|
|
4223
|
-
|
|
4224
|
-
// src/mcp/ui/Overview.tsx
|
|
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";
|
|
4216
|
+
Header = () => /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingBottom: 1, children: /* @__PURE__ */ jsx(Box, { borderStyle: "double", borderColor: "white", paddingX: 2, justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: " RRCE MCP Hub " }) }) });
|
|
4365
4217
|
}
|
|
4366
4218
|
});
|
|
4367
4219
|
|
|
4368
|
-
// src/
|
|
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,208 +4393,381 @@ 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
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
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();
|
|
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: "white", 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, { flexDirection: "column", children: [
|
|
4649
|
+
/* @__PURE__ */ jsxs2(Box3, { children: [
|
|
4650
|
+
/* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
|
|
4651
|
+
isMulti && /* @__PURE__ */ jsx4(Text3, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
|
|
4652
|
+
/* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: item.label.split("\n")[0] })
|
|
4653
|
+
] }),
|
|
4654
|
+
item.label.includes("\n") && /* @__PURE__ */ jsxs2(Box3, { paddingLeft: isSelected ? 2 : 2, children: [
|
|
4655
|
+
isMulti && /* @__PURE__ */ jsx4(Text3, { children: " " }),
|
|
4656
|
+
/* @__PURE__ */ jsx4(Text3, { dimColor: true, children: item.label.split("\n").slice(1).join("\n") })
|
|
4657
|
+
] })
|
|
4658
|
+
] }, item.key || String(item.value));
|
|
4659
|
+
}),
|
|
4660
|
+
/* @__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" }) })
|
|
4661
|
+
] });
|
|
4662
|
+
}
|
|
4663
|
+
var init_SimpleSelect = __esm({
|
|
4664
|
+
"src/mcp/ui/components/SimpleSelect.tsx"() {
|
|
4665
|
+
"use strict";
|
|
4666
|
+
}
|
|
4667
|
+
});
|
|
4668
|
+
|
|
4669
|
+
// src/mcp/ui/ProjectsView.tsx
|
|
4670
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
4671
|
+
import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
|
|
4672
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4673
|
+
function projectKey(p) {
|
|
4674
|
+
return p.sourcePath ?? p.path;
|
|
4675
|
+
}
|
|
4676
|
+
function formatProjectLabel(p) {
|
|
4677
|
+
const root = p.sourcePath ?? p.path;
|
|
4678
|
+
return `${p.name} (${p.source})${root ? ` - ${root}` : ""}`;
|
|
4679
|
+
}
|
|
4680
|
+
var ProjectsView;
|
|
4681
|
+
var init_ProjectsView = __esm({
|
|
4682
|
+
"src/mcp/ui/ProjectsView.tsx"() {
|
|
4683
|
+
"use strict";
|
|
4684
|
+
init_SimpleSelect();
|
|
4685
|
+
init_config();
|
|
4686
|
+
init_ConfigContext();
|
|
4687
|
+
init_indexing_jobs();
|
|
4688
|
+
init_config_utils();
|
|
4689
|
+
ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange, workspacePath }) => {
|
|
4710
4690
|
const { driftReports, checkAllDrift } = useConfig();
|
|
4711
4691
|
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);
|
|
4692
|
+
const [indexingStats, setIndexingStats] = useState3({});
|
|
4717
4693
|
const sortedProjects = useMemo3(() => {
|
|
4718
4694
|
return [...allProjects].sort((a, b) => {
|
|
4695
|
+
const aIsCurrent = a.path === workspacePath;
|
|
4696
|
+
const bIsCurrent = b.path === workspacePath;
|
|
4697
|
+
if (aIsCurrent && !bIsCurrent) return -1;
|
|
4698
|
+
if (!aIsCurrent && bIsCurrent) return 1;
|
|
4719
4699
|
const byName = a.name.localeCompare(b.name);
|
|
4720
4700
|
if (byName !== 0) return byName;
|
|
4721
4701
|
return projectKey(a).localeCompare(projectKey(b));
|
|
4722
4702
|
});
|
|
4723
|
-
}, [allProjects]);
|
|
4724
|
-
|
|
4725
|
-
const
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4703
|
+
}, [allProjects, workspacePath]);
|
|
4704
|
+
useEffect3(() => {
|
|
4705
|
+
const updateStats = () => {
|
|
4706
|
+
const next = {};
|
|
4707
|
+
for (const p of allProjects) {
|
|
4708
|
+
let projConfig = findProjectConfig(config, { name: p.name, path: p.path });
|
|
4709
|
+
if (!projConfig && p.source === "global") {
|
|
4710
|
+
projConfig = config.projects.find((c) => c.name === p.name);
|
|
4711
|
+
}
|
|
4712
|
+
const enabled = projConfig?.semanticSearch?.enabled || p.semanticSearchEnabled || false;
|
|
4713
|
+
const prog = indexingJobs.getProgress(p.name);
|
|
4714
|
+
next[p.name] = { enabled, ...prog };
|
|
4715
|
+
}
|
|
4716
|
+
setIndexingStats(next);
|
|
4717
|
+
};
|
|
4718
|
+
updateStats();
|
|
4719
|
+
const interval = setInterval(updateStats, 2e3);
|
|
4720
|
+
return () => clearInterval(interval);
|
|
4721
|
+
}, [allProjects, config]);
|
|
4735
4722
|
useInput2((input, key) => {
|
|
4736
|
-
if (input === "t") {
|
|
4737
|
-
setErrorLine(null);
|
|
4738
|
-
setMode((prev) => prev === "expose" ? "tasks" : "expose");
|
|
4739
|
-
return;
|
|
4740
|
-
}
|
|
4741
4723
|
if (input === "u") {
|
|
4742
4724
|
checkAllDrift();
|
|
4743
4725
|
return;
|
|
4744
4726
|
}
|
|
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);
|
|
4786
|
-
}
|
|
4787
|
-
return;
|
|
4788
|
-
}
|
|
4789
|
-
if (input === "s") {
|
|
4790
|
-
const row = flattenedRows[selectedIndex];
|
|
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
|
-
});
|
|
4727
|
+
if (input === "a") {
|
|
4728
|
+
const newConfig = {
|
|
4729
|
+
...config,
|
|
4730
|
+
defaults: {
|
|
4731
|
+
...config.defaults,
|
|
4732
|
+
includeNew: !config.defaults.includeNew
|
|
4805
4733
|
}
|
|
4806
|
-
|
|
4807
|
-
|
|
4734
|
+
};
|
|
4735
|
+
saveMCPConfig(newConfig);
|
|
4736
|
+
setConfig(newConfig);
|
|
4737
|
+
onConfigChange?.();
|
|
4808
4738
|
}
|
|
4809
4739
|
});
|
|
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
4740
|
const projectItems = useMemo3(() => {
|
|
4817
|
-
return
|
|
4741
|
+
return sortedProjects.map((p) => {
|
|
4818
4742
|
const projectConfig = config.projects.find(
|
|
4819
4743
|
(c) => c.path && c.path === p.path || p.source === "global" && c.name === p.name || !c.path && c.name === p.name
|
|
4820
4744
|
);
|
|
4821
4745
|
const isExposed = projectConfig ? projectConfig.expose : config.defaults.includeNew;
|
|
4822
4746
|
const drift = driftReports[p.path];
|
|
4747
|
+
const idx = indexingStats[p.name];
|
|
4748
|
+
let label = formatProjectLabel(p);
|
|
4749
|
+
if (drift?.hasDrift) {
|
|
4750
|
+
label += ` \u26A0`;
|
|
4751
|
+
}
|
|
4752
|
+
if (idx?.state === "running") {
|
|
4753
|
+
label += `
|
|
4754
|
+
\u27F3 Indexing ${idx.itemsDone}/${idx.itemsTotal ?? "?"}`;
|
|
4755
|
+
} else if (idx?.state === "failed") {
|
|
4756
|
+
label += `
|
|
4757
|
+
\u2715 Index Fail`;
|
|
4758
|
+
} else if (idx?.enabled && idx?.state === "complete") {
|
|
4759
|
+
label += `
|
|
4760
|
+
\u2713 Indexed`;
|
|
4761
|
+
}
|
|
4823
4762
|
return {
|
|
4824
|
-
label
|
|
4763
|
+
label,
|
|
4825
4764
|
value: p.path,
|
|
4826
4765
|
key: p.path,
|
|
4827
|
-
exposed: isExposed
|
|
4766
|
+
exposed: isExposed,
|
|
4767
|
+
indexing: idx
|
|
4828
4768
|
};
|
|
4829
4769
|
});
|
|
4830
|
-
}, [
|
|
4770
|
+
}, [sortedProjects, config, driftReports, indexingStats]);
|
|
4831
4771
|
const initialSelected = useMemo3(() => {
|
|
4832
4772
|
return projectItems.filter((p) => p.exposed).map((p) => p.value);
|
|
4833
4773
|
}, [projectItems]);
|
|
@@ -4852,11 +4792,158 @@ var init_ProjectsView = __esm({
|
|
|
4852
4792
|
setConfig(newConfig);
|
|
4853
4793
|
onConfigChange?.();
|
|
4854
4794
|
};
|
|
4855
|
-
|
|
4795
|
+
return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "white", flexGrow: 1, children: [
|
|
4796
|
+
/* @__PURE__ */ jsxs3(Box4, { justifyContent: "space-between", children: [
|
|
4797
|
+
/* @__PURE__ */ jsxs3(Box4, { children: [
|
|
4798
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "cyan", children: " Projects " }),
|
|
4799
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " \u2022 " }),
|
|
4800
|
+
/* @__PURE__ */ jsxs3(Text4, { color: config.defaults.includeNew ? "green" : "red", children: [
|
|
4801
|
+
"Auto-expose: ",
|
|
4802
|
+
config.defaults.includeNew ? "ON" : "OFF"
|
|
4803
|
+
] })
|
|
4804
|
+
] }),
|
|
4805
|
+
/* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Text4, { color: "dim", children: "a:Toggle Auto u:Drift Space:Select Enter:Save" }) })
|
|
4806
|
+
] }),
|
|
4807
|
+
/* @__PURE__ */ jsx5(Text4, { color: "dim", children: " Manage which projects are exposed to the MCP server." }),
|
|
4808
|
+
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx5(
|
|
4809
|
+
SimpleSelect,
|
|
4810
|
+
{
|
|
4811
|
+
message: "",
|
|
4812
|
+
items: projectItems,
|
|
4813
|
+
isMulti: true,
|
|
4814
|
+
initialSelected,
|
|
4815
|
+
onSelect: () => {
|
|
4816
|
+
},
|
|
4817
|
+
onSubmit: handleSubmit,
|
|
4818
|
+
onCancel: () => {
|
|
4819
|
+
}
|
|
4820
|
+
},
|
|
4821
|
+
JSON.stringify(initialSelected) + config.defaults.includeNew + JSON.stringify(indexingStats)
|
|
4822
|
+
) }),
|
|
4823
|
+
/* @__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." }) })
|
|
4824
|
+
] });
|
|
4825
|
+
};
|
|
4826
|
+
}
|
|
4827
|
+
});
|
|
4828
|
+
|
|
4829
|
+
// src/mcp/ui/ui-helpers.ts
|
|
4830
|
+
var getStatusIcon, getStatusColor, getChecklistProgress, getCheckbox, getProgressBar, getFolderIcon;
|
|
4831
|
+
var init_ui_helpers = __esm({
|
|
4832
|
+
"src/mcp/ui/ui-helpers.ts"() {
|
|
4833
|
+
"use strict";
|
|
4834
|
+
getStatusIcon = (status) => {
|
|
4835
|
+
const icons = {
|
|
4836
|
+
pending: "\u23F3",
|
|
4837
|
+
in_progress: "\u{1F504}",
|
|
4838
|
+
blocked: "\u{1F6AB}",
|
|
4839
|
+
complete: "\u2705"
|
|
4840
|
+
};
|
|
4841
|
+
return icons[status] || "\u25CB";
|
|
4842
|
+
};
|
|
4843
|
+
getStatusColor = (status) => {
|
|
4844
|
+
const colors = {
|
|
4845
|
+
pending: "yellow",
|
|
4846
|
+
in_progress: "yellow",
|
|
4847
|
+
blocked: "red",
|
|
4848
|
+
complete: "green"
|
|
4849
|
+
};
|
|
4850
|
+
return colors[status] || "white";
|
|
4851
|
+
};
|
|
4852
|
+
getChecklistProgress = (checklist) => {
|
|
4853
|
+
if (!checklist || checklist.length === 0) {
|
|
4854
|
+
return { completed: 0, total: 0, percentage: 0 };
|
|
4855
|
+
}
|
|
4856
|
+
const completed = checklist.filter((item) => item.status === "done").length;
|
|
4857
|
+
return {
|
|
4858
|
+
completed,
|
|
4859
|
+
total: checklist.length,
|
|
4860
|
+
percentage: Math.round(completed / checklist.length * 100)
|
|
4861
|
+
};
|
|
4862
|
+
};
|
|
4863
|
+
getCheckbox = (status) => {
|
|
4864
|
+
return status === "done" ? "\u2611" : "\u2610";
|
|
4865
|
+
};
|
|
4866
|
+
getProgressBar = (percentage, length = 10) => {
|
|
4867
|
+
const filled = Math.floor(percentage / 100 * length);
|
|
4868
|
+
const empty = length - filled;
|
|
4869
|
+
return "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
4870
|
+
};
|
|
4871
|
+
getFolderIcon = (isOpen) => {
|
|
4872
|
+
return isOpen ? "\u{1F4C2}" : "\u{1F4C1}";
|
|
4873
|
+
};
|
|
4874
|
+
}
|
|
4875
|
+
});
|
|
4876
|
+
|
|
4877
|
+
// src/mcp/ui/TasksView.tsx
|
|
4878
|
+
import { useEffect as useEffect4, useMemo as useMemo4, useState as useState4 } from "react";
|
|
4879
|
+
import { Box as Box5, Text as Text5, useInput as useInput3 } from "ink";
|
|
4880
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4881
|
+
function nextStatus(current) {
|
|
4882
|
+
const idx = STATUS_CYCLE.indexOf(current || "");
|
|
4883
|
+
if (idx === -1) return STATUS_CYCLE[0];
|
|
4884
|
+
return STATUS_CYCLE[(idx + 1) % STATUS_CYCLE.length];
|
|
4885
|
+
}
|
|
4886
|
+
function projectKey2(p) {
|
|
4887
|
+
return p.sourcePath ?? p.path;
|
|
4888
|
+
}
|
|
4889
|
+
function formatProjectLabel2(p) {
|
|
4890
|
+
return `${p.name} (${p.source})`;
|
|
4891
|
+
}
|
|
4892
|
+
var STATUS_CYCLE, TasksView;
|
|
4893
|
+
var init_TasksView = __esm({
|
|
4894
|
+
"src/mcp/ui/TasksView.tsx"() {
|
|
4895
|
+
"use strict";
|
|
4896
|
+
init_tasks_fs();
|
|
4897
|
+
init_ConfigContext();
|
|
4898
|
+
init_ui_helpers();
|
|
4899
|
+
STATUS_CYCLE = ["pending", "in_progress", "blocked", "complete"];
|
|
4900
|
+
TasksView = ({ projects: allProjects, workspacePath }) => {
|
|
4901
|
+
const { driftReports } = useConfig();
|
|
4902
|
+
const [expanded, setExpanded] = useState4(() => /* @__PURE__ */ new Set());
|
|
4903
|
+
const [selectedIndex, setSelectedIndex] = useState4(0);
|
|
4904
|
+
const [taskCache, setTaskCache] = useState4({});
|
|
4905
|
+
const [errorLine, setErrorLine] = useState4(null);
|
|
4906
|
+
const sortedProjects = useMemo4(() => {
|
|
4907
|
+
return [...allProjects].sort((a, b) => {
|
|
4908
|
+
const aIsCurrent = a.path === workspacePath;
|
|
4909
|
+
const bIsCurrent = b.path === workspacePath;
|
|
4910
|
+
if (aIsCurrent && !bIsCurrent) return -1;
|
|
4911
|
+
if (!aIsCurrent && bIsCurrent) return 1;
|
|
4912
|
+
const byName = a.name.localeCompare(b.name);
|
|
4913
|
+
if (byName !== 0) return byName;
|
|
4914
|
+
return projectKey2(a).localeCompare(projectKey2(b));
|
|
4915
|
+
});
|
|
4916
|
+
}, [allProjects, workspacePath]);
|
|
4917
|
+
useEffect4(() => {
|
|
4918
|
+
const current = sortedProjects.find((p) => p.path === workspacePath);
|
|
4919
|
+
if (current) {
|
|
4920
|
+
const k = projectKey2(current);
|
|
4921
|
+
setExpanded((prev) => {
|
|
4922
|
+
const next = new Set(prev);
|
|
4923
|
+
if (!next.has(k)) {
|
|
4924
|
+
next.add(k);
|
|
4925
|
+
refreshTasksForProject(current);
|
|
4926
|
+
}
|
|
4927
|
+
return next;
|
|
4928
|
+
});
|
|
4929
|
+
}
|
|
4930
|
+
}, [sortedProjects, workspacePath]);
|
|
4931
|
+
const refreshTasksForProject = (project) => {
|
|
4932
|
+
const res = listProjectTasks(project);
|
|
4933
|
+
setTaskCache((prev) => ({ ...prev, [projectKey2(project)]: res.tasks }));
|
|
4934
|
+
};
|
|
4935
|
+
const refreshAllTasks = () => {
|
|
4936
|
+
const next = {};
|
|
4937
|
+
for (const p of sortedProjects) {
|
|
4938
|
+
next[projectKey2(p)] = listProjectTasks(p).tasks;
|
|
4939
|
+
}
|
|
4940
|
+
setTaskCache(next);
|
|
4941
|
+
};
|
|
4942
|
+
const flattenedRows = useMemo4(() => {
|
|
4856
4943
|
const rows = [];
|
|
4857
4944
|
for (const p of sortedProjects) {
|
|
4858
4945
|
rows.push({ kind: "project", project: p });
|
|
4859
|
-
const k =
|
|
4946
|
+
const k = projectKey2(p);
|
|
4860
4947
|
if (!expanded.has(k)) continue;
|
|
4861
4948
|
const tasks = taskCache[k] || [];
|
|
4862
4949
|
for (const t of tasks) {
|
|
@@ -4868,133 +4955,158 @@ var init_ProjectsView = __esm({
|
|
|
4868
4955
|
}
|
|
4869
4956
|
return rows;
|
|
4870
4957
|
}, [sortedProjects, expanded, taskCache]);
|
|
4958
|
+
useInput3((input, key) => {
|
|
4959
|
+
if (input === "R") {
|
|
4960
|
+
setErrorLine(null);
|
|
4961
|
+
refreshAllTasks();
|
|
4962
|
+
return;
|
|
4963
|
+
}
|
|
4964
|
+
if (key.upArrow) {
|
|
4965
|
+
setSelectedIndex((prev) => prev > 0 ? prev - 1 : Math.max(0, flattenedRows.length - 1));
|
|
4966
|
+
return;
|
|
4967
|
+
}
|
|
4968
|
+
if (key.downArrow) {
|
|
4969
|
+
setSelectedIndex((prev) => prev < flattenedRows.length - 1 ? prev + 1 : 0);
|
|
4970
|
+
return;
|
|
4971
|
+
}
|
|
4972
|
+
if (key.return) {
|
|
4973
|
+
const row = flattenedRows[selectedIndex];
|
|
4974
|
+
if (row?.kind === "project") {
|
|
4975
|
+
const k = projectKey2(row.project);
|
|
4976
|
+
const next = new Set(expanded);
|
|
4977
|
+
if (next.has(k)) {
|
|
4978
|
+
next.delete(k);
|
|
4979
|
+
} else {
|
|
4980
|
+
next.add(k);
|
|
4981
|
+
refreshTasksForProject(row.project);
|
|
4982
|
+
}
|
|
4983
|
+
setExpanded(next);
|
|
4984
|
+
}
|
|
4985
|
+
return;
|
|
4986
|
+
}
|
|
4987
|
+
if (input === "s") {
|
|
4988
|
+
const row = flattenedRows[selectedIndex];
|
|
4989
|
+
if (row?.kind === "task") {
|
|
4990
|
+
setErrorLine(null);
|
|
4991
|
+
const desired = nextStatus(row.task.status);
|
|
4992
|
+
const result = updateTaskStatus(row.project, row.task.task_slug, desired);
|
|
4993
|
+
if (!result.ok) {
|
|
4994
|
+
setErrorLine(`Failed to update status: ${result.error}`);
|
|
4995
|
+
return;
|
|
4996
|
+
}
|
|
4997
|
+
setTaskCache((prev) => {
|
|
4998
|
+
const k = projectKey2(row.project);
|
|
4999
|
+
const tasks = prev[k] || [];
|
|
5000
|
+
const updated = tasks.map((t) => t.task_slug === row.task.task_slug ? result.meta : t);
|
|
5001
|
+
return { ...prev, [k]: updated };
|
|
5002
|
+
});
|
|
5003
|
+
}
|
|
5004
|
+
return;
|
|
5005
|
+
}
|
|
5006
|
+
});
|
|
5007
|
+
useEffect4(() => {
|
|
5008
|
+
setSelectedIndex((prev) => {
|
|
5009
|
+
if (flattenedRows.length === 0) return 0;
|
|
5010
|
+
return Math.min(prev, flattenedRows.length - 1);
|
|
5011
|
+
});
|
|
5012
|
+
}, [flattenedRows]);
|
|
4871
5013
|
const selectedRow = flattenedRows[selectedIndex];
|
|
4872
5014
|
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: [
|
|
5015
|
+
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "white", flexGrow: 1, children: [
|
|
5016
|
+
/* @__PURE__ */ jsxs4(Box5, { justifyContent: "space-between", children: [
|
|
5017
|
+
/* @__PURE__ */ jsxs4(Box5, { children: [
|
|
5018
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u2699 Tasks" }),
|
|
5019
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \u2022 " }),
|
|
5020
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
4907
5021
|
sortedProjects.length,
|
|
4908
5022
|
" projects"
|
|
4909
5023
|
] }),
|
|
4910
|
-
/* @__PURE__ */
|
|
4911
|
-
/* @__PURE__ */
|
|
5024
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \u2022 " }),
|
|
5025
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
4912
5026
|
Object.values(taskCache).flat().length,
|
|
4913
5027
|
" tasks"
|
|
4914
5028
|
] })
|
|
4915
5029
|
] }),
|
|
4916
|
-
/* @__PURE__ */
|
|
5030
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2191/\u2193:Nav Enter:Expand s:Status R:Refresh" })
|
|
4917
5031
|
] }),
|
|
4918
|
-
errorLine && /* @__PURE__ */
|
|
4919
|
-
/* @__PURE__ */
|
|
4920
|
-
/* @__PURE__ */
|
|
4921
|
-
flattenedRows.length === 0 ? /* @__PURE__ */
|
|
5032
|
+
errorLine && /* @__PURE__ */ jsx6(Box5, { marginTop: 0, children: /* @__PURE__ */ jsx6(Text5, { color: "red", children: errorLine }) }),
|
|
5033
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, flexDirection: "row", flexGrow: 1, children: [
|
|
5034
|
+
/* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", width: "55%", children: [
|
|
5035
|
+
flattenedRows.length === 0 ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "No projects detected." }) : flattenedRows.map((row, idx) => {
|
|
4922
5036
|
const isSel = idx === selectedIndex;
|
|
4923
5037
|
if (row.kind === "project") {
|
|
4924
|
-
const k =
|
|
5038
|
+
const k = projectKey2(row.project);
|
|
4925
5039
|
const isOpen = expanded.has(k);
|
|
4926
5040
|
const count = (taskCache[k] || []).length;
|
|
4927
5041
|
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
|
-
] })
|
|
5042
|
+
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box5, { children: [
|
|
5043
|
+
/* @__PURE__ */ jsx6(Text5, { color: isSel ? "cyan" : "white", children: isSel ? "> " : " " }),
|
|
5044
|
+
/* @__PURE__ */ jsxs4(Text5, { color: isSel ? "cyan" : "white", children: [
|
|
5045
|
+
getFolderIcon(isOpen),
|
|
5046
|
+
" ",
|
|
5047
|
+
formatProjectLabel2(row.project)
|
|
4941
5048
|
] }),
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
"
|
|
4945
|
-
|
|
4946
|
-
|
|
5049
|
+
drift?.hasDrift && /* @__PURE__ */ jsx6(Text5, { color: "magenta", children: " \u26A0" }),
|
|
5050
|
+
/* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
|
|
5051
|
+
" ",
|
|
5052
|
+
count > 0 ? `(${count})` : ""
|
|
5053
|
+
] })
|
|
5054
|
+
] }) }, `p:${k}`);
|
|
4947
5055
|
}
|
|
4948
5056
|
const taskLabel = row.task.title || row.task.task_slug;
|
|
4949
5057
|
const status = row.task.status || "";
|
|
4950
|
-
return /* @__PURE__ */
|
|
4951
|
-
/* @__PURE__ */
|
|
4952
|
-
/* @__PURE__ */
|
|
4953
|
-
/* @__PURE__ */
|
|
4954
|
-
row.task.task_slug !== "__none__" && /* @__PURE__ */
|
|
4955
|
-
] }, `t:${
|
|
5058
|
+
return /* @__PURE__ */ jsxs4(Box5, { children: [
|
|
5059
|
+
/* @__PURE__ */ jsx6(Text5, { color: isSel ? "cyan" : "white", children: isSel ? "> " : " " }),
|
|
5060
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: " - " }),
|
|
5061
|
+
/* @__PURE__ */ jsx6(Text5, { color: isSel ? "cyan" : "white", children: taskLabel }),
|
|
5062
|
+
row.task.task_slug !== "__none__" && /* @__PURE__ */ jsx6(Text5, { backgroundColor: getStatusColor(status), color: "black", children: ` ${getStatusIcon(status)} ${status.toUpperCase().replace("_", " ")} ` })
|
|
5063
|
+
] }, `t:${projectKey2(row.project)}:${row.task.task_slug}`);
|
|
4956
5064
|
}),
|
|
4957
|
-
/* @__PURE__ */
|
|
5065
|
+
/* @__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
5066
|
] }),
|
|
4959
|
-
/* @__PURE__ */
|
|
4960
|
-
/* @__PURE__ */
|
|
4961
|
-
/* @__PURE__ */
|
|
4962
|
-
/* @__PURE__ */
|
|
4963
|
-
] }) : /* @__PURE__ */
|
|
4964
|
-
/* @__PURE__ */
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
5067
|
+
/* @__PURE__ */ jsx6(Box5, { flexDirection: "column", width: "45%", paddingLeft: 2, children: !selectedTask ? /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", justifyContent: "center", alignItems: "center", gap: 1, flexGrow: 1, children: [
|
|
5068
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "dim", children: "\u2500 No Task Selected \u2500" }),
|
|
5069
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Use \u2191/\u2193 to navigate, Enter to expand projects" }),
|
|
5070
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Press 's' to cycle task status" })
|
|
5071
|
+
] }) : /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
5072
|
+
/* @__PURE__ */ jsxs4(Box5, { marginBottom: 1, flexDirection: "column", children: [
|
|
5073
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: selectedTask.title || selectedTask.task_slug }),
|
|
5074
|
+
selectedTask.summary && /* @__PURE__ */ jsx6(Text5, { color: "white", children: selectedTask.summary })
|
|
5075
|
+
] }),
|
|
5076
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
|
|
5077
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
|
|
5078
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "white", children: "\u{1F4CB} STATUS" }),
|
|
5079
|
+
/* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
5080
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5081
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Status: " }),
|
|
4971
5082
|
" ",
|
|
4972
|
-
/* @__PURE__ */
|
|
5083
|
+
/* @__PURE__ */ jsx6(Text5, { color: getStatusColor(selectedTask.status || ""), children: selectedTask.status || "unknown" })
|
|
4973
5084
|
] }),
|
|
4974
|
-
/* @__PURE__ */
|
|
4975
|
-
/* @__PURE__ */
|
|
5085
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5086
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Updated:" }),
|
|
4976
5087
|
" ",
|
|
4977
|
-
/* @__PURE__ */
|
|
5088
|
+
/* @__PURE__ */ jsx6(Text5, { children: selectedTask.updated_at || "\u2014" })
|
|
4978
5089
|
] }),
|
|
4979
|
-
/* @__PURE__ */
|
|
4980
|
-
/* @__PURE__ */
|
|
5090
|
+
/* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5091
|
+
/* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Tags: " }),
|
|
4981
5092
|
" ",
|
|
4982
5093
|
" ",
|
|
4983
5094
|
(() => {
|
|
4984
5095
|
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__ */
|
|
5096
|
+
return tags.length > 0 ? tags.map((tag, i) => /* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5097
|
+
/* @__PURE__ */ jsx6(Text5, { color: "cyan", children: tag }),
|
|
5098
|
+
i < tags.length - 1 && /* @__PURE__ */ jsx6(Text5, { color: "dim", children: ", " })
|
|
5099
|
+
] }, tag)) : /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" });
|
|
4989
5100
|
})()
|
|
4990
5101
|
] })
|
|
4991
5102
|
] })
|
|
4992
5103
|
] }),
|
|
4993
|
-
/* @__PURE__ */
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
/* @__PURE__ */
|
|
5104
|
+
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }),
|
|
5105
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
|
|
5106
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "white", children: "\u{1F4CB} CHECKLIST" }),
|
|
5107
|
+
selectedTask.checklist && selectedTask.checklist.length > 0 && /* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box5, { marginBottom: 1, children: [
|
|
5108
|
+
/* @__PURE__ */ jsx6(Text5, { backgroundColor: "white", children: getProgressBar(getChecklistProgress(selectedTask.checklist).percentage) }),
|
|
5109
|
+
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
4998
5110
|
" ",
|
|
4999
5111
|
" ",
|
|
5000
5112
|
getChecklistProgress(selectedTask.checklist).completed,
|
|
@@ -5005,36 +5117,40 @@ var init_ProjectsView = __esm({
|
|
|
5005
5117
|
"%)"
|
|
5006
5118
|
] })
|
|
5007
5119
|
] }) }),
|
|
5008
|
-
(selectedTask.checklist || []).length === 0 ? /* @__PURE__ */
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
" "
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5120
|
+
(selectedTask.checklist || []).length === 0 ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : (selectedTask.checklist || []).slice(0, 12).map((c, i) => {
|
|
5121
|
+
const isDone = c.status === "done";
|
|
5122
|
+
return /* @__PURE__ */ jsxs4(Text5, { color: isDone ? "dim" : "white", children: [
|
|
5123
|
+
/* @__PURE__ */ jsxs4(Text5, { color: isDone ? "green" : "dim", children: [
|
|
5124
|
+
getCheckbox(c.status || "pending"),
|
|
5125
|
+
" "
|
|
5126
|
+
] }),
|
|
5127
|
+
c.label || c.id || "item"
|
|
5128
|
+
] }, c.id || i);
|
|
5129
|
+
})
|
|
5015
5130
|
] }),
|
|
5016
|
-
/* @__PURE__ */
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5131
|
+
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }),
|
|
5132
|
+
/* @__PURE__ */ jsxs4(Box5, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
|
|
5133
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "white", children: "\u{1F916} AGENTS" }),
|
|
5134
|
+
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "column", children: !selectedTask.agents ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : Object.entries(selectedTask.agents).map(([agent, info]) => /* @__PURE__ */ jsxs4(Text5, { children: [
|
|
5135
|
+
/* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
|
|
5020
5136
|
"- ",
|
|
5021
5137
|
agent,
|
|
5022
5138
|
": "
|
|
5023
5139
|
] }),
|
|
5024
|
-
info?.status === "complete" && /* @__PURE__ */
|
|
5025
|
-
info?.status === "in_progress" && /* @__PURE__ */
|
|
5026
|
-
info?.status === "pending" && /* @__PURE__ */
|
|
5027
|
-
info?.blocked && /* @__PURE__ */
|
|
5028
|
-
/* @__PURE__ */
|
|
5140
|
+
info?.status === "complete" && /* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u2713" }),
|
|
5141
|
+
info?.status === "in_progress" && /* @__PURE__ */ jsx6(Text5, { color: "yellow", children: "\u27F3" }),
|
|
5142
|
+
info?.status === "pending" && /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u25CB" }),
|
|
5143
|
+
info?.blocked && /* @__PURE__ */ jsx6(Text5, { color: "red", children: "\u2715" }),
|
|
5144
|
+
/* @__PURE__ */ jsxs4(Text5, { color: info?.status === "complete" ? "dim" : "white", children: [
|
|
5029
5145
|
" ",
|
|
5030
5146
|
info?.status || "\u2014"
|
|
5031
5147
|
] }),
|
|
5032
|
-
info?.artifact && /* @__PURE__ */
|
|
5033
|
-
"(",
|
|
5148
|
+
info?.artifact && /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
5149
|
+
" (",
|
|
5034
5150
|
info.artifact,
|
|
5035
5151
|
")"
|
|
5036
5152
|
] })
|
|
5037
|
-
] }, agent))
|
|
5153
|
+
] }, agent)) })
|
|
5038
5154
|
] })
|
|
5039
5155
|
] }) })
|
|
5040
5156
|
] })
|
|
@@ -5043,126 +5159,10 @@ var init_ProjectsView = __esm({
|
|
|
5043
5159
|
}
|
|
5044
5160
|
});
|
|
5045
5161
|
|
|
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
|
|
5162
|
+
// src/mcp/ui/LogViewer.tsx
|
|
5133
5163
|
import "react";
|
|
5134
5164
|
import { Box as Box6, Text as Text6 } from "ink";
|
|
5135
5165
|
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
5166
|
var LogViewer;
|
|
5167
5167
|
var init_LogViewer = __esm({
|
|
5168
5168
|
"src/mcp/ui/LogViewer.tsx"() {
|
|
@@ -5172,16 +5172,16 @@ var init_LogViewer = __esm({
|
|
|
5172
5172
|
const emptyLines = Math.max(0, height - visibleLogs.length);
|
|
5173
5173
|
const padding = Array(emptyLines).fill("");
|
|
5174
5174
|
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__ */
|
|
5175
|
+
if (log.includes("[RAG]")) return /* @__PURE__ */ jsx7(Text6, { color: "cyan", children: log });
|
|
5176
|
+
if (log.includes("[ERROR]")) return /* @__PURE__ */ jsx7(Text6, { color: "red", children: log });
|
|
5177
|
+
if (log.includes("[WARN]")) return /* @__PURE__ */ jsx7(Text6, { color: "yellow", children: log });
|
|
5178
|
+
if (log.includes("[INFO]")) return /* @__PURE__ */ jsx7(Text6, { color: "green", children: log });
|
|
5179
|
+
if (log.includes("Success")) return /* @__PURE__ */ jsx7(Text6, { color: "green", children: log });
|
|
5180
|
+
return /* @__PURE__ */ jsx7(Text6, { children: log });
|
|
5181
5181
|
};
|
|
5182
|
-
return /* @__PURE__ */
|
|
5183
|
-
padding.map((_, i) => /* @__PURE__ */
|
|
5184
|
-
visibleLogs.map((log, i) => /* @__PURE__ */
|
|
5182
|
+
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "white", paddingX: 1, height: height + 2, flexGrow: 1, children: [
|
|
5183
|
+
padding.map((_, i) => /* @__PURE__ */ jsx7(Text6, { children: " " }, `empty-${i}`)),
|
|
5184
|
+
visibleLogs.map((log, i) => /* @__PURE__ */ jsx7(Box6, { children: formatLog(log) }, `log-${i}`))
|
|
5185
5185
|
] });
|
|
5186
5186
|
};
|
|
5187
5187
|
}
|
|
@@ -5189,28 +5189,28 @@ var init_LogViewer = __esm({
|
|
|
5189
5189
|
|
|
5190
5190
|
// src/mcp/ui/StatusBoard.tsx
|
|
5191
5191
|
import "react";
|
|
5192
|
-
import { Box as
|
|
5193
|
-
import { jsx as
|
|
5192
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
5193
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5194
5194
|
var StatusBoard;
|
|
5195
5195
|
var init_StatusBoard = __esm({
|
|
5196
5196
|
"src/mcp/ui/StatusBoard.tsx"() {
|
|
5197
5197
|
"use strict";
|
|
5198
5198
|
StatusBoard = ({ exposedLabel, port, pid, running, hasDrift }) => {
|
|
5199
|
-
return /* @__PURE__ */
|
|
5200
|
-
running ? /* @__PURE__ */
|
|
5199
|
+
return /* @__PURE__ */ jsx8(Box7, { borderStyle: "single", borderColor: "white", paddingX: 1, flexGrow: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
|
|
5200
|
+
running ? /* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CF RUNNING" }) : /* @__PURE__ */ jsx8(Text7, { color: "red", children: "\u25CF STOPPED" }),
|
|
5201
5201
|
" ",
|
|
5202
5202
|
"\u2502",
|
|
5203
5203
|
" \u{1F4CB} ",
|
|
5204
|
-
/* @__PURE__ */
|
|
5204
|
+
/* @__PURE__ */ jsx8(Text7, { color: "yellow", children: exposedLabel }),
|
|
5205
5205
|
" ",
|
|
5206
5206
|
"\u2502",
|
|
5207
5207
|
" Port: ",
|
|
5208
|
-
/* @__PURE__ */
|
|
5208
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: port }),
|
|
5209
5209
|
" ",
|
|
5210
5210
|
"\u2502",
|
|
5211
5211
|
" PID: ",
|
|
5212
|
-
/* @__PURE__ */
|
|
5213
|
-
hasDrift && /* @__PURE__ */
|
|
5212
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: pid }),
|
|
5213
|
+
hasDrift && /* @__PURE__ */ jsxs6(Text7, { color: "magenta", bold: true, children: [
|
|
5214
5214
|
" ",
|
|
5215
5215
|
"\u2502",
|
|
5216
5216
|
" \u2B06 UPDATE AVAILABLE"
|
|
@@ -5220,121 +5220,16 @@ var init_StatusBoard = __esm({
|
|
|
5220
5220
|
}
|
|
5221
5221
|
});
|
|
5222
5222
|
|
|
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
5223
|
// src/mcp/ui/components/TabBar.tsx
|
|
5329
5224
|
import "react";
|
|
5330
|
-
import { Box as
|
|
5331
|
-
import { jsx as
|
|
5225
|
+
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
5226
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5332
5227
|
var TabBar;
|
|
5333
5228
|
var init_TabBar = __esm({
|
|
5334
5229
|
"src/mcp/ui/components/TabBar.tsx"() {
|
|
5335
5230
|
"use strict";
|
|
5336
5231
|
TabBar = ({ tabs, activeTab, onChange }) => {
|
|
5337
|
-
|
|
5232
|
+
useInput4((input, key) => {
|
|
5338
5233
|
if (key.leftArrow) {
|
|
5339
5234
|
const index = tabs.findIndex((t) => t.id === activeTab);
|
|
5340
5235
|
if (index !== -1) {
|
|
@@ -5355,11 +5250,11 @@ var init_TabBar = __esm({
|
|
|
5355
5250
|
if (tab) onChange(tab.id);
|
|
5356
5251
|
}
|
|
5357
5252
|
});
|
|
5358
|
-
return /* @__PURE__ */
|
|
5253
|
+
return /* @__PURE__ */ jsxs7(Box8, { borderStyle: "single", paddingX: 1, borderColor: "gray", children: [
|
|
5359
5254
|
tabs.map((tab, index) => {
|
|
5360
5255
|
const isActive = tab.id === activeTab;
|
|
5361
|
-
return /* @__PURE__ */
|
|
5362
|
-
|
|
5256
|
+
return /* @__PURE__ */ jsx9(Box8, { marginRight: 2, children: /* @__PURE__ */ jsx9(
|
|
5257
|
+
Text8,
|
|
5363
5258
|
{
|
|
5364
5259
|
color: isActive ? "cyan" : "white",
|
|
5365
5260
|
bold: isActive,
|
|
@@ -5368,8 +5263,8 @@ var init_TabBar = __esm({
|
|
|
5368
5263
|
}
|
|
5369
5264
|
) }, tab.id);
|
|
5370
5265
|
}),
|
|
5371
|
-
/* @__PURE__ */
|
|
5372
|
-
/* @__PURE__ */
|
|
5266
|
+
/* @__PURE__ */ jsx9(Box8, { flexGrow: 1 }),
|
|
5267
|
+
/* @__PURE__ */ jsx9(Text8, { color: "dim", children: "Use \u25C4/\u25BA arrows to navigate" })
|
|
5373
5268
|
] });
|
|
5374
5269
|
};
|
|
5375
5270
|
}
|
|
@@ -5380,63 +5275,55 @@ var App_exports = {};
|
|
|
5380
5275
|
__export(App_exports, {
|
|
5381
5276
|
App: () => App
|
|
5382
5277
|
});
|
|
5383
|
-
import { useState as
|
|
5384
|
-
import { Box as
|
|
5278
|
+
import { useState as useState5, useEffect as useEffect6, useMemo as useMemo5, useCallback as useCallback3 } from "react";
|
|
5279
|
+
import { Box as Box9, useInput as useInput5, useApp } from "ink";
|
|
5385
5280
|
import fs20 from "fs";
|
|
5386
|
-
import { jsx as
|
|
5281
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5387
5282
|
var App;
|
|
5388
5283
|
var init_App = __esm({
|
|
5389
5284
|
"src/mcp/ui/App.tsx"() {
|
|
5390
5285
|
"use strict";
|
|
5391
5286
|
init_Overview();
|
|
5392
5287
|
init_ProjectsView();
|
|
5393
|
-
|
|
5288
|
+
init_TasksView();
|
|
5394
5289
|
init_LogViewer();
|
|
5395
5290
|
init_StatusBoard();
|
|
5396
|
-
init_IndexingStatus();
|
|
5397
5291
|
init_TabBar();
|
|
5398
|
-
init_config();
|
|
5399
5292
|
init_config_utils();
|
|
5400
|
-
init_detection();
|
|
5401
5293
|
init_logger();
|
|
5402
5294
|
init_server();
|
|
5403
|
-
init_resources();
|
|
5404
|
-
init_install();
|
|
5405
5295
|
init_paths();
|
|
5296
|
+
init_install();
|
|
5406
5297
|
init_ConfigContext();
|
|
5407
5298
|
App = ({ onExit, initialPort }) => {
|
|
5408
5299
|
const { exit } = useApp();
|
|
5409
5300
|
const { config, projects, exposedProjects, driftReports, refresh: refreshData } = useConfig();
|
|
5410
|
-
const [activeTab, setActiveTab] =
|
|
5411
|
-
const [logs, setLogs] =
|
|
5412
|
-
const [serverInfo, setServerInfo] =
|
|
5301
|
+
const [activeTab, setActiveTab] = useState5("overview");
|
|
5302
|
+
const [logs, setLogs] = useState5([]);
|
|
5303
|
+
const [serverInfo, setServerInfo] = useState5({
|
|
5413
5304
|
port: initialPort,
|
|
5414
5305
|
pid: process.pid,
|
|
5415
5306
|
running: false
|
|
5416
5307
|
});
|
|
5417
|
-
const
|
|
5308
|
+
const workspacePath = useMemo5(() => detectWorkspaceRoot(), []);
|
|
5309
|
+
const isRAGEnabled = useMemo5(() => {
|
|
5418
5310
|
return exposedProjects.some((p) => {
|
|
5419
5311
|
const cfg = findProjectConfig(config, { name: p.name, path: p.path });
|
|
5420
5312
|
return cfg?.semanticSearch?.enabled || p.semanticSearchEnabled;
|
|
5421
5313
|
});
|
|
5422
5314
|
}, [exposedProjects, config]);
|
|
5423
|
-
const hasAnyDrift =
|
|
5315
|
+
const hasAnyDrift = useMemo5(
|
|
5424
5316
|
() => Object.values(driftReports).some((r) => r.hasDrift),
|
|
5425
5317
|
[driftReports]
|
|
5426
5318
|
);
|
|
5427
|
-
const tabs =
|
|
5428
|
-
|
|
5319
|
+
const tabs = useMemo5(() => {
|
|
5320
|
+
return [
|
|
5429
5321
|
{ id: "overview", label: "Overview" },
|
|
5430
5322
|
{ id: "logs", label: "Logs" },
|
|
5431
|
-
{ id: "
|
|
5432
|
-
{ id: "
|
|
5323
|
+
{ id: "tasks", label: "Tasks" },
|
|
5324
|
+
{ id: "projects", label: "Projects" }
|
|
5433
5325
|
];
|
|
5434
|
-
|
|
5435
|
-
baseTabs.splice(3, 0, { id: "indexing", label: "Indexing" });
|
|
5436
|
-
}
|
|
5437
|
-
return baseTabs;
|
|
5438
|
-
}, [isRAGEnabled]);
|
|
5439
|
-
const workspacePath = detectWorkspaceRoot();
|
|
5326
|
+
}, []);
|
|
5440
5327
|
const installStatus = checkInstallStatus(workspacePath);
|
|
5441
5328
|
const installedCount = [
|
|
5442
5329
|
installStatus.antigravity,
|
|
@@ -5487,7 +5374,7 @@ var init_App = __esm({
|
|
|
5487
5374
|
}, 500);
|
|
5488
5375
|
return () => clearInterval(interval);
|
|
5489
5376
|
}, []);
|
|
5490
|
-
|
|
5377
|
+
useInput5(async (input, key) => {
|
|
5491
5378
|
if (input === "q" || key.ctrl && input === "c") {
|
|
5492
5379
|
stopMCPServer();
|
|
5493
5380
|
onExit();
|
|
@@ -5511,10 +5398,10 @@ var init_App = __esm({
|
|
|
5511
5398
|
const handleConfigChange = useCallback3(() => {
|
|
5512
5399
|
refreshData();
|
|
5513
5400
|
}, [refreshData]);
|
|
5514
|
-
return /* @__PURE__ */
|
|
5515
|
-
/* @__PURE__ */
|
|
5516
|
-
/* @__PURE__ */
|
|
5517
|
-
activeTab === "overview" && /* @__PURE__ */
|
|
5401
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", padding: 0, height: termHeight, children: [
|
|
5402
|
+
/* @__PURE__ */ jsx10(TabBar, { tabs, activeTab, onChange: setActiveTab }),
|
|
5403
|
+
/* @__PURE__ */ jsxs8(Box9, { marginTop: 1, flexGrow: 1, children: [
|
|
5404
|
+
activeTab === "overview" && /* @__PURE__ */ jsx10(
|
|
5518
5405
|
Overview,
|
|
5519
5406
|
{
|
|
5520
5407
|
serverStatus: serverInfo,
|
|
@@ -5522,15 +5409,15 @@ var init_App = __esm({
|
|
|
5522
5409
|
exposedProjects: exposedProjects.length,
|
|
5523
5410
|
totalProjects: projects.length,
|
|
5524
5411
|
installedIntegrations: installedCount
|
|
5525
|
-
}
|
|
5412
|
+
},
|
|
5413
|
+
logs
|
|
5526
5414
|
}
|
|
5527
5415
|
),
|
|
5528
|
-
activeTab === "
|
|
5529
|
-
activeTab === "
|
|
5530
|
-
activeTab === "
|
|
5531
|
-
activeTab === "logs" && /* @__PURE__ */ jsx12(LogViewer, { logs, height: contentHeight })
|
|
5416
|
+
activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight }),
|
|
5417
|
+
activeTab === "tasks" && /* @__PURE__ */ jsx10(TasksView, { projects, workspacePath }),
|
|
5418
|
+
activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { config, projects, onConfigChange: handleConfigChange, workspacePath })
|
|
5532
5419
|
] }),
|
|
5533
|
-
/* @__PURE__ */
|
|
5420
|
+
/* @__PURE__ */ jsx10(Box9, { marginTop: 0, children: /* @__PURE__ */ jsx10(
|
|
5534
5421
|
StatusBoard,
|
|
5535
5422
|
{
|
|
5536
5423
|
exposedLabel: `${exposedProjects.length} / ${projects.length} projects`,
|
|
@@ -5548,7 +5435,7 @@ var init_App = __esm({
|
|
|
5548
5435
|
// src/mcp/commands/start.ts
|
|
5549
5436
|
import { confirm as confirm3, isCancel as isCancel5, text } from "@clack/prompts";
|
|
5550
5437
|
async function handleStartServer() {
|
|
5551
|
-
const
|
|
5438
|
+
const React11 = await import("react");
|
|
5552
5439
|
const { render } = await import("ink");
|
|
5553
5440
|
const { App: App2 } = await Promise.resolve().then(() => (init_App(), App_exports));
|
|
5554
5441
|
const { ConfigProvider: ConfigProvider2 } = await Promise.resolve().then(() => (init_ConfigContext(), ConfigContext_exports));
|
|
@@ -5591,10 +5478,10 @@ async function handleStartServer() {
|
|
|
5591
5478
|
}
|
|
5592
5479
|
process.stdin.resume();
|
|
5593
5480
|
const app = render(
|
|
5594
|
-
|
|
5481
|
+
React11.createElement(
|
|
5595
5482
|
ConfigProvider2,
|
|
5596
5483
|
null,
|
|
5597
|
-
|
|
5484
|
+
React11.createElement(App2, {
|
|
5598
5485
|
initialPort,
|
|
5599
5486
|
onExit: () => {
|
|
5600
5487
|
}
|
|
@@ -6407,8 +6294,8 @@ linked_projects:
|
|
|
6407
6294
|
async function registerWithMCP(config, workspacePath, workspaceName) {
|
|
6408
6295
|
if (!config.exposeToMCP) return;
|
|
6409
6296
|
try {
|
|
6410
|
-
const { loadMCPConfig:
|
|
6411
|
-
const mcpConfig =
|
|
6297
|
+
const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6298
|
+
const mcpConfig = loadMCPConfig2();
|
|
6412
6299
|
setProjectConfig2(
|
|
6413
6300
|
mcpConfig,
|
|
6414
6301
|
workspaceName,
|
|
@@ -6801,8 +6688,8 @@ linked_projects:
|
|
|
6801
6688
|
});
|
|
6802
6689
|
if (shouldExpose && !isCancel9(shouldExpose)) {
|
|
6803
6690
|
try {
|
|
6804
|
-
const { loadMCPConfig:
|
|
6805
|
-
const mcpConfig =
|
|
6691
|
+
const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6692
|
+
const mcpConfig = loadMCPConfig2();
|
|
6806
6693
|
for (const project of selectedProjects) {
|
|
6807
6694
|
setProjectConfig2(mcpConfig, project.name, true, void 0, project.dataPath);
|
|
6808
6695
|
}
|