@triedotdev/mcp 1.0.104 → 1.0.106
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/{chunk-M3WF7ZXI.js → chunk-3YDNSKKP.js} +901 -667
- package/dist/chunk-3YDNSKKP.js.map +1 -0
- package/dist/{chunk-HFKOGW7H.js → chunk-C5NK7EGK.js} +2 -2
- package/dist/{chunk-CKYU5JOD.js → chunk-JT2OOIQX.js} +2 -2
- package/dist/{chunk-SPQJC7RA.js → chunk-S2WVHIFG.js} +69 -5
- package/dist/chunk-S2WVHIFG.js.map +1 -0
- package/dist/cli/main.js +2 -2
- package/dist/cli/yolo-daemon.js +3 -3
- package/dist/{guardian-agent-WB6LWRLM.js → guardian-agent-DX4ZQEZ7.js} +3 -3
- package/dist/index.js +19 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-M3WF7ZXI.js.map +0 -1
- package/dist/chunk-SPQJC7RA.js.map +0 -1
- /package/dist/{chunk-HFKOGW7H.js.map → chunk-C5NK7EGK.js.map} +0 -0
- /package/dist/{chunk-CKYU5JOD.js.map → chunk-JT2OOIQX.js.map} +0 -0
- /package/dist/{guardian-agent-WB6LWRLM.js.map → guardian-agent-DX4ZQEZ7.js.map} +0 -0
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGuardian
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C5NK7EGK.js";
|
|
4
4
|
import {
|
|
5
|
+
ContextGraph,
|
|
6
|
+
TieredStorage,
|
|
5
7
|
findCrossProjectPatterns,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
getKeyFromKeychain,
|
|
9
|
+
isAIAvailable,
|
|
10
|
+
runAIAnalysis,
|
|
11
|
+
setAPIKey
|
|
12
|
+
} from "./chunk-S2WVHIFG.js";
|
|
8
13
|
import {
|
|
9
|
-
getGuardianState
|
|
10
|
-
getMemoryStats,
|
|
11
|
-
getRecentIssues
|
|
14
|
+
getGuardianState
|
|
12
15
|
} from "./chunk-6JPPYG7F.js";
|
|
13
16
|
import {
|
|
14
17
|
getTrieDirectory,
|
|
@@ -254,11 +257,11 @@ var StreamingManager = class {
|
|
|
254
257
|
|
|
255
258
|
// src/cli/dashboard/index.ts
|
|
256
259
|
import { render } from "ink";
|
|
257
|
-
import
|
|
260
|
+
import React10 from "react";
|
|
258
261
|
|
|
259
262
|
// src/cli/dashboard/App.tsx
|
|
260
|
-
import { useState as
|
|
261
|
-
import { Box as
|
|
263
|
+
import { useState as useState3, useEffect as useEffect4, useCallback as useCallback6, useRef } from "react";
|
|
264
|
+
import { Box as Box12, useInput as useInput8, useApp } from "ink";
|
|
262
265
|
|
|
263
266
|
// src/cli/dashboard/state.tsx
|
|
264
267
|
import React, { createContext, useContext, useReducer } from "react";
|
|
@@ -273,38 +276,36 @@ function getVisibleInsights(state) {
|
|
|
273
276
|
}
|
|
274
277
|
function getMemoryTreeNodes(state) {
|
|
275
278
|
const nodes = [];
|
|
276
|
-
const { expandedNodes,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
nodes.push({ id: "severity-serious", level: 1 });
|
|
286
|
-
nodes.push({ id: "severity-moderate", level: 1 });
|
|
287
|
-
nodes.push({ id: "severity-low", level: 1 });
|
|
288
|
-
}
|
|
279
|
+
const { expandedNodes, snapshot, globalPatterns } = state.memoryTree;
|
|
280
|
+
if (!snapshot) return nodes;
|
|
281
|
+
const fileNodes = snapshot.nodes.filter((n) => n.type === "file");
|
|
282
|
+
const changeNodes = snapshot.nodes.filter((n) => n.type === "change");
|
|
283
|
+
const patternNodes = snapshot.nodes.filter((n) => n.type === "pattern");
|
|
284
|
+
const incidentNodes = snapshot.nodes.filter((n) => n.type === "incident");
|
|
285
|
+
const decisionNodes = snapshot.nodes.filter((n) => n.type === "decision");
|
|
289
286
|
nodes.push({ id: "files", level: 0 });
|
|
290
287
|
if (expandedNodes.has("files")) {
|
|
291
|
-
|
|
292
|
-
for (const issue of issues) {
|
|
293
|
-
byFile.set(issue.file, (byFile.get(issue.file) || 0) + 1);
|
|
294
|
-
}
|
|
295
|
-
Array.from(byFile.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).forEach(([file]) => nodes.push({ id: `file-${file}`, level: 1 }));
|
|
288
|
+
fileNodes.slice(0, 15).forEach((n) => nodes.push({ id: `file-${n.id}`, level: 1 }));
|
|
296
289
|
}
|
|
297
|
-
nodes.push({ id: "
|
|
298
|
-
if (expandedNodes.has("
|
|
299
|
-
|
|
300
|
-
for (const issue of issues) {
|
|
301
|
-
byAgent.set(issue.agent, (byAgent.get(issue.agent) || 0) + 1);
|
|
302
|
-
}
|
|
303
|
-
Array.from(byAgent.entries()).sort((a, b) => b[1] - a[1]).forEach(([agent]) => nodes.push({ id: `agent-${agent}`, level: 1 }));
|
|
290
|
+
nodes.push({ id: "changes", level: 0 });
|
|
291
|
+
if (expandedNodes.has("changes")) {
|
|
292
|
+
changeNodes.slice(0, 10).forEach((n) => nodes.push({ id: `change-${n.id}`, level: 1 }));
|
|
304
293
|
}
|
|
305
294
|
nodes.push({ id: "patterns", level: 0 });
|
|
306
295
|
if (expandedNodes.has("patterns")) {
|
|
307
|
-
|
|
296
|
+
patternNodes.slice(0, 10).forEach((n) => nodes.push({ id: `pattern-${n.id}`, level: 1 }));
|
|
297
|
+
}
|
|
298
|
+
nodes.push({ id: "incidents", level: 0 });
|
|
299
|
+
if (expandedNodes.has("incidents")) {
|
|
300
|
+
incidentNodes.slice(0, 10).forEach((n) => nodes.push({ id: `incident-${n.id}`, level: 1 }));
|
|
301
|
+
}
|
|
302
|
+
nodes.push({ id: "decisions", level: 0 });
|
|
303
|
+
if (expandedNodes.has("decisions")) {
|
|
304
|
+
decisionNodes.slice(0, 10).forEach((n) => nodes.push({ id: `decision-${n.id}`, level: 1 }));
|
|
305
|
+
}
|
|
306
|
+
nodes.push({ id: "cross-project", level: 0 });
|
|
307
|
+
if (expandedNodes.has("cross-project")) {
|
|
308
|
+
globalPatterns.slice(0, 5).forEach((p) => nodes.push({ id: `global-${p.id}`, level: 1 }));
|
|
308
309
|
}
|
|
309
310
|
return nodes;
|
|
310
311
|
}
|
|
@@ -551,18 +552,41 @@ function dashboardReducer(state, action) {
|
|
|
551
552
|
case "SET_MEMORY_TREE":
|
|
552
553
|
return {
|
|
553
554
|
...state,
|
|
554
|
-
memoryTree: { ...state.memoryTree, loaded: true,
|
|
555
|
+
memoryTree: { ...state.memoryTree, loaded: true, snapshot: action.snapshot, globalPatterns: action.patterns }
|
|
555
556
|
};
|
|
556
557
|
case "SELECT_MEMORY_NODE":
|
|
557
558
|
return { ...state, memoryTree: { ...state.memoryTree, selectedNode: action.nodeId } };
|
|
558
559
|
case "TOGGLE_MEMORY_NODE": {
|
|
559
|
-
const expandable = ["
|
|
560
|
+
const expandable = ["files", "changes", "patterns", "incidents", "decisions", "cross-project"];
|
|
560
561
|
if (!expandable.includes(action.nodeId)) return state;
|
|
561
562
|
const expanded = new Set(state.memoryTree.expandedNodes);
|
|
562
563
|
if (expanded.has(action.nodeId)) expanded.delete(action.nodeId);
|
|
563
564
|
else expanded.add(action.nodeId);
|
|
564
565
|
return { ...state, memoryTree: { ...state.memoryTree, expandedNodes: expanded } };
|
|
565
566
|
}
|
|
567
|
+
case "SET_AGENT_BRAIN":
|
|
568
|
+
return {
|
|
569
|
+
...state,
|
|
570
|
+
agentBrain: {
|
|
571
|
+
...state.agentBrain,
|
|
572
|
+
loaded: true,
|
|
573
|
+
decisions: action.decisions,
|
|
574
|
+
patterns: action.patterns,
|
|
575
|
+
ledgerHash: action.ledgerHash
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
case "SET_CHAT_INPUT":
|
|
579
|
+
return { ...state, chatState: { ...state.chatState, inputBuffer: action.buffer } };
|
|
580
|
+
case "ADD_CHAT_MESSAGE":
|
|
581
|
+
return {
|
|
582
|
+
...state,
|
|
583
|
+
chatState: {
|
|
584
|
+
...state.chatState,
|
|
585
|
+
messages: [...state.chatState.messages, { role: action.role, content: action.content, timestamp: Date.now() }].slice(-20)
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
case "SET_CHAT_LOADING":
|
|
589
|
+
return { ...state, chatState: { ...state.chatState, loading: action.loading } };
|
|
566
590
|
case "SET_AGENT_CONFIG":
|
|
567
591
|
return { ...state, agentConfig: applyAgentConfigPatch(state.agentConfig, action.config) };
|
|
568
592
|
case "NAVIGATE_UP": {
|
|
@@ -663,7 +687,7 @@ function createInitialState() {
|
|
|
663
687
|
watch: { watching: false, directories: 0, recentChanges: [] },
|
|
664
688
|
rawLog: [],
|
|
665
689
|
rawLogPage: 0,
|
|
666
|
-
scrollPositions: { overview: 0, rawlog: 0, agent: 0, goals: 0, hypotheses: 0, memory: 0 },
|
|
690
|
+
scrollPositions: { overview: 0, rawlog: 0, agent: 0, goals: 0, hypotheses: 0, memory: 0, chat: 0 },
|
|
667
691
|
notification: null,
|
|
668
692
|
notificationHistory: [],
|
|
669
693
|
agentInsights: [],
|
|
@@ -683,7 +707,9 @@ function createInitialState() {
|
|
|
683
707
|
},
|
|
684
708
|
goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
685
709
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
686
|
-
memoryTree: { loaded: false,
|
|
710
|
+
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], expandedNodes: /* @__PURE__ */ new Set(["files"]), selectedNode: "files", scrollPosition: 0, lastRefresh: 0 },
|
|
711
|
+
agentBrain: { loaded: false, decisions: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
|
|
712
|
+
chatState: { messages: [], inputBuffer: "", loading: false }
|
|
687
713
|
};
|
|
688
714
|
}
|
|
689
715
|
var DashboardContext = createContext(null);
|
|
@@ -1254,32 +1280,49 @@ import { readFile, writeFile, mkdir } from "fs/promises";
|
|
|
1254
1280
|
import { join } from "path";
|
|
1255
1281
|
|
|
1256
1282
|
// src/cli/dashboard/components/Header.tsx
|
|
1283
|
+
import { useState, useEffect } from "react";
|
|
1257
1284
|
import { Box, Text } from "ink";
|
|
1258
1285
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
1286
|
+
var WATCH_FRAMES = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
1259
1287
|
function Header() {
|
|
1260
1288
|
const { state } = useDashboard();
|
|
1261
|
-
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
1262
1289
|
const { signalExtraction, watch, alerts } = state;
|
|
1263
1290
|
const totalExtracted = signalExtraction.decisionsExtracted + signalExtraction.factsExtracted + signalExtraction.blockersExtracted + signalExtraction.questionsExtracted;
|
|
1291
|
+
const [frame, setFrame] = useState(0);
|
|
1292
|
+
useEffect(() => {
|
|
1293
|
+
if (!watch.watching) return;
|
|
1294
|
+
const id = setInterval(() => setFrame((f) => (f + 1) % WATCH_FRAMES.length), 150);
|
|
1295
|
+
return () => clearInterval(id);
|
|
1296
|
+
}, [watch.watching]);
|
|
1264
1297
|
let statusLabel;
|
|
1265
1298
|
if (watch.watching) {
|
|
1299
|
+
const spinner = WATCH_FRAMES[frame] || "\u25D0";
|
|
1266
1300
|
statusLabel = totalExtracted > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
1267
|
-
/* @__PURE__ */ jsx2(Text, { color: "green",
|
|
1301
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", children: spinner }),
|
|
1302
|
+
" ",
|
|
1303
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", bold: true, children: "Learning" }),
|
|
1268
1304
|
" ",
|
|
1269
1305
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1270
1306
|
totalExtracted,
|
|
1271
1307
|
" signals"
|
|
1272
1308
|
] })
|
|
1273
|
-
] }) : /* @__PURE__ */
|
|
1309
|
+
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
1310
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", children: spinner }),
|
|
1311
|
+
" ",
|
|
1312
|
+
/* @__PURE__ */ jsx2(Text, { bold: true, children: "Watching" })
|
|
1313
|
+
] });
|
|
1274
1314
|
} else {
|
|
1275
|
-
statusLabel = /* @__PURE__ */
|
|
1315
|
+
statusLabel = /* @__PURE__ */ jsxs(Text, { children: [
|
|
1316
|
+
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "\u25CB" }),
|
|
1317
|
+
" ",
|
|
1318
|
+
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "Idle" })
|
|
1319
|
+
] });
|
|
1276
1320
|
}
|
|
1277
|
-
return /* @__PURE__ */ jsxs(Box, {
|
|
1278
|
-
/* @__PURE__ */ jsx2(
|
|
1321
|
+
return /* @__PURE__ */ jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [
|
|
1322
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", bold: true, children: "trie" }),
|
|
1279
1323
|
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
1280
1324
|
statusLabel,
|
|
1281
|
-
alerts.hasCritical && /* @__PURE__ */ jsx2(Text, { color: "red", bold: true, children: "\
|
|
1282
|
-
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: time })
|
|
1325
|
+
alerts.hasCritical && /* @__PURE__ */ jsx2(Text, { color: "red", bold: true, children: "\u25CF Alert" })
|
|
1283
1326
|
] })
|
|
1284
1327
|
] });
|
|
1285
1328
|
}
|
|
@@ -1293,84 +1336,39 @@ var VIEW_LABELS = {
|
|
|
1293
1336
|
agent: "Agent",
|
|
1294
1337
|
goals: "Goals",
|
|
1295
1338
|
hypotheses: "Hypotheses",
|
|
1296
|
-
memory: "Memory"
|
|
1339
|
+
memory: "Memory",
|
|
1340
|
+
chat: "Chat"
|
|
1297
1341
|
};
|
|
1298
|
-
|
|
1299
|
-
return /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
1300
|
-
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "[" }),
|
|
1301
|
-
/* @__PURE__ */ jsx3(Text2, { bold: true, children: k }),
|
|
1302
|
-
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "]" }),
|
|
1303
|
-
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
1304
|
-
" ",
|
|
1305
|
-
label
|
|
1306
|
-
] })
|
|
1307
|
-
] });
|
|
1308
|
-
}
|
|
1342
|
+
var TAB_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
1309
1343
|
function Footer() {
|
|
1310
1344
|
const { state } = useDashboard();
|
|
1311
1345
|
const { view } = state;
|
|
1312
|
-
|
|
1313
|
-
const isActive = v === view;
|
|
1314
|
-
const label = VIEW_LABELS[v];
|
|
1315
|
-
return isActive ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: ` ${label} ` }, v) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: ` ${label} ` }, v);
|
|
1316
|
-
});
|
|
1317
|
-
let hints;
|
|
1346
|
+
let contextHints;
|
|
1318
1347
|
if (view === "goals" && state.goalsPanel.inputMode === "add") {
|
|
1319
|
-
|
|
1320
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Enter", label: "Save" }),
|
|
1321
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Esc", label: "Cancel" })
|
|
1322
|
-
] });
|
|
1348
|
+
contextHints = "enter save \xB7 esc cancel";
|
|
1323
1349
|
} else if (view === "hypotheses" && state.hypothesesPanel.inputMode === "add") {
|
|
1324
|
-
|
|
1325
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Enter", label: "Save" }),
|
|
1326
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Esc", label: "Cancel" })
|
|
1327
|
-
] });
|
|
1350
|
+
contextHints = "enter save \xB7 esc cancel";
|
|
1328
1351
|
} else if (view === "goals") {
|
|
1329
|
-
|
|
1330
|
-
/* @__PURE__ */ jsx3(Hint, { k: "j/k", label: "Nav" }),
|
|
1331
|
-
/* @__PURE__ */ jsx3(Hint, { k: "a", label: "Add" }),
|
|
1332
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Enter", label: "Complete" }),
|
|
1333
|
-
/* @__PURE__ */ jsx3(Hint, { k: "d", label: "Delete" })
|
|
1334
|
-
] });
|
|
1352
|
+
contextHints = "j/k nav \xB7 a add \xB7 enter complete \xB7 d delete";
|
|
1335
1353
|
} else if (view === "hypotheses") {
|
|
1336
|
-
|
|
1337
|
-
/* @__PURE__ */ jsx3(Hint, { k: "j/k", label: "Nav" }),
|
|
1338
|
-
/* @__PURE__ */ jsx3(Hint, { k: "a", label: "Add" }),
|
|
1339
|
-
/* @__PURE__ */ jsx3(Hint, { k: "v", label: "Validate" }),
|
|
1340
|
-
/* @__PURE__ */ jsx3(Hint, { k: "x", label: "Invalidate" })
|
|
1341
|
-
] });
|
|
1354
|
+
contextHints = "j/k nav \xB7 a add \xB7 v validate \xB7 x invalidate";
|
|
1342
1355
|
} else if (view === "agent") {
|
|
1343
|
-
|
|
1344
|
-
/* @__PURE__ */ jsx3(Hint, { k: "j/k", label: "Nav" }),
|
|
1345
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Enter", label: "Expand" }),
|
|
1346
|
-
/* @__PURE__ */ jsx3(Hint, { k: "d", label: "Dismiss" }),
|
|
1347
|
-
/* @__PURE__ */ jsx3(Hint, { k: "i", label: "Ignore" }),
|
|
1348
|
-
/* @__PURE__ */ jsx3(Hint, { k: "x", label: "Clear" })
|
|
1349
|
-
] });
|
|
1356
|
+
contextHints = "j/k nav \xB7 enter expand \xB7 d dismiss";
|
|
1350
1357
|
} else if (view === "memory") {
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
/* @__PURE__ */ jsx3(Hint, { k: "b", label: "Back" })
|
|
1355
|
-
] });
|
|
1358
|
+
contextHints = "j/k nav \xB7 enter expand";
|
|
1359
|
+
} else if (view === "chat") {
|
|
1360
|
+
contextHints = "type to ask \xB7 enter send \xB7 esc clear";
|
|
1356
1361
|
} else if (view === "rawlog") {
|
|
1357
|
-
|
|
1358
|
-
/* @__PURE__ */ jsx3(Hint, { k: "n/p", label: "Pages" }),
|
|
1359
|
-
/* @__PURE__ */ jsx3(Hint, { k: "b", label: "Back" })
|
|
1360
|
-
] });
|
|
1362
|
+
contextHints = "n/p pages \xB7 b back";
|
|
1361
1363
|
} else {
|
|
1362
|
-
|
|
1363
|
-
/* @__PURE__ */ jsx3(Hint, { k: "Tab", label: "Views" }),
|
|
1364
|
-
/* @__PURE__ */ jsx3(Hint, { k: "n/p", label: "Pages" }),
|
|
1365
|
-
/* @__PURE__ */ jsx3(Hint, { k: "h", label: "Help" })
|
|
1366
|
-
] });
|
|
1364
|
+
contextHints = "n/p pages \xB7 c config";
|
|
1367
1365
|
}
|
|
1368
|
-
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
1369
|
-
/* @__PURE__ */
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1366
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
|
|
1367
|
+
/* @__PURE__ */ jsxs2(Box2, { justifyContent: "space-between", children: [
|
|
1368
|
+
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => v === view ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: VIEW_LABELS[v] }, v) : /* @__PURE__ */ jsx3(Text2, { children: VIEW_LABELS[v] }, v)) }),
|
|
1369
|
+
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "q quit" })
|
|
1370
|
+
] }),
|
|
1371
|
+
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: contextHints })
|
|
1374
1372
|
] });
|
|
1375
1373
|
}
|
|
1376
1374
|
|
|
@@ -1395,21 +1393,31 @@ function Notification() {
|
|
|
1395
1393
|
}
|
|
1396
1394
|
|
|
1397
1395
|
// src/cli/dashboard/components/ConfigDialog.tsx
|
|
1398
|
-
import { useState } from "react";
|
|
1396
|
+
import { useState as useState2 } from "react";
|
|
1399
1397
|
import { Box as Box4, Text as Text4, useInput } from "ink";
|
|
1400
|
-
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1398
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1399
|
+
function maskKey(key) {
|
|
1400
|
+
if (!key || key.length < 12) return "Not set";
|
|
1401
|
+
return key.slice(0, 7) + "..." + key.slice(-4);
|
|
1402
|
+
}
|
|
1401
1403
|
function ConfigDialog({ onClose }) {
|
|
1402
1404
|
const { state, dispatch } = useDashboard();
|
|
1403
|
-
const [section, setSection] =
|
|
1404
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1405
|
-
const [editing, setEditing] =
|
|
1406
|
-
const [editBuffer, setEditBuffer] =
|
|
1405
|
+
const [section, setSection] = useState2("main");
|
|
1406
|
+
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
1407
|
+
const [editing, setEditing] = useState2(false);
|
|
1408
|
+
const [editBuffer, setEditBuffer] = useState2("");
|
|
1409
|
+
const [editIsText, setEditIsText] = useState2(false);
|
|
1407
1410
|
const config = state.agentConfig;
|
|
1411
|
+
const currentKeyDisplay = isAIAvailable() ? maskKey(getKeyFromKeychain() || process.env.ANTHROPIC_API_KEY || null) : "Not set";
|
|
1412
|
+
const keyActive = isAIAvailable();
|
|
1408
1413
|
const mainMenu = [
|
|
1409
|
-
{ label: "
|
|
1414
|
+
{ label: "API Keys", key: "apiKeys", value: keyActive ? "Active" : "Not set", section: "main" },
|
|
1410
1415
|
{ label: "Performance Settings", key: "performance", value: `${config.performance.maxConcurrency} concurrent`, section: "main" },
|
|
1411
1416
|
{ label: "Risk Thresholds", key: "riskThresholds", value: `critical: ${config.riskThresholds.critical}%`, section: "main" }
|
|
1412
1417
|
];
|
|
1418
|
+
const apiKeysItems = [
|
|
1419
|
+
{ label: "Anthropic", key: "anthropic", value: currentKeyDisplay, section: "apiKeys" }
|
|
1420
|
+
];
|
|
1413
1421
|
const performanceItems = [
|
|
1414
1422
|
{ label: "Max Concurrency", key: "maxConcurrency", value: String(config.performance.maxConcurrency), section: "performance" },
|
|
1415
1423
|
{ label: "Timeout (ms)", key: "timeoutMs", value: String(config.performance.timeoutMs), section: "performance" },
|
|
@@ -1422,37 +1430,50 @@ function ConfigDialog({ onClose }) {
|
|
|
1422
1430
|
{ label: "High Threshold", key: "high", value: String(config.riskThresholds.high), section: "riskThresholds" },
|
|
1423
1431
|
{ label: "Medium Threshold", key: "medium", value: String(config.riskThresholds.medium), section: "riskThresholds" }
|
|
1424
1432
|
];
|
|
1425
|
-
const items = section === "main" ? mainMenu : section === "performance" ? performanceItems : section === "riskThresholds" ? riskItems : mainMenu;
|
|
1433
|
+
const items = section === "main" ? mainMenu : section === "apiKeys" ? apiKeysItems : section === "performance" ? performanceItems : section === "riskThresholds" ? riskItems : mainMenu;
|
|
1426
1434
|
useInput((_input, key) => {
|
|
1427
1435
|
if (editing) {
|
|
1428
1436
|
if (key.escape) {
|
|
1429
1437
|
setEditing(false);
|
|
1430
1438
|
setEditBuffer("");
|
|
1439
|
+
setEditIsText(false);
|
|
1431
1440
|
} else if (key.return) {
|
|
1432
1441
|
const item = items[selectedIndex];
|
|
1433
1442
|
if (item) {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
if (item.key === "maxConcurrency" || item.key === "timeoutMs") {
|
|
1439
|
-
patch.performance = { ...config.performance, [item.key]: val };
|
|
1440
|
-
}
|
|
1441
|
-
} else if (section === "riskThresholds") {
|
|
1442
|
-
patch.riskThresholds = { ...config.riskThresholds, [item.key]: val };
|
|
1443
|
+
if (editIsText) {
|
|
1444
|
+
if (item.key === "anthropic" && editBuffer.length > 10) {
|
|
1445
|
+
setAPIKey(editBuffer);
|
|
1446
|
+
dispatch({ type: "ADD_ACTIVITY", message: "API key saved" });
|
|
1443
1447
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1448
|
+
} else {
|
|
1449
|
+
const val = parseInt(editBuffer, 10);
|
|
1450
|
+
if (!isNaN(val)) {
|
|
1451
|
+
const patch = {};
|
|
1452
|
+
if (section === "performance") {
|
|
1453
|
+
if (item.key === "maxConcurrency" || item.key === "timeoutMs") {
|
|
1454
|
+
patch.performance = { ...config.performance, [item.key]: val };
|
|
1455
|
+
}
|
|
1456
|
+
} else if (section === "riskThresholds") {
|
|
1457
|
+
patch.riskThresholds = { ...config.riskThresholds, [item.key]: val };
|
|
1458
|
+
}
|
|
1459
|
+
if (Object.keys(patch).length > 0) {
|
|
1460
|
+
dispatch({ type: "SET_AGENT_CONFIG", config: patch });
|
|
1461
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Config: ${item.label} set to ${val}` });
|
|
1462
|
+
}
|
|
1447
1463
|
}
|
|
1448
1464
|
}
|
|
1449
1465
|
}
|
|
1450
1466
|
setEditing(false);
|
|
1451
1467
|
setEditBuffer("");
|
|
1468
|
+
setEditIsText(false);
|
|
1452
1469
|
} else if (key.backspace || key.delete) {
|
|
1453
1470
|
setEditBuffer(editBuffer.slice(0, -1));
|
|
1454
|
-
} else if (_input
|
|
1455
|
-
|
|
1471
|
+
} else if (_input) {
|
|
1472
|
+
if (editIsText) {
|
|
1473
|
+
setEditBuffer(editBuffer + _input);
|
|
1474
|
+
} else if (/\d/.test(_input)) {
|
|
1475
|
+
setEditBuffer(editBuffer + _input);
|
|
1476
|
+
}
|
|
1456
1477
|
}
|
|
1457
1478
|
return;
|
|
1458
1479
|
}
|
|
@@ -1473,6 +1494,10 @@ function ConfigDialog({ onClose }) {
|
|
|
1473
1494
|
setSection(item.key);
|
|
1474
1495
|
setSelectedIndex(0);
|
|
1475
1496
|
}
|
|
1497
|
+
} else if (section === "apiKeys") {
|
|
1498
|
+
setEditing(true);
|
|
1499
|
+
setEditBuffer("");
|
|
1500
|
+
setEditIsText(true);
|
|
1476
1501
|
} else {
|
|
1477
1502
|
const item = items[selectedIndex];
|
|
1478
1503
|
if (item) {
|
|
@@ -1489,32 +1514,60 @@ function ConfigDialog({ onClose }) {
|
|
|
1489
1514
|
}
|
|
1490
1515
|
}
|
|
1491
1516
|
});
|
|
1492
|
-
const sectionTitle = section === "main" ? "TRIE
|
|
1517
|
+
const sectionTitle = section === "main" ? "TRIE CONFIGURATION" : section === "apiKeys" ? "API KEYS" : section === "performance" ? "PERFORMANCE SETTINGS" : section === "riskThresholds" ? "RISK THRESHOLDS" : "CONFIGURATION";
|
|
1493
1518
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, paddingY: 0, children: [
|
|
1494
1519
|
/* @__PURE__ */ jsx5(Text4, { bold: true, children: sectionTitle }),
|
|
1495
1520
|
/* @__PURE__ */ jsx5(Text4, { children: " " }),
|
|
1496
|
-
|
|
1521
|
+
section === "apiKeys" && !editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
1522
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1523
|
+
" ",
|
|
1524
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, children: "Anthropic:" }),
|
|
1525
|
+
" ",
|
|
1526
|
+
/* @__PURE__ */ jsx5(Text4, { children: currentKeyDisplay }),
|
|
1527
|
+
" ",
|
|
1528
|
+
keyActive ? /* @__PURE__ */ jsx5(Text4, { color: "green", children: "\u25CF Active" }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "\u25CB Not set" })
|
|
1529
|
+
] }),
|
|
1530
|
+
/* @__PURE__ */ jsx5(Text4, { children: " " }),
|
|
1531
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to update esc back" })
|
|
1532
|
+
] }),
|
|
1533
|
+
section === "apiKeys" && editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
1534
|
+
/* @__PURE__ */ jsx5(Box4, { borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1535
|
+
editBuffer || /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "sk-ant-..." }),
|
|
1536
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "|" })
|
|
1537
|
+
] }) }),
|
|
1538
|
+
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
1539
|
+
" enter save (",
|
|
1540
|
+
process.platform === "darwin" ? "keychain" : "config",
|
|
1541
|
+
") esc cancel"
|
|
1542
|
+
] })
|
|
1543
|
+
] }),
|
|
1544
|
+
section !== "apiKeys" && items.map((item, idx) => {
|
|
1497
1545
|
const isSelected = selectedIndex === idx;
|
|
1498
1546
|
return /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1499
|
-
isSelected ? /* @__PURE__ */
|
|
1547
|
+
isSelected ? /* @__PURE__ */ jsxs4(Text4, { bold: true, color: "green", children: [
|
|
1548
|
+
">",
|
|
1549
|
+
" "
|
|
1550
|
+
] }) : /* @__PURE__ */ jsx5(Text4, { children: " " }),
|
|
1500
1551
|
/* @__PURE__ */ jsxs4(Text4, { bold: isSelected, children: [
|
|
1501
1552
|
item.label,
|
|
1502
1553
|
": "
|
|
1503
1554
|
] }),
|
|
1504
1555
|
editing && isSelected ? /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1505
1556
|
editBuffer,
|
|
1506
|
-
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "
|
|
1557
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "|" })
|
|
1507
1558
|
] }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: item.value })
|
|
1508
1559
|
] }, item.key);
|
|
1509
1560
|
}),
|
|
1510
|
-
/* @__PURE__ */
|
|
1511
|
-
|
|
1561
|
+
section !== "apiKeys" && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1562
|
+
/* @__PURE__ */ jsx5(Text4, { children: " " }),
|
|
1563
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: section === "main" ? "enter select \xB7 esc close" : "enter edit \xB7 esc/b back" })
|
|
1564
|
+
] })
|
|
1512
1565
|
] });
|
|
1513
1566
|
}
|
|
1514
1567
|
|
|
1515
1568
|
// src/cli/dashboard/views/OverviewView.tsx
|
|
1516
1569
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
1517
|
-
import {
|
|
1570
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1518
1571
|
function OverviewView() {
|
|
1519
1572
|
const { state } = useDashboard();
|
|
1520
1573
|
const { progress, signalExtraction, watch, issues, activityLog, activityPage } = state;
|
|
@@ -1527,92 +1580,75 @@ function OverviewView() {
|
|
|
1527
1580
|
const pageActivities = activityLog.slice(startIdx, startIdx + activityRows);
|
|
1528
1581
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, children: [
|
|
1529
1582
|
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1583
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u25CF" }),
|
|
1584
|
+
" Scanned ",
|
|
1530
1585
|
/* @__PURE__ */ jsx6(Text5, { bold: true, children: processedFiles }),
|
|
1586
|
+
" files ",
|
|
1531
1587
|
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1532
|
-
" files scanned in ",
|
|
1533
1588
|
elapsed,
|
|
1534
1589
|
"s"
|
|
1535
1590
|
] })
|
|
1536
1591
|
] }),
|
|
1537
|
-
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs5(
|
|
1538
|
-
/* @__PURE__ */
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
/* @__PURE__ */
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
/* @__PURE__ */ jsx6(Text5, {
|
|
1546
|
-
|
|
1547
|
-
/* @__PURE__ */
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
/* @__PURE__ */
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " facts" })
|
|
1556
|
-
] }),
|
|
1557
|
-
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1558
|
-
" ",
|
|
1559
|
-
/* @__PURE__ */ jsx6(Text5, { bold: true, children: signalExtraction.blockersExtracted }),
|
|
1560
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " blockers" })
|
|
1561
|
-
] }),
|
|
1562
|
-
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1563
|
-
" ",
|
|
1564
|
-
/* @__PURE__ */ jsx6(Text5, { bold: true, children: signalExtraction.questionsExtracted }),
|
|
1565
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " questions" })
|
|
1566
|
-
] }),
|
|
1567
|
-
/* @__PURE__ */ jsx6(Text5, { children: " " }),
|
|
1568
|
-
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1569
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "Use " }),
|
|
1570
|
-
/* @__PURE__ */ jsx6(Text5, { bold: true, children: "trie gotcha" }),
|
|
1571
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " to query the ledger" })
|
|
1572
|
-
] })
|
|
1592
|
+
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
1593
|
+
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1594
|
+
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CF" }),
|
|
1595
|
+
" Signal extraction ",
|
|
1596
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "enabled" })
|
|
1597
|
+
] }),
|
|
1598
|
+
(signalExtraction.decisionsExtracted > 0 || signalExtraction.factsExtracted > 0 || signalExtraction.blockersExtracted > 0) && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1599
|
+
" ",
|
|
1600
|
+
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CB" }),
|
|
1601
|
+
" ",
|
|
1602
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: signalExtraction.decisionsExtracted }),
|
|
1603
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " decisions" }),
|
|
1604
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \xB7 " }),
|
|
1605
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: signalExtraction.factsExtracted }),
|
|
1606
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " facts" }),
|
|
1607
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \xB7 " }),
|
|
1608
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: signalExtraction.blockersExtracted }),
|
|
1609
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " blockers" })
|
|
1573
1610
|
] })
|
|
1574
1611
|
] }),
|
|
1575
|
-
criticalIssues.length > 0 && /* @__PURE__ */ jsxs5(
|
|
1612
|
+
criticalIssues.length > 0 && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
1576
1613
|
/* @__PURE__ */ jsx6(Text5, { children: " " }),
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
lineNum
|
|
1593
|
-
] })
|
|
1594
|
-
] }, i);
|
|
1595
|
-
})
|
|
1596
|
-
] })
|
|
1614
|
+
criticalIssues.map((issue, i) => {
|
|
1615
|
+
const filename = issue.file.split("/").pop() || issue.file;
|
|
1616
|
+
const lineNum = issue.line ? `:${issue.line}` : "";
|
|
1617
|
+
const desc = issue.issue.slice(0, 50) + (issue.issue.length > 50 ? "..." : "");
|
|
1618
|
+
return /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1619
|
+
/* @__PURE__ */ jsx6(Text5, { color: "red", children: "\u25CF" }),
|
|
1620
|
+
" ",
|
|
1621
|
+
/* @__PURE__ */ jsx6(Text5, { color: "red", children: desc }),
|
|
1622
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1623
|
+
" ",
|
|
1624
|
+
filename,
|
|
1625
|
+
lineNum
|
|
1626
|
+
] })
|
|
1627
|
+
] }, i);
|
|
1628
|
+
})
|
|
1597
1629
|
] }),
|
|
1598
|
-
totalIssues === 0 && criticalIssues.length === 0 && /* @__PURE__ */ jsxs5(
|
|
1599
|
-
/* @__PURE__ */ jsx6(Text5, {
|
|
1600
|
-
|
|
1630
|
+
totalIssues === 0 && criticalIssues.length === 0 && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1631
|
+
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CF" }),
|
|
1632
|
+
" No issues found"
|
|
1601
1633
|
] }),
|
|
1602
1634
|
/* @__PURE__ */ jsx6(Text5, { children: " " }),
|
|
1603
1635
|
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
1604
1636
|
/* @__PURE__ */ jsx6(Text5, { bold: true, children: "Activity" }),
|
|
1605
1637
|
pageActivities.map((entry, i) => /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1606
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: entry.time }),
|
|
1607
1638
|
" ",
|
|
1608
|
-
|
|
1639
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u25CF" }),
|
|
1640
|
+
" ",
|
|
1641
|
+
entry.message,
|
|
1642
|
+
" ",
|
|
1643
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: entry.time })
|
|
1609
1644
|
] }, i)),
|
|
1610
|
-
pageActivities.length === 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "No activity yet." })
|
|
1645
|
+
pageActivities.length === 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " No activity yet." })
|
|
1611
1646
|
] })
|
|
1612
1647
|
] });
|
|
1613
1648
|
}
|
|
1614
1649
|
|
|
1615
1650
|
// src/cli/dashboard/views/AgentView.tsx
|
|
1651
|
+
import { useEffect as useEffect2, useCallback } from "react";
|
|
1616
1652
|
import { Box as Box6, Text as Text6, useInput as useInput2 } from "ink";
|
|
1617
1653
|
|
|
1618
1654
|
// src/cli/dashboard/theme.ts
|
|
@@ -1643,41 +1679,50 @@ function formatTimeAgo(timestamp) {
|
|
|
1643
1679
|
const hours = Math.floor(minutes / 60);
|
|
1644
1680
|
return `${hours}h ago`;
|
|
1645
1681
|
}
|
|
1646
|
-
function insightIcon(type) {
|
|
1647
|
-
switch (type) {
|
|
1648
|
-
case "warning":
|
|
1649
|
-
return { icon: "[!]", color: colors.critical };
|
|
1650
|
-
case "observation":
|
|
1651
|
-
return { icon: "[>]", color: colors.serious };
|
|
1652
|
-
case "suggestion":
|
|
1653
|
-
return { icon: "[?]", color: colors.highlight };
|
|
1654
|
-
case "celebration":
|
|
1655
|
-
return { icon: "[+]", color: colors.success };
|
|
1656
|
-
case "question":
|
|
1657
|
-
return { icon: "[?]", color: colors.moderate };
|
|
1658
|
-
default:
|
|
1659
|
-
return { icon: "[>]", color: colors.dim };
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
1682
|
function progressBar(current, total, width = 10) {
|
|
1663
|
-
if (total <= 0) return colors.dim("
|
|
1683
|
+
if (total <= 0) return colors.dim("\u2591".repeat(width));
|
|
1664
1684
|
const progress = Math.min(1, current / total);
|
|
1665
1685
|
const filled = Math.round(width * progress);
|
|
1666
1686
|
const empty = width - filled;
|
|
1667
|
-
return colors.
|
|
1668
|
-
}
|
|
1669
|
-
function stripEmojis(s) {
|
|
1670
|
-
return s.replace(/[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{FE00}-\u{FE0F}\u{200D}\u{20E3}\u{FE0F}\u{E0020}-\u{E007F}]/gu, "").trim();
|
|
1687
|
+
return colors.success("\u2588".repeat(filled)) + colors.dim("\u2591".repeat(empty));
|
|
1671
1688
|
}
|
|
1672
1689
|
|
|
1673
1690
|
// src/cli/dashboard/views/AgentView.tsx
|
|
1674
1691
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1692
|
+
function timeAgo(iso) {
|
|
1693
|
+
const ms = Date.now() - new Date(iso).getTime();
|
|
1694
|
+
const mins = Math.floor(ms / 6e4);
|
|
1695
|
+
if (mins < 60) return `${mins}m ago`;
|
|
1696
|
+
const hrs = Math.floor(mins / 60);
|
|
1697
|
+
if (hrs < 24) return `${hrs}h ago`;
|
|
1698
|
+
return `${Math.floor(hrs / 24)}d ago`;
|
|
1699
|
+
}
|
|
1675
1700
|
function AgentView() {
|
|
1676
1701
|
const { state, dispatch } = useDashboard();
|
|
1677
|
-
const { agentInsights,
|
|
1678
|
-
const totalInsights = agentInsights.length;
|
|
1702
|
+
const { agentInsights, agentBrain, selectedInsight, expandedInsight } = state;
|
|
1679
1703
|
const visibleInsights = getVisibleInsights(state);
|
|
1680
|
-
const
|
|
1704
|
+
const alerts = visibleInsights.filter((i) => i.type === "warning");
|
|
1705
|
+
const { decisions, patterns, loaded } = agentBrain;
|
|
1706
|
+
const loadBrain = useCallback(async () => {
|
|
1707
|
+
try {
|
|
1708
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1709
|
+
const storage = new TieredStorage(workDir);
|
|
1710
|
+
const graph = new ContextGraph(workDir);
|
|
1711
|
+
const [decs, snap] = await Promise.all([
|
|
1712
|
+
storage.queryDecisions({ limit: 20 }),
|
|
1713
|
+
graph.getSnapshot()
|
|
1714
|
+
]);
|
|
1715
|
+
const patternData = snap.nodes.filter((n) => n.type === "pattern").map((n) => n.data);
|
|
1716
|
+
dispatch({ type: "SET_AGENT_BRAIN", decisions: decs, patterns: patternData, ledgerHash: null });
|
|
1717
|
+
} catch {
|
|
1718
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Agent brain load error" });
|
|
1719
|
+
}
|
|
1720
|
+
}, [dispatch]);
|
|
1721
|
+
useEffect2(() => {
|
|
1722
|
+
if (!loaded) {
|
|
1723
|
+
void loadBrain();
|
|
1724
|
+
}
|
|
1725
|
+
}, [loaded, loadBrain]);
|
|
1681
1726
|
useInput2((input, key) => {
|
|
1682
1727
|
if (key.upArrow || input === "k") {
|
|
1683
1728
|
dispatch({ type: "NAVIGATE_UP" });
|
|
@@ -1687,186 +1732,190 @@ function AgentView() {
|
|
|
1687
1732
|
dispatch({ type: "TOGGLE_INSIGHT", index: selectedInsight });
|
|
1688
1733
|
} else if (input === "d") {
|
|
1689
1734
|
dispatch({ type: "DISMISS_INSIGHT", index: selectedInsight });
|
|
1690
|
-
} else if (input === "i") {
|
|
1691
|
-
dispatch({ type: "IGNORE_INSIGHT", index: selectedInsight });
|
|
1692
|
-
} else if (input === "x") {
|
|
1693
|
-
dispatch({ type: "CLEAR_DISMISSED_INSIGHTS" });
|
|
1694
1735
|
}
|
|
1695
1736
|
});
|
|
1696
|
-
const
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
] }),
|
|
1737
|
+
const alertCount = alerts.length;
|
|
1738
|
+
const decCount = decisions.length;
|
|
1739
|
+
const patCount = patterns.length;
|
|
1740
|
+
if (alertCount === 0 && decCount === 0 && patCount === 0 && !loaded) {
|
|
1741
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
|
|
1742
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Trie" }),
|
|
1743
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " Loading..." })
|
|
1744
|
+
] });
|
|
1745
|
+
}
|
|
1746
|
+
if (alertCount === 0 && decCount === 0 && patCount === 0) {
|
|
1747
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
|
|
1748
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Trie" }),
|
|
1709
1749
|
" ",
|
|
1710
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "
|
|
1711
|
-
|
|
1712
|
-
agency && /* @__PURE__ */ jsxs6(Box6, { gap: 2, children: [
|
|
1750
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "Proactive code guardian" }),
|
|
1751
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1713
1752
|
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1714
|
-
|
|
1715
|
-
" ",
|
|
1716
|
-
|
|
1717
|
-
"/",
|
|
1718
|
-
agency.goals.completed + agency.goals.active
|
|
1753
|
+
" ",
|
|
1754
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1755
|
+
" Alerts you about gotchas before you push"
|
|
1719
1756
|
] }),
|
|
1720
1757
|
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1721
|
-
|
|
1722
|
-
" ",
|
|
1723
|
-
|
|
1724
|
-
" testing"
|
|
1758
|
+
" ",
|
|
1759
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1760
|
+
" Records decisions with traceable hashes"
|
|
1725
1761
|
] }),
|
|
1726
1762
|
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1727
|
-
|
|
1728
|
-
" ",
|
|
1729
|
-
|
|
1763
|
+
" ",
|
|
1764
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1765
|
+
" Learns patterns from your feedback (trie ok / trie bad)"
|
|
1730
1766
|
] }),
|
|
1731
1767
|
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1732
|
-
|
|
1733
|
-
" ",
|
|
1734
|
-
|
|
1735
|
-
agency.effectiveness,
|
|
1736
|
-
"%"
|
|
1737
|
-
] })
|
|
1768
|
+
" ",
|
|
1769
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1770
|
+
" Gets smarter over time"
|
|
1738
1771
|
] }),
|
|
1739
|
-
agency.isQuietHours && /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "[quiet]" })
|
|
1740
|
-
] }),
|
|
1741
|
-
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1742
|
-
visibleInsights.length === 0 && state.notificationHistory.length === 0 ? /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1743
|
-
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "The Trie Agent is watching over your code." }),
|
|
1744
|
-
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1745
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "Unlike a log viewer, the Trie Agent:" }),
|
|
1746
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " \u2022 Synthesizes insights from all skills" }),
|
|
1747
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " \u2022 Speaks conversationally about what matters" }),
|
|
1748
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " \u2022 Suggests specific actions to take" }),
|
|
1749
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " \u2022 Celebrates when you fix issues" }),
|
|
1750
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " \u2022 Tracks patterns over time" }),
|
|
1751
1772
|
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1752
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "
|
|
1773
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " Start watching to get proactive alerts," }),
|
|
1774
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " or run trie tell / trie ok / trie bad to teach it." }),
|
|
1753
1775
|
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1754
1776
|
isAIAvailable() ? /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1755
|
-
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "
|
|
1756
|
-
|
|
1777
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1778
|
+
" ",
|
|
1779
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "AI-enhanced analysis enabled" })
|
|
1757
1780
|
] }) : /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1758
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "
|
|
1781
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1782
|
+
" Set ",
|
|
1759
1783
|
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "ANTHROPIC_API_KEY" }),
|
|
1760
|
-
|
|
1784
|
+
" ",
|
|
1785
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "for AI insights" })
|
|
1761
1786
|
] })
|
|
1762
|
-
] })
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1787
|
+
] });
|
|
1788
|
+
}
|
|
1789
|
+
const confidentPatterns = patterns.filter((p) => p.confidence > 0.7).length;
|
|
1790
|
+
const learningPatterns = patterns.filter((p) => p.confidence <= 0.7).length;
|
|
1791
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
|
|
1792
|
+
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1793
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Trie" }),
|
|
1794
|
+
" ",
|
|
1795
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1796
|
+
alertCount,
|
|
1797
|
+
" alert",
|
|
1798
|
+
alertCount !== 1 ? "s" : "",
|
|
1799
|
+
" ",
|
|
1800
|
+
decCount,
|
|
1801
|
+
" decision",
|
|
1802
|
+
decCount !== 1 ? "s" : "",
|
|
1803
|
+
" ",
|
|
1804
|
+
patCount,
|
|
1805
|
+
" pattern",
|
|
1806
|
+
patCount !== 1 ? "s" : ""
|
|
1807
|
+
] })
|
|
1808
|
+
] }),
|
|
1809
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1810
|
+
alertCount > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1811
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: " Alerts" }),
|
|
1812
|
+
alerts.map((insight, idx) => {
|
|
1813
|
+
const isSelected = idx === selectedInsight;
|
|
1814
|
+
const isExpanded = idx === expandedInsight;
|
|
1815
|
+
const ago = formatTimeAgo(insight.timestamp);
|
|
1816
|
+
const msg = insight.message.slice(0, 60) + (insight.message.length > 60 ? "..." : "");
|
|
1817
|
+
const riskColor2 = insight.priority >= 8 ? "red" : insight.priority >= 5 ? "yellow" : void 0;
|
|
1818
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1819
|
+
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1820
|
+
isSelected ? /* @__PURE__ */ jsxs6(Text6, { bold: true, color: "green", children: [
|
|
1821
|
+
">",
|
|
1822
|
+
" "
|
|
1823
|
+
] }) : /* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1824
|
+
riskColor2 ? /* @__PURE__ */ jsx7(Text6, { color: riskColor2, children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1780
1825
|
" ",
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
" \u2022 ",
|
|
1788
|
-
insight.category,
|
|
1789
|
-
isSelected && !isExpanded ? " \u2022 Press Enter to expand" : ""
|
|
1790
|
-
] }),
|
|
1791
|
-
isExpanded && insight.details && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginLeft: 7, children: [
|
|
1792
|
-
insight.details.issueBreakdown && Object.keys(insight.details.issueBreakdown).length > 0 && /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1793
|
-
insight.details.issueBreakdown["critical"] ? /* @__PURE__ */ jsxs6(Text6, { color: "red", children: [
|
|
1794
|
-
insight.details.issueBreakdown["critical"],
|
|
1795
|
-
" critical"
|
|
1796
|
-
] }) : null,
|
|
1797
|
-
insight.details.issueBreakdown["serious"] ? /* @__PURE__ */ jsxs6(Text6, { color: "yellow", children: [
|
|
1798
|
-
" \u2022 ",
|
|
1799
|
-
insight.details.issueBreakdown["serious"],
|
|
1800
|
-
" serious"
|
|
1801
|
-
] }) : null,
|
|
1802
|
-
insight.details.issueBreakdown["moderate"] ? /* @__PURE__ */ jsxs6(Text6, { color: "blue", children: [
|
|
1803
|
-
" \u2022 ",
|
|
1804
|
-
insight.details.issueBreakdown["moderate"],
|
|
1805
|
-
" moderate"
|
|
1806
|
-
] }) : null
|
|
1807
|
-
] }),
|
|
1808
|
-
insight.details.affectedFiles && insight.details.affectedFiles.length > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1809
|
-
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Files:" }),
|
|
1810
|
-
insight.details.affectedFiles.slice(0, 8).map((f, fi) => /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1811
|
-
" \u2022 ",
|
|
1812
|
-
f
|
|
1813
|
-
] }, fi)),
|
|
1814
|
-
insight.details.affectedFiles.length > 8 && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1815
|
-
" ... +",
|
|
1816
|
-
insight.details.affectedFiles.length - 8,
|
|
1817
|
-
" more"
|
|
1826
|
+
isSelected ? /* @__PURE__ */ jsx7(Text6, { bold: true, children: msg }) : /* @__PURE__ */ jsx7(Text6, { children: msg }),
|
|
1827
|
+
" ",
|
|
1828
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1829
|
+
insight.category,
|
|
1830
|
+
" \xB7 ",
|
|
1831
|
+
ago
|
|
1818
1832
|
] })
|
|
1819
1833
|
] }),
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
" \u2022 ",
|
|
1824
|
-
ex.slice(0, 60),
|
|
1825
|
-
ex.length > 60 ? "..." : ""
|
|
1826
|
-
] }, ei))
|
|
1827
|
-
] }),
|
|
1828
|
-
insight.details.comparison && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1829
|
-
insight.details.trend === "improving" ? "\u2193" : insight.details.trend === "worsening" ? "\u2191" : "\u2192",
|
|
1834
|
+
(isExpanded || isSelected) && insight.suggestedAction && /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1835
|
+
" ",
|
|
1836
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u2192" }),
|
|
1830
1837
|
" ",
|
|
1831
|
-
insight.
|
|
1838
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: insight.suggestedAction })
|
|
1832
1839
|
] })
|
|
1833
|
-
] })
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1840
|
+
] }, insight.id);
|
|
1841
|
+
}),
|
|
1842
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " })
|
|
1843
|
+
] }),
|
|
1844
|
+
decCount > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1845
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: " Decisions" }),
|
|
1846
|
+
decisions.slice(0, 10).map((dec) => {
|
|
1847
|
+
const ago = timeAgo(dec.when);
|
|
1848
|
+
const hash = dec.hash ? dec.hash.slice(0, 6) : "";
|
|
1849
|
+
const active = dec.status === "active";
|
|
1850
|
+
return /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1851
|
+
" ",
|
|
1852
|
+
active ? /* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1853
|
+
" ",
|
|
1854
|
+
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1855
|
+
dec.decision.slice(0, 45),
|
|
1856
|
+
dec.decision.length > 45 ? "..." : ""
|
|
1857
|
+
] }),
|
|
1858
|
+
" ",
|
|
1859
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: ago }),
|
|
1860
|
+
hash && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1861
|
+
" ",
|
|
1862
|
+
hash
|
|
1863
|
+
] })
|
|
1864
|
+
] }, dec.id);
|
|
1865
|
+
}),
|
|
1866
|
+
/* @__PURE__ */ jsx7(Text6, { children: " " })
|
|
1867
|
+
] }),
|
|
1868
|
+
patCount > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1869
|
+
/* @__PURE__ */ jsx7(Text6, { bold: true, children: " Patterns" }),
|
|
1870
|
+
confidentPatterns > 0 && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1871
|
+
" ",
|
|
1872
|
+
confidentPatterns,
|
|
1873
|
+
" confident ",
|
|
1874
|
+
learningPatterns,
|
|
1875
|
+
" learning"
|
|
1876
|
+
] }),
|
|
1877
|
+
patterns.slice(0, 8).map((pat, idx) => {
|
|
1878
|
+
const conf = Math.round(pat.confidence * 100);
|
|
1879
|
+
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
1880
|
+
const desc = pat.description.slice(0, 45) + (pat.description.length > 45 ? "..." : "");
|
|
1881
|
+
return /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1882
|
+
" ",
|
|
1883
|
+
pat.isAntiPattern ? /* @__PURE__ */ jsx7(Text6, { color: "red", children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1884
|
+
" ",
|
|
1885
|
+
/* @__PURE__ */ jsx7(Text6, { children: desc }),
|
|
1886
|
+
" ",
|
|
1887
|
+
confColor ? /* @__PURE__ */ jsxs6(Text6, { color: confColor, children: [
|
|
1888
|
+
conf,
|
|
1889
|
+
"%"
|
|
1890
|
+
] }) : /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1891
|
+
conf,
|
|
1892
|
+
"%"
|
|
1893
|
+
] }),
|
|
1894
|
+
pat.isAntiPattern && /* @__PURE__ */ jsx7(Text6, { color: "red", children: " anti-pattern" })
|
|
1895
|
+
] }, idx);
|
|
1896
|
+
})
|
|
1897
|
+
] }),
|
|
1848
1898
|
/* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1849
1899
|
/* @__PURE__ */ jsxs6(Box6, { gap: 2, children: [
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
"
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
"
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
isAIAvailable() ? /* @__PURE__ */ jsx7(Text6, { color: "green", children: "AI \u2713" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "AI off" })
|
|
1900
|
+
isAIAvailable() ? /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1901
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1902
|
+
" ",
|
|
1903
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "AI" })
|
|
1904
|
+
] }) : /* @__PURE__ */ jsx7(Text6, { children: /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB AI off" }) }),
|
|
1905
|
+
agentInsights.filter((i) => i.type === "celebration").length > 0 && /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1906
|
+
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1907
|
+
" ",
|
|
1908
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1909
|
+
agentInsights.filter((i) => i.type === "celebration").length,
|
|
1910
|
+
" wins"
|
|
1911
|
+
] })
|
|
1912
|
+
] })
|
|
1864
1913
|
] })
|
|
1865
1914
|
] });
|
|
1866
1915
|
}
|
|
1867
1916
|
|
|
1868
1917
|
// src/cli/dashboard/views/GoalsView.tsx
|
|
1869
|
-
import { useCallback } from "react";
|
|
1918
|
+
import { useCallback as useCallback2 } from "react";
|
|
1870
1919
|
import { Box as Box7, Text as Text7, useInput as useInput3 } from "ink";
|
|
1871
1920
|
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1872
1921
|
function calculateGoalProgress(goal) {
|
|
@@ -1885,7 +1934,7 @@ function GoalsView() {
|
|
|
1885
1934
|
const activeGoals = goalsPanel.goals.filter((g) => g.status === "active");
|
|
1886
1935
|
const achievedGoals = goalsPanel.goals.filter((g) => g.status === "achieved");
|
|
1887
1936
|
const otherGoals = goalsPanel.goals.filter((g) => g.status !== "active" && g.status !== "achieved");
|
|
1888
|
-
const refreshGoals =
|
|
1937
|
+
const refreshGoals = useCallback2(async () => {
|
|
1889
1938
|
try {
|
|
1890
1939
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1891
1940
|
const agentState = getGuardianState(workDir);
|
|
@@ -1901,7 +1950,7 @@ function GoalsView() {
|
|
|
1901
1950
|
} catch {
|
|
1902
1951
|
}
|
|
1903
1952
|
}, [dispatch]);
|
|
1904
|
-
const addGoal =
|
|
1953
|
+
const addGoal = useCallback2(async (description) => {
|
|
1905
1954
|
if (!description.trim()) return;
|
|
1906
1955
|
try {
|
|
1907
1956
|
const workDir = getWorkingDirectory(void 0, true);
|
|
@@ -1927,7 +1976,7 @@ function GoalsView() {
|
|
|
1927
1976
|
} catch {
|
|
1928
1977
|
}
|
|
1929
1978
|
}, [dispatch, refreshGoals]);
|
|
1930
|
-
const completeGoal =
|
|
1979
|
+
const completeGoal = useCallback2(async (goalId) => {
|
|
1931
1980
|
try {
|
|
1932
1981
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1933
1982
|
const agentState = getGuardianState(workDir);
|
|
@@ -1942,7 +1991,7 @@ function GoalsView() {
|
|
|
1942
1991
|
} catch {
|
|
1943
1992
|
}
|
|
1944
1993
|
}, [dispatch, refreshGoals]);
|
|
1945
|
-
const deleteGoal =
|
|
1994
|
+
const deleteGoal = useCallback2(async (goalId) => {
|
|
1946
1995
|
try {
|
|
1947
1996
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1948
1997
|
const agentState = getGuardianState(workDir);
|
|
@@ -1953,7 +2002,7 @@ function GoalsView() {
|
|
|
1953
2002
|
} catch {
|
|
1954
2003
|
}
|
|
1955
2004
|
}, [dispatch, refreshGoals]);
|
|
1956
|
-
const reactivateGoal =
|
|
2005
|
+
const reactivateGoal = useCallback2(async (goalId) => {
|
|
1957
2006
|
try {
|
|
1958
2007
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1959
2008
|
const agentState = getGuardianState(workDir);
|
|
@@ -2003,75 +2052,76 @@ function GoalsView() {
|
|
|
2003
2052
|
] }),
|
|
2004
2053
|
/* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
2005
2054
|
goalsPanel.inputMode === "add" ? /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2006
|
-
/* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2007
|
-
/* @__PURE__ */ jsx8(Text7, { bold: true, children: "New goal:" }),
|
|
2008
|
-
" ",
|
|
2055
|
+
/* @__PURE__ */ jsx8(Box7, { borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2009
2056
|
goalsPanel.inputBuffer,
|
|
2010
|
-
/* @__PURE__ */ jsx8(Text7, { bold: true, color: "green", children: "
|
|
2011
|
-
] }),
|
|
2012
|
-
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children:
|
|
2013
|
-
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Press Enter to add, Escape to cancel" })
|
|
2057
|
+
/* @__PURE__ */ jsx8(Text7, { bold: true, color: "green", children: "|" })
|
|
2058
|
+
] }) }),
|
|
2059
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2014
2060
|
] }) : /* @__PURE__ */ jsx8(Fragment2, { children: goalsPanel.goals.length === 0 ? /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2015
|
-
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "No goals yet." }),
|
|
2016
|
-
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Press
|
|
2061
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " No goals yet." }),
|
|
2062
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " Press a to add your first goal." })
|
|
2017
2063
|
] }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2018
2064
|
activeGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2019
|
-
/* @__PURE__ */ jsx8(Text7, { bold: true, children: "Active:" }),
|
|
2020
2065
|
activeGoals.map((goal, idx) => {
|
|
2021
2066
|
const isSelected = goalsPanel.selectedIndex === idx;
|
|
2022
2067
|
const progress = calculateGoalProgress(goal);
|
|
2023
|
-
const bar = progressBar(progress, 100,
|
|
2024
|
-
const source = goal.autoGenerated ?
|
|
2068
|
+
const bar = progressBar(progress, 100, 8);
|
|
2069
|
+
const source = goal.autoGenerated ? "auto" : "manual";
|
|
2025
2070
|
return /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2026
|
-
isSelected ? /* @__PURE__ */
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2071
|
+
isSelected ? /* @__PURE__ */ jsxs7(Text7, { bold: true, color: "green", children: [
|
|
2072
|
+
">",
|
|
2073
|
+
" "
|
|
2074
|
+
] }) : /* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
2075
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CB" }),
|
|
2030
2076
|
" ",
|
|
2031
|
-
|
|
2077
|
+
goal.description.slice(0, 45),
|
|
2078
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2079
|
+
" ",
|
|
2080
|
+
source,
|
|
2081
|
+
" ",
|
|
2082
|
+
bar,
|
|
2083
|
+
" ",
|
|
2084
|
+
progress,
|
|
2085
|
+
"%"
|
|
2086
|
+
] })
|
|
2032
2087
|
] }, goal.id);
|
|
2033
2088
|
}),
|
|
2034
2089
|
/* @__PURE__ */ jsx8(Text7, { children: " " })
|
|
2035
2090
|
] }),
|
|
2036
2091
|
achievedGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2037
|
-
/* @__PURE__ */
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
" [+] ",
|
|
2092
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " Achieved" }),
|
|
2093
|
+
achievedGoals.slice(0, 5).map((g) => /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2094
|
+
" ",
|
|
2095
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CF" }),
|
|
2096
|
+
" ",
|
|
2043
2097
|
g.description.slice(0, 50)
|
|
2044
2098
|
] }, g.id)),
|
|
2045
2099
|
achievedGoals.length > 5 && /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2046
|
-
"
|
|
2100
|
+
" +",
|
|
2047
2101
|
achievedGoals.length - 5,
|
|
2048
2102
|
" more"
|
|
2049
2103
|
] }),
|
|
2050
2104
|
/* @__PURE__ */ jsx8(Text7, { children: " " })
|
|
2051
2105
|
] }),
|
|
2052
2106
|
otherGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2053
|
-
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Other
|
|
2054
|
-
otherGoals.slice(0, 2).map((g) => {
|
|
2055
|
-
|
|
2056
|
-
|
|
2107
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " Other" }),
|
|
2108
|
+
otherGoals.slice(0, 2).map((g) => /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2109
|
+
" ",
|
|
2110
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "\u25CB" }),
|
|
2111
|
+
" ",
|
|
2112
|
+
g.description.slice(0, 50),
|
|
2113
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2057
2114
|
" ",
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2062
|
-
" (",
|
|
2063
|
-
g.status,
|
|
2064
|
-
")"
|
|
2065
|
-
] })
|
|
2066
|
-
] }, g.id);
|
|
2067
|
-
})
|
|
2115
|
+
g.status
|
|
2116
|
+
] })
|
|
2117
|
+
] }, g.id))
|
|
2068
2118
|
] })
|
|
2069
2119
|
] }) })
|
|
2070
2120
|
] });
|
|
2071
2121
|
}
|
|
2072
2122
|
|
|
2073
2123
|
// src/cli/dashboard/views/HypothesesView.tsx
|
|
2074
|
-
import { useCallback as
|
|
2124
|
+
import { useCallback as useCallback3 } from "react";
|
|
2075
2125
|
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
2076
2126
|
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2077
2127
|
function HypothesesView() {
|
|
@@ -2080,7 +2130,7 @@ function HypothesesView() {
|
|
|
2080
2130
|
const testing = hypothesesPanel.hypotheses.filter((h) => h.status === "testing");
|
|
2081
2131
|
const validated = hypothesesPanel.hypotheses.filter((h) => h.status === "validated");
|
|
2082
2132
|
const invalidated = hypothesesPanel.hypotheses.filter((h) => h.status === "invalidated");
|
|
2083
|
-
const refreshHypotheses =
|
|
2133
|
+
const refreshHypotheses = useCallback3(async () => {
|
|
2084
2134
|
try {
|
|
2085
2135
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2086
2136
|
const agentState = getGuardianState(workDir);
|
|
@@ -2096,7 +2146,7 @@ function HypothesesView() {
|
|
|
2096
2146
|
} catch {
|
|
2097
2147
|
}
|
|
2098
2148
|
}, [dispatch]);
|
|
2099
|
-
const addHypothesis =
|
|
2149
|
+
const addHypothesis = useCallback3(async (statement) => {
|
|
2100
2150
|
if (!statement.trim()) return;
|
|
2101
2151
|
try {
|
|
2102
2152
|
const workDir = getWorkingDirectory(void 0, true);
|
|
@@ -2118,7 +2168,7 @@ function HypothesesView() {
|
|
|
2118
2168
|
} catch {
|
|
2119
2169
|
}
|
|
2120
2170
|
}, [dispatch, refreshHypotheses]);
|
|
2121
|
-
const updateHypothesis =
|
|
2171
|
+
const updateHypothesis = useCallback3(async (hypoId, action) => {
|
|
2122
2172
|
try {
|
|
2123
2173
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2124
2174
|
const agentState = getGuardianState(workDir);
|
|
@@ -2131,7 +2181,7 @@ function HypothesesView() {
|
|
|
2131
2181
|
} catch {
|
|
2132
2182
|
}
|
|
2133
2183
|
}, [dispatch, refreshHypotheses]);
|
|
2134
|
-
const reactivateHypothesis =
|
|
2184
|
+
const reactivateHypothesis = useCallback3(async (hypoId) => {
|
|
2135
2185
|
try {
|
|
2136
2186
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2137
2187
|
const agentState = getGuardianState(workDir);
|
|
@@ -2184,74 +2234,63 @@ function HypothesesView() {
|
|
|
2184
2234
|
] }),
|
|
2185
2235
|
/* @__PURE__ */ jsx9(Text8, { children: " " }),
|
|
2186
2236
|
hypothesesPanel.inputMode === "add" ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2187
|
-
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2188
|
-
/* @__PURE__ */ jsx9(Text8, { bold: true, children: "New hypothesis:" }),
|
|
2189
|
-
" ",
|
|
2237
|
+
/* @__PURE__ */ jsx9(Box8, { borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2190
2238
|
hypothesesPanel.inputBuffer,
|
|
2191
|
-
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "
|
|
2192
|
-
] }),
|
|
2193
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children:
|
|
2194
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Press Enter to add, Escape to cancel" })
|
|
2239
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "|" })
|
|
2240
|
+
] }) }),
|
|
2241
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2195
2242
|
] }) : /* @__PURE__ */ jsx9(Fragment3, { children: hypothesesPanel.hypotheses.length === 0 ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2196
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "No hypotheses yet." }),
|
|
2197
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Press
|
|
2198
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "The agent will collect evidence and update confidence over time." })
|
|
2243
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " No hypotheses yet." }),
|
|
2244
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Press a to add your first hypothesis." })
|
|
2199
2245
|
] }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2200
2246
|
testing.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2201
|
-
/* @__PURE__ */ jsx9(Text8, { bold: true, children: "Testing:" }),
|
|
2202
2247
|
testing.map((hypo, idx) => {
|
|
2203
2248
|
const isSelected = hypothesesPanel.selectedIndex === idx;
|
|
2204
2249
|
const conf = Math.round(hypo.confidence * 100);
|
|
2205
|
-
return /* @__PURE__ */
|
|
2206
|
-
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
conf,
|
|
2214
|
-
"%)"
|
|
2215
|
-
] })
|
|
2216
|
-
] }),
|
|
2250
|
+
return /* @__PURE__ */ jsx9(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2251
|
+
isSelected ? /* @__PURE__ */ jsxs8(Text8, { bold: true, color: "green", children: [
|
|
2252
|
+
">",
|
|
2253
|
+
" "
|
|
2254
|
+
] }) : /* @__PURE__ */ jsx9(Text8, { children: " " }),
|
|
2255
|
+
/* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "\u25CB" }),
|
|
2256
|
+
" ",
|
|
2257
|
+
hypo.statement.slice(0, 50),
|
|
2217
2258
|
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2218
|
-
"
|
|
2259
|
+
" ",
|
|
2260
|
+
conf,
|
|
2261
|
+
"% \xB7 ",
|
|
2219
2262
|
hypo.evidenceCount,
|
|
2220
|
-
"
|
|
2263
|
+
" evidence"
|
|
2221
2264
|
] })
|
|
2222
|
-
] }, hypo.id);
|
|
2265
|
+
] }) }, hypo.id);
|
|
2223
2266
|
}),
|
|
2224
2267
|
/* @__PURE__ */ jsx9(Text8, { children: " " })
|
|
2225
2268
|
] }),
|
|
2226
2269
|
validated.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2227
|
-
/* @__PURE__ */
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
h.statement.slice(0, 50),
|
|
2234
|
-
'"'
|
|
2270
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Validated" }),
|
|
2271
|
+
validated.slice(0, 3).map((h) => /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2272
|
+
" ",
|
|
2273
|
+
/* @__PURE__ */ jsx9(Text8, { color: "green", children: "\u25CF" }),
|
|
2274
|
+
" ",
|
|
2275
|
+
h.statement.slice(0, 50)
|
|
2235
2276
|
] }, h.id)),
|
|
2236
2277
|
validated.length > 3 && /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2237
|
-
"
|
|
2278
|
+
" +",
|
|
2238
2279
|
validated.length - 3,
|
|
2239
2280
|
" more"
|
|
2240
2281
|
] }),
|
|
2241
2282
|
/* @__PURE__ */ jsx9(Text8, { children: " " })
|
|
2242
2283
|
] }),
|
|
2243
2284
|
invalidated.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2244
|
-
/* @__PURE__ */
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
'"'
|
|
2252
|
-
] }) }, h.id)),
|
|
2285
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Invalidated" }),
|
|
2286
|
+
invalidated.slice(0, 2).map((h) => /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2287
|
+
" ",
|
|
2288
|
+
/* @__PURE__ */ jsx9(Text8, { color: "red", children: "\u25CF" }),
|
|
2289
|
+
" ",
|
|
2290
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: h.statement.slice(0, 50) })
|
|
2291
|
+
] }, h.id)),
|
|
2253
2292
|
invalidated.length > 2 && /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2254
|
-
"
|
|
2293
|
+
" +",
|
|
2255
2294
|
invalidated.length - 2,
|
|
2256
2295
|
" more"
|
|
2257
2296
|
] })
|
|
@@ -2261,31 +2300,48 @@ function HypothesesView() {
|
|
|
2261
2300
|
}
|
|
2262
2301
|
|
|
2263
2302
|
// src/cli/dashboard/views/MemoryTreeView.tsx
|
|
2264
|
-
import { useEffect, useCallback as
|
|
2303
|
+
import { useEffect as useEffect3, useCallback as useCallback4 } from "react";
|
|
2265
2304
|
import { Box as Box9, Text as Text9, useInput as useInput5 } from "ink";
|
|
2266
2305
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2306
|
+
var RISK_ORDER = { critical: 0, high: 1, medium: 2, low: 3, unknown: 4 };
|
|
2307
|
+
function riskColor(risk) {
|
|
2308
|
+
switch (risk) {
|
|
2309
|
+
case "critical":
|
|
2310
|
+
return "red";
|
|
2311
|
+
case "high":
|
|
2312
|
+
return "yellow";
|
|
2313
|
+
case "medium":
|
|
2314
|
+
return "blue";
|
|
2315
|
+
default:
|
|
2316
|
+
return void 0;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
function timeAgo2(iso) {
|
|
2320
|
+
const ms = Date.now() - new Date(iso).getTime();
|
|
2321
|
+
const mins = Math.floor(ms / 6e4);
|
|
2322
|
+
if (mins < 60) return `${mins}m`;
|
|
2323
|
+
const hrs = Math.floor(mins / 60);
|
|
2324
|
+
if (hrs < 24) return `${hrs}h`;
|
|
2325
|
+
return `${Math.floor(hrs / 24)}d`;
|
|
2270
2326
|
}
|
|
2271
2327
|
function MemoryTreeView() {
|
|
2272
2328
|
const { state, dispatch } = useDashboard();
|
|
2273
2329
|
const { memoryTree } = state;
|
|
2274
|
-
const {
|
|
2275
|
-
const loadData =
|
|
2330
|
+
const { snapshot, globalPatterns, expandedNodes, selectedNode, loaded } = memoryTree;
|
|
2331
|
+
const loadData = useCallback4(async () => {
|
|
2276
2332
|
try {
|
|
2277
2333
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2278
|
-
const
|
|
2279
|
-
|
|
2280
|
-
|
|
2334
|
+
const graph = new ContextGraph(workDir);
|
|
2335
|
+
const [snap, patterns] = await Promise.all([
|
|
2336
|
+
graph.getSnapshot(),
|
|
2281
2337
|
findCrossProjectPatterns(2)
|
|
2282
2338
|
]);
|
|
2283
|
-
dispatch({ type: "SET_MEMORY_TREE",
|
|
2339
|
+
dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns });
|
|
2284
2340
|
} catch {
|
|
2285
|
-
dispatch({ type: "ADD_ACTIVITY", message: "
|
|
2341
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Context graph load error" });
|
|
2286
2342
|
}
|
|
2287
2343
|
}, [dispatch]);
|
|
2288
|
-
|
|
2344
|
+
useEffect3(() => {
|
|
2289
2345
|
if (!loaded) {
|
|
2290
2346
|
void loadData();
|
|
2291
2347
|
}
|
|
@@ -2295,167 +2351,196 @@ function MemoryTreeView() {
|
|
|
2295
2351
|
else if (key.downArrow || _input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
2296
2352
|
else if (key.return) dispatch({ type: "TOGGLE_MEMORY_NODE", nodeId: selectedNode });
|
|
2297
2353
|
});
|
|
2298
|
-
const bySeverity = { critical: [], serious: [], moderate: [], low: [] };
|
|
2299
|
-
for (const issue of issues) {
|
|
2300
|
-
const arr = bySeverity[issue.severity];
|
|
2301
|
-
if (arr) arr.push(issue);
|
|
2302
|
-
}
|
|
2303
|
-
const byFile = /* @__PURE__ */ new Map();
|
|
2304
|
-
for (const issue of issues) {
|
|
2305
|
-
if (!byFile.has(issue.file)) byFile.set(issue.file, []);
|
|
2306
|
-
byFile.get(issue.file).push(issue);
|
|
2307
|
-
}
|
|
2308
|
-
const sortedFiles = Array.from(byFile.entries()).sort((a, b) => b[1].length - a[1].length).slice(0, 10);
|
|
2309
|
-
const byAgent = /* @__PURE__ */ new Map();
|
|
2310
|
-
for (const issue of issues) {
|
|
2311
|
-
if (!byAgent.has(issue.agent)) byAgent.set(issue.agent, []);
|
|
2312
|
-
byAgent.get(issue.agent).push(issue);
|
|
2313
|
-
}
|
|
2314
|
-
const sortedAgents = Array.from(byAgent.entries()).sort((a, b) => b[1].length - a[1].length);
|
|
2315
|
-
const maxCount = Math.max(bySeverity["critical"]?.length || 0, bySeverity["serious"]?.length || 0, bySeverity["moderate"]?.length || 0, bySeverity["low"]?.length || 0, 1);
|
|
2316
|
-
const totalIssues = stats?.totalIssues || issues.length;
|
|
2317
2354
|
const sel = (nodeId) => selectedNode === nodeId;
|
|
2355
|
+
if (!loaded) {
|
|
2356
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, children: [
|
|
2357
|
+
/* @__PURE__ */ jsx10(Text9, { bold: true, children: "Context" }),
|
|
2358
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " Loading context graph..." })
|
|
2359
|
+
] });
|
|
2360
|
+
}
|
|
2361
|
+
const nodeCount = snapshot?.nodes.length ?? 0;
|
|
2362
|
+
const edgeCount = snapshot?.edges.length ?? 0;
|
|
2363
|
+
if (nodeCount === 0 && globalPatterns.length === 0) {
|
|
2364
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, children: [
|
|
2365
|
+
/* @__PURE__ */ jsx10(Text9, { bold: true, children: "Context" }),
|
|
2366
|
+
/* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2367
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " No context data yet." }),
|
|
2368
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " Run trie watch or trie tell to populate the graph." })
|
|
2369
|
+
] });
|
|
2370
|
+
}
|
|
2371
|
+
const fileNodes = snapshot?.nodes.filter((n) => n.type === "file") ?? [];
|
|
2372
|
+
const changeNodes = snapshot?.nodes.filter((n) => n.type === "change") ?? [];
|
|
2373
|
+
const patternNodes = snapshot?.nodes.filter((n) => n.type === "pattern") ?? [];
|
|
2374
|
+
const incidentNodes = snapshot?.nodes.filter((n) => n.type === "incident") ?? [];
|
|
2375
|
+
const decisionNodes = snapshot?.nodes.filter((n) => n.type === "decision") ?? [];
|
|
2376
|
+
const sortedFiles = [...fileNodes].sort(
|
|
2377
|
+
(a, b) => (RISK_ORDER[a.data.riskLevel] ?? 4) - (RISK_ORDER[b.data.riskLevel] ?? 4)
|
|
2378
|
+
);
|
|
2379
|
+
const sortedChanges = [...changeNodes].sort(
|
|
2380
|
+
(a, b) => new Date(b.data.timestamp).getTime() - new Date(a.data.timestamp).getTime()
|
|
2381
|
+
);
|
|
2382
|
+
function renderSectionHeader(id, label, count) {
|
|
2383
|
+
const expanded = expandedNodes.has(id);
|
|
2384
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2385
|
+
sel(id) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2386
|
+
">",
|
|
2387
|
+
" "
|
|
2388
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2389
|
+
expanded ? /* @__PURE__ */ jsx10(Text9, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2390
|
+
" ",
|
|
2391
|
+
sel(id) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2392
|
+
label,
|
|
2393
|
+
" (",
|
|
2394
|
+
count,
|
|
2395
|
+
")"
|
|
2396
|
+
] }) : /* @__PURE__ */ jsxs9(Text9, { bold: true, children: [
|
|
2397
|
+
label,
|
|
2398
|
+
" (",
|
|
2399
|
+
count,
|
|
2400
|
+
")"
|
|
2401
|
+
] })
|
|
2402
|
+
] });
|
|
2403
|
+
}
|
|
2318
2404
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, children: [
|
|
2319
2405
|
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2320
|
-
/* @__PURE__ */ jsx10(Text9, { bold: true, children: "
|
|
2406
|
+
/* @__PURE__ */ jsx10(Text9, { bold: true, children: "Context" }),
|
|
2321
2407
|
" ",
|
|
2322
2408
|
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2409
|
+
nodeCount,
|
|
2410
|
+
" nodes ",
|
|
2411
|
+
edgeCount,
|
|
2412
|
+
" edges"
|
|
2326
2413
|
] })
|
|
2327
2414
|
] }),
|
|
2328
2415
|
/* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
const barStr = severityBar(count, maxCount);
|
|
2343
|
-
const isLow = sev === "low";
|
|
2344
|
-
const sevColorMap = { critical: "red", serious: "yellow", moderate: "blue" };
|
|
2345
|
-
const sevColor = isLow ? void 0 : sevColorMap[sev];
|
|
2346
|
-
const SevText = ({ children }) => isLow ? /* @__PURE__ */ jsx10(Text9, { dimColor: true, children }) : sevColor ? /* @__PURE__ */ jsx10(Text9, { color: sevColor, children }) : /* @__PURE__ */ jsx10(Text9, { children });
|
|
2347
|
-
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
2348
|
-
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2349
|
-
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "\u2192 " }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2350
|
-
" \u2502 ",
|
|
2351
|
-
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: sev }) : /* @__PURE__ */ jsx10(SevText, { children: sev }),
|
|
2352
|
-
` (${count}) `,
|
|
2353
|
-
/* @__PURE__ */ jsx10(SevText, { children: barStr })
|
|
2354
|
-
] }),
|
|
2355
|
-
expandedNodes.has(nodeId) && (bySeverity[sev] || []).slice(0, 5).map((issue, i) => {
|
|
2356
|
-
const issueId = `severity-${sev}-${issue.id}`;
|
|
2357
|
-
const filename = issue.file.split("/").pop() || issue.file;
|
|
2358
|
-
const line = issue.line ? `:${issue.line}` : "";
|
|
2359
|
-
const desc = issue.issue.slice(0, 35) + (issue.issue.length > 35 ? "..." : "");
|
|
2360
|
-
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2361
|
-
sel(issueId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "\u2192 " }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2362
|
-
" \u2502 ",
|
|
2363
|
-
i === Math.min(5, bySeverity[sev]?.length || 0) - 1 ? "\u2514\u2500 " : "\u251C\u2500 ",
|
|
2364
|
-
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2365
|
-
filename,
|
|
2366
|
-
line
|
|
2367
|
-
] }),
|
|
2368
|
-
" - ",
|
|
2369
|
-
/* @__PURE__ */ jsx10(SevText, { children: desc })
|
|
2370
|
-
] }, i);
|
|
2371
|
-
})
|
|
2372
|
-
] }, sev);
|
|
2373
|
-
}),
|
|
2374
|
-
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2375
|
-
sel("files") ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "\u2192 " }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2376
|
-
expandedNodes.has("files") ? "\u25BC" : "\u25B6",
|
|
2416
|
+
renderSectionHeader("files", "Files", fileNodes.length),
|
|
2417
|
+
expandedNodes.has("files") && sortedFiles.slice(0, 15).map((n) => {
|
|
2418
|
+
const nodeId = `file-${n.id}`;
|
|
2419
|
+
const path = n.data.path.split("/").slice(-2).join("/");
|
|
2420
|
+
const risk = n.data.riskLevel;
|
|
2421
|
+
const color = riskColor(risk);
|
|
2422
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2423
|
+
sel(nodeId) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2424
|
+
">",
|
|
2425
|
+
" "
|
|
2426
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2427
|
+
" ",
|
|
2428
|
+
color ? /* @__PURE__ */ jsx10(Text9, { color, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2377
2429
|
" ",
|
|
2378
|
-
sel(
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
"
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2430
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: path }) : /* @__PURE__ */ jsx10(Text9, { children: path }),
|
|
2431
|
+
" ",
|
|
2432
|
+
color ? /* @__PURE__ */ jsx10(Text9, { color, children: risk }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: risk }),
|
|
2433
|
+
" ",
|
|
2434
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2435
|
+
n.data.changeCount,
|
|
2436
|
+
" changes"
|
|
2437
|
+
] }),
|
|
2438
|
+
n.data.incidentCount > 0 && /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2439
|
+
" ",
|
|
2440
|
+
n.data.incidentCount,
|
|
2441
|
+
" incidents"
|
|
2442
|
+
] })
|
|
2443
|
+
] }, n.id);
|
|
2444
|
+
}),
|
|
2445
|
+
renderSectionHeader("changes", "Changes", changeNodes.length),
|
|
2446
|
+
expandedNodes.has("changes") && sortedChanges.slice(0, 10).map((n) => {
|
|
2447
|
+
const nodeId = `change-${n.id}`;
|
|
2448
|
+
const msg = n.data.message.slice(0, 45) + (n.data.message.length > 45 ? "..." : "");
|
|
2449
|
+
const outcome = n.data.outcome;
|
|
2450
|
+
const outcomeColor = outcome === "incident" ? "red" : outcome === "success" ? "green" : void 0;
|
|
2451
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2452
|
+
sel(nodeId) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2453
|
+
">",
|
|
2454
|
+
" "
|
|
2455
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2456
|
+
" ",
|
|
2457
|
+
outcomeColor ? /* @__PURE__ */ jsx10(Text9, { color: outcomeColor, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2396
2458
|
" ",
|
|
2397
|
-
sel(
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2459
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: msg }) : /* @__PURE__ */ jsx10(Text9, { children: msg }),
|
|
2460
|
+
" ",
|
|
2461
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: timeAgo2(n.data.timestamp) })
|
|
2462
|
+
] }, n.id);
|
|
2463
|
+
}),
|
|
2464
|
+
renderSectionHeader("patterns", "Patterns", patternNodes.length),
|
|
2465
|
+
expandedNodes.has("patterns") && patternNodes.slice(0, 10).map((n) => {
|
|
2466
|
+
const nodeId = `pattern-${n.id}`;
|
|
2467
|
+
const conf = Math.round(n.data.confidence * 100);
|
|
2468
|
+
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
2469
|
+
const desc = n.data.description.slice(0, 45) + (n.data.description.length > 45 ? "..." : "");
|
|
2470
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2471
|
+
sel(nodeId) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2472
|
+
">",
|
|
2473
|
+
" "
|
|
2474
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2475
|
+
" ",
|
|
2476
|
+
n.data.isAntiPattern ? /* @__PURE__ */ jsx10(Text9, { color: "red", children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2413
2477
|
" ",
|
|
2414
|
-
sel(
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
"
|
|
2422
|
-
] })
|
|
2423
|
-
] }),
|
|
2424
|
-
expandedNodes.has("patterns") && globalPatterns.slice(0, 5).map((pattern, idx) => {
|
|
2425
|
-
const patternId = `pattern-${pattern.id}`;
|
|
2426
|
-
const isLast = idx === Math.min(4, globalPatterns.length - 1);
|
|
2427
|
-
const desc = pattern.pattern.slice(0, 40) + (pattern.pattern.length > 40 ? "..." : "");
|
|
2428
|
-
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2429
|
-
sel(patternId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "\u2192 " }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2430
|
-
" ",
|
|
2431
|
-
isLast ? "\u2514\u2500 " : "\u251C\u2500 ",
|
|
2432
|
-
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2433
|
-
'"',
|
|
2434
|
-
desc,
|
|
2435
|
-
'" - seen in ',
|
|
2436
|
-
pattern.projects.length,
|
|
2437
|
-
" projects"
|
|
2438
|
-
] })
|
|
2439
|
-
] }, pattern.id);
|
|
2440
|
-
}),
|
|
2441
|
-
/* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2442
|
-
/* @__PURE__ */ jsxs9(Box9, { gap: 2, children: [
|
|
2443
|
-
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2444
|
-
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "Trend: " }),
|
|
2445
|
-
stats?.improvementTrend === "improving" ? /* @__PURE__ */ jsx10(Text9, { color: "green", children: "\u2191 Improving" }) : stats?.improvementTrend === "declining" ? /* @__PURE__ */ jsx10(Text9, { color: "red", children: "\u2193 Declining" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u2192 Stable" })
|
|
2446
|
-
] }),
|
|
2447
|
-
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2448
|
-
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "Resolved:" }),
|
|
2449
|
-
" ",
|
|
2450
|
-
/* @__PURE__ */ jsx10(Text9, { color: "green", children: stats?.resolvedCount || 0 })
|
|
2478
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx10(Text9, { children: desc }),
|
|
2479
|
+
" ",
|
|
2480
|
+
confColor ? /* @__PURE__ */ jsxs9(Text9, { color: confColor, children: [
|
|
2481
|
+
conf,
|
|
2482
|
+
"%"
|
|
2483
|
+
] }) : /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2484
|
+
conf,
|
|
2485
|
+
"%"
|
|
2451
2486
|
] }),
|
|
2452
|
-
/* @__PURE__ */
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2487
|
+
n.data.isAntiPattern && /* @__PURE__ */ jsx10(Text9, { color: "red", children: " anti-pattern" })
|
|
2488
|
+
] }, n.id);
|
|
2489
|
+
}),
|
|
2490
|
+
renderSectionHeader("incidents", "Incidents", incidentNodes.length),
|
|
2491
|
+
expandedNodes.has("incidents") && incidentNodes.slice(0, 10).map((n) => {
|
|
2492
|
+
const nodeId = `incident-${n.id}`;
|
|
2493
|
+
const sevColor = n.data.severity === "critical" ? "red" : n.data.severity === "major" ? "yellow" : void 0;
|
|
2494
|
+
const desc = n.data.description.slice(0, 45) + (n.data.description.length > 45 ? "..." : "");
|
|
2495
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2496
|
+
sel(nodeId) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2497
|
+
">",
|
|
2498
|
+
" "
|
|
2499
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2500
|
+
" ",
|
|
2501
|
+
sevColor ? /* @__PURE__ */ jsx10(Text9, { color: sevColor, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2502
|
+
" ",
|
|
2503
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx10(Text9, { children: desc }),
|
|
2504
|
+
" ",
|
|
2505
|
+
n.data.resolved ? /* @__PURE__ */ jsx10(Text9, { color: "green", children: "resolved" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "open" })
|
|
2506
|
+
] }, n.id);
|
|
2507
|
+
}),
|
|
2508
|
+
renderSectionHeader("decisions", "Decisions", decisionNodes.length),
|
|
2509
|
+
expandedNodes.has("decisions") && decisionNodes.slice(0, 10).map((n) => {
|
|
2510
|
+
const nodeId = `decision-${n.id}`;
|
|
2511
|
+
const dec = n.data.decision.slice(0, 45) + (n.data.decision.length > 45 ? "..." : "");
|
|
2512
|
+
const outcomeColor = n.data.outcome === "good" ? "green" : n.data.outcome === "bad" ? "red" : void 0;
|
|
2513
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2514
|
+
sel(nodeId) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2515
|
+
">",
|
|
2516
|
+
" "
|
|
2517
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2518
|
+
" ",
|
|
2519
|
+
outcomeColor ? /* @__PURE__ */ jsx10(Text9, { color: outcomeColor, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2520
|
+
" ",
|
|
2521
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: dec }) : /* @__PURE__ */ jsx10(Text9, { children: dec }),
|
|
2522
|
+
" ",
|
|
2523
|
+
outcomeColor ? /* @__PURE__ */ jsx10(Text9, { color: outcomeColor, children: n.data.outcome }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: n.data.outcome })
|
|
2524
|
+
] }, n.id);
|
|
2525
|
+
}),
|
|
2526
|
+
renderSectionHeader("cross-project", "Cross-Project", globalPatterns.length),
|
|
2527
|
+
expandedNodes.has("cross-project") && globalPatterns.slice(0, 5).map((pattern) => {
|
|
2528
|
+
const patternId = `global-${pattern.id}`;
|
|
2529
|
+
const desc = pattern.pattern.slice(0, 40) + (pattern.pattern.length > 40 ? "..." : "");
|
|
2530
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2531
|
+
sel(patternId) ? /* @__PURE__ */ jsxs9(Text9, { bold: true, color: "green", children: [
|
|
2532
|
+
">",
|
|
2533
|
+
" "
|
|
2534
|
+
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2535
|
+
" ",
|
|
2536
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2537
|
+
desc,
|
|
2538
|
+
" \xB7 ",
|
|
2539
|
+
pattern.projects.length,
|
|
2540
|
+
" projects"
|
|
2456
2541
|
] })
|
|
2457
|
-
] })
|
|
2458
|
-
|
|
2542
|
+
] }, pattern.id);
|
|
2543
|
+
})
|
|
2459
2544
|
] });
|
|
2460
2545
|
}
|
|
2461
2546
|
|
|
@@ -2491,33 +2576,167 @@ function RawLogView() {
|
|
|
2491
2576
|
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " entries" })
|
|
2492
2577
|
] }),
|
|
2493
2578
|
/* @__PURE__ */ jsx11(Text10, { children: " " }),
|
|
2494
|
-
rawLog.length === 0 ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "No log entries yet." }) : /* @__PURE__ */ jsx11(Box10, { flexDirection: "column", children: logs.map((entry, i) => {
|
|
2495
|
-
const
|
|
2496
|
-
const levelEl = entry.level === "error" ? /* @__PURE__ */ jsx11(Text10, { color: "red", children: levelTag }) : entry.level === "warn" ? /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: levelTag }) : entry.level === "info" ? /* @__PURE__ */ jsx11(Text10, { color: "green", children: levelTag }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: levelTag });
|
|
2579
|
+
rawLog.length === 0 ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " No log entries yet." }) : /* @__PURE__ */ jsx11(Box10, { flexDirection: "column", children: logs.map((entry, i) => {
|
|
2580
|
+
const dot = entry.level === "error" ? /* @__PURE__ */ jsx11(Text10, { color: "red", children: "\u25CF" }) : entry.level === "warn" ? /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "\u25CF" }) : entry.level === "info" ? /* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" });
|
|
2497
2581
|
return /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
levelEl,
|
|
2582
|
+
" ",
|
|
2583
|
+
dot,
|
|
2501
2584
|
" ",
|
|
2502
|
-
entry.message.slice(0,
|
|
2585
|
+
entry.message.slice(0, 70),
|
|
2586
|
+
" ",
|
|
2587
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: entry.time })
|
|
2503
2588
|
] }, i);
|
|
2504
2589
|
}) })
|
|
2505
2590
|
] });
|
|
2506
2591
|
}
|
|
2507
2592
|
|
|
2508
|
-
// src/cli/dashboard/
|
|
2593
|
+
// src/cli/dashboard/views/ChatView.tsx
|
|
2594
|
+
import { useCallback as useCallback5 } from "react";
|
|
2595
|
+
import { Box as Box11, Text as Text11, useInput as useInput7 } from "ink";
|
|
2509
2596
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2510
|
-
|
|
2597
|
+
function ChatView() {
|
|
2598
|
+
const { state, dispatch } = useDashboard();
|
|
2599
|
+
const { chatState } = state;
|
|
2600
|
+
const { messages, inputBuffer, loading } = chatState;
|
|
2601
|
+
const sendMessage = useCallback5(async (question) => {
|
|
2602
|
+
dispatch({ type: "ADD_CHAT_MESSAGE", role: "user", content: question });
|
|
2603
|
+
dispatch({ type: "SET_CHAT_INPUT", buffer: "" });
|
|
2604
|
+
dispatch({ type: "SET_CHAT_LOADING", loading: true });
|
|
2605
|
+
try {
|
|
2606
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
2607
|
+
const storage = new TieredStorage(workDir);
|
|
2608
|
+
const graph = new ContextGraph(workDir);
|
|
2609
|
+
const [decisions, blockers, snap] = await Promise.all([
|
|
2610
|
+
storage.queryDecisions({ limit: 10 }),
|
|
2611
|
+
storage.queryBlockers({ limit: 5 }),
|
|
2612
|
+
graph.getSnapshot()
|
|
2613
|
+
]);
|
|
2614
|
+
const contextParts = [];
|
|
2615
|
+
if (decisions.length > 0) {
|
|
2616
|
+
contextParts.push("Recent decisions:\n" + decisions.map(
|
|
2617
|
+
(d) => `- ${d.decision} (${d.when}${d.hash ? `, hash: ${d.hash.slice(0, 8)}` : ""})`
|
|
2618
|
+
).join("\n"));
|
|
2619
|
+
}
|
|
2620
|
+
if (blockers.length > 0) {
|
|
2621
|
+
contextParts.push("Active blockers:\n" + blockers.map(
|
|
2622
|
+
(b) => `- ${b.blocker} [${b.impact}]`
|
|
2623
|
+
).join("\n"));
|
|
2624
|
+
}
|
|
2625
|
+
const fileNodes = snap.nodes.filter((n) => n.type === "file");
|
|
2626
|
+
const riskFiles = fileNodes.filter((n) => n.data && "riskLevel" in n.data && (n.data.riskLevel === "critical" || n.data.riskLevel === "high")).slice(0, 10);
|
|
2627
|
+
if (riskFiles.length > 0) {
|
|
2628
|
+
contextParts.push("High-risk files:\n" + riskFiles.map(
|
|
2629
|
+
(n) => `- ${n.data.path} (${n.data.riskLevel})`
|
|
2630
|
+
).join("\n"));
|
|
2631
|
+
}
|
|
2632
|
+
const patternNodes = snap.nodes.filter((n) => n.type === "pattern").slice(0, 5);
|
|
2633
|
+
if (patternNodes.length > 0) {
|
|
2634
|
+
contextParts.push("Learned patterns:\n" + patternNodes.map(
|
|
2635
|
+
(n) => `- ${n.data.description} (${Math.round(n.data.confidence * 100)}% confidence)`
|
|
2636
|
+
).join("\n"));
|
|
2637
|
+
}
|
|
2638
|
+
const contextBlock = contextParts.length > 0 ? contextParts.join("\n\n") : "No context data available yet.";
|
|
2639
|
+
const result = await runAIAnalysis({
|
|
2640
|
+
systemPrompt: `You are Trie, a code guardian assistant embedded in a TUI. Answer concisely based on the project context below. Reference specific decisions, patterns, and files when relevant.
|
|
2641
|
+
|
|
2642
|
+
Project context:
|
|
2643
|
+
${contextBlock}`,
|
|
2644
|
+
userPrompt: question,
|
|
2645
|
+
maxTokens: 1024,
|
|
2646
|
+
temperature: 0.4
|
|
2647
|
+
});
|
|
2648
|
+
if (result.success) {
|
|
2649
|
+
dispatch({ type: "ADD_CHAT_MESSAGE", role: "assistant", content: result.content });
|
|
2650
|
+
} else {
|
|
2651
|
+
dispatch({ type: "ADD_CHAT_MESSAGE", role: "assistant", content: result.error || "Failed to get a response." });
|
|
2652
|
+
}
|
|
2653
|
+
} catch (err) {
|
|
2654
|
+
dispatch({ type: "ADD_CHAT_MESSAGE", role: "assistant", content: `Error: ${err instanceof Error ? err.message : "unknown"}` });
|
|
2655
|
+
} finally {
|
|
2656
|
+
dispatch({ type: "SET_CHAT_LOADING", loading: false });
|
|
2657
|
+
}
|
|
2658
|
+
}, [dispatch]);
|
|
2659
|
+
useInput7((input, key) => {
|
|
2660
|
+
if (loading) return;
|
|
2661
|
+
if (key.return && inputBuffer.trim().length > 0) {
|
|
2662
|
+
void sendMessage(inputBuffer.trim());
|
|
2663
|
+
} else if (key.escape) {
|
|
2664
|
+
dispatch({ type: "SET_CHAT_INPUT", buffer: "" });
|
|
2665
|
+
} else if (key.backspace || key.delete) {
|
|
2666
|
+
dispatch({ type: "SET_CHAT_INPUT", buffer: inputBuffer.slice(0, -1) });
|
|
2667
|
+
} else if (input && !key.ctrl && !key.meta) {
|
|
2668
|
+
dispatch({ type: "SET_CHAT_INPUT", buffer: inputBuffer + input });
|
|
2669
|
+
}
|
|
2670
|
+
});
|
|
2671
|
+
if (!isAIAvailable()) {
|
|
2672
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
2673
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "Chat" }),
|
|
2674
|
+
" ",
|
|
2675
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Ask Trie anything" }),
|
|
2676
|
+
/* @__PURE__ */ jsx12(Text11, { children: " " }),
|
|
2677
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " AI is not available." }),
|
|
2678
|
+
/* @__PURE__ */ jsxs11(Text11, { dimColor: true, children: [
|
|
2679
|
+
" Press ",
|
|
2680
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "c" }),
|
|
2681
|
+
" to open settings and add your Anthropic API key,"
|
|
2682
|
+
] }),
|
|
2683
|
+
/* @__PURE__ */ jsxs11(Text11, { dimColor: true, children: [
|
|
2684
|
+
" or set ",
|
|
2685
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "ANTHROPIC_API_KEY" }),
|
|
2686
|
+
" in your environment."
|
|
2687
|
+
] })
|
|
2688
|
+
] });
|
|
2689
|
+
}
|
|
2690
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
2691
|
+
/* @__PURE__ */ jsxs11(Text11, { children: [
|
|
2692
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "Chat" }),
|
|
2693
|
+
" ",
|
|
2694
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Ask Trie anything" })
|
|
2695
|
+
] }),
|
|
2696
|
+
/* @__PURE__ */ jsx12(Text11, { children: " " }),
|
|
2697
|
+
messages.length === 0 && !loading && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
2698
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " Ask about your codebase, decisions, patterns, or risks." }),
|
|
2699
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " Trie uses your context graph and decision ledger to answer." }),
|
|
2700
|
+
/* @__PURE__ */ jsx12(Text11, { children: " " })
|
|
2701
|
+
] }),
|
|
2702
|
+
messages.map((msg, idx) => /* @__PURE__ */ jsx12(Box11, { flexDirection: "column", marginBottom: 1, children: msg.role === "user" ? /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
2703
|
+
" ",
|
|
2704
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "green", children: "You:" }),
|
|
2705
|
+
" ",
|
|
2706
|
+
msg.content
|
|
2707
|
+
] }) : /* @__PURE__ */ jsx12(Box11, { flexDirection: "column", children: /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
2708
|
+
" ",
|
|
2709
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "Trie:" }),
|
|
2710
|
+
" ",
|
|
2711
|
+
msg.content.slice(0, 500),
|
|
2712
|
+
msg.content.length > 500 ? "..." : ""
|
|
2713
|
+
] }) }) }, idx)),
|
|
2714
|
+
loading && /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
2715
|
+
" ",
|
|
2716
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Thinking..." })
|
|
2717
|
+
] }),
|
|
2718
|
+
/* @__PURE__ */ jsx12(Box11, { flexGrow: 1 }),
|
|
2719
|
+
/* @__PURE__ */ jsx12(Box11, { borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
2720
|
+
inputBuffer || /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Ask a question..." }),
|
|
2721
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "green", children: "|" })
|
|
2722
|
+
] }) }),
|
|
2723
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " enter send esc clear" })
|
|
2724
|
+
] });
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2727
|
+
// src/cli/dashboard/App.tsx
|
|
2728
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2729
|
+
var MAIN_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
2511
2730
|
function DashboardApp({ onReady }) {
|
|
2512
2731
|
const { state, dispatch } = useDashboard();
|
|
2513
2732
|
const { exit } = useApp();
|
|
2514
|
-
const [showConfig, setShowConfig] =
|
|
2733
|
+
const [showConfig, setShowConfig] = useState3(false);
|
|
2515
2734
|
const dispatchRef = useRef(dispatch);
|
|
2516
2735
|
dispatchRef.current = dispatch;
|
|
2517
2736
|
const stateRef = useRef(state);
|
|
2518
2737
|
stateRef.current = state;
|
|
2519
2738
|
const configPath = join(getTrieDirectory(getWorkingDirectory(void 0, true)), "agent.json");
|
|
2520
|
-
const loadConfig =
|
|
2739
|
+
const loadConfig = useCallback6(async () => {
|
|
2521
2740
|
if (!existsSync(configPath)) return;
|
|
2522
2741
|
try {
|
|
2523
2742
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -2526,14 +2745,14 @@ function DashboardApp({ onReady }) {
|
|
|
2526
2745
|
} catch {
|
|
2527
2746
|
}
|
|
2528
2747
|
}, [configPath]);
|
|
2529
|
-
const persistConfig =
|
|
2748
|
+
const persistConfig = useCallback6(async () => {
|
|
2530
2749
|
try {
|
|
2531
2750
|
await mkdir(getTrieDirectory(getWorkingDirectory(void 0, true)), { recursive: true });
|
|
2532
2751
|
await writeFile(configPath, JSON.stringify(stateRef.current.agentConfig, null, 2), "utf-8");
|
|
2533
2752
|
} catch {
|
|
2534
2753
|
}
|
|
2535
2754
|
}, [configPath]);
|
|
2536
|
-
const processInsights =
|
|
2755
|
+
const processInsights = useCallback6(async (issues) => {
|
|
2537
2756
|
try {
|
|
2538
2757
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2539
2758
|
const trieAgent = getGuardian(workDir);
|
|
@@ -2559,7 +2778,7 @@ function DashboardApp({ onReady }) {
|
|
|
2559
2778
|
dispatchRef.current({ type: "ADD_ACTIVITY", message: `Trie Agent error: ${error instanceof Error ? error.message : "unknown"}` });
|
|
2560
2779
|
}
|
|
2561
2780
|
}, []);
|
|
2562
|
-
const refreshGoals =
|
|
2781
|
+
const refreshGoals = useCallback6(async () => {
|
|
2563
2782
|
try {
|
|
2564
2783
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2565
2784
|
const agentState = getGuardianState(workDir);
|
|
@@ -2575,7 +2794,7 @@ function DashboardApp({ onReady }) {
|
|
|
2575
2794
|
} catch {
|
|
2576
2795
|
}
|
|
2577
2796
|
}, []);
|
|
2578
|
-
const refreshHypotheses =
|
|
2797
|
+
const refreshHypotheses = useCallback6(async () => {
|
|
2579
2798
|
try {
|
|
2580
2799
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2581
2800
|
const agentState = getGuardianState(workDir);
|
|
@@ -2591,7 +2810,7 @@ function DashboardApp({ onReady }) {
|
|
|
2591
2810
|
} catch {
|
|
2592
2811
|
}
|
|
2593
2812
|
}, []);
|
|
2594
|
-
|
|
2813
|
+
useEffect4(() => {
|
|
2595
2814
|
void loadConfig();
|
|
2596
2815
|
void refreshGoals();
|
|
2597
2816
|
void refreshHypotheses();
|
|
@@ -2632,16 +2851,24 @@ function DashboardApp({ onReady }) {
|
|
|
2632
2851
|
outputManager.setMode("console");
|
|
2633
2852
|
};
|
|
2634
2853
|
}, [loadConfig, onReady, processInsights, refreshGoals, refreshHypotheses]);
|
|
2635
|
-
|
|
2854
|
+
useEffect4(() => {
|
|
2636
2855
|
const interval = setInterval(() => {
|
|
2637
2856
|
dispatchRef.current({ type: "AUTO_DISMISS_NOTIFICATIONS" });
|
|
2638
2857
|
}, 5e3);
|
|
2639
2858
|
return () => clearInterval(interval);
|
|
2640
2859
|
}, []);
|
|
2641
|
-
|
|
2860
|
+
useInput8((input, key) => {
|
|
2642
2861
|
if (showConfig) return;
|
|
2643
2862
|
if (state.view === "goals" && state.goalsPanel.inputMode === "add") return;
|
|
2644
2863
|
if (state.view === "hypotheses" && state.hypothesesPanel.inputMode === "add") return;
|
|
2864
|
+
if (state.view === "chat") {
|
|
2865
|
+
if (key.tab) {
|
|
2866
|
+
const currentIndex = MAIN_VIEWS.indexOf(state.view);
|
|
2867
|
+
const nextIndex = (currentIndex + 1) % MAIN_VIEWS.length;
|
|
2868
|
+
dispatch({ type: "SET_VIEW", view: MAIN_VIEWS[nextIndex] || "overview" });
|
|
2869
|
+
}
|
|
2870
|
+
return;
|
|
2871
|
+
}
|
|
2645
2872
|
if (input === "q" || key.escape) {
|
|
2646
2873
|
exit();
|
|
2647
2874
|
process.exit(0);
|
|
@@ -2652,7 +2879,7 @@ function DashboardApp({ onReady }) {
|
|
|
2652
2879
|
dispatch({ type: "SET_VIEW", view: MAIN_VIEWS[nextIndex] || "overview" });
|
|
2653
2880
|
return;
|
|
2654
2881
|
}
|
|
2655
|
-
if (input === "
|
|
2882
|
+
if (input === "s") {
|
|
2656
2883
|
setShowConfig(true);
|
|
2657
2884
|
return;
|
|
2658
2885
|
}
|
|
@@ -2678,6 +2905,10 @@ function DashboardApp({ onReady }) {
|
|
|
2678
2905
|
dispatch({ type: "SET_VIEW", view: "memory" });
|
|
2679
2906
|
return;
|
|
2680
2907
|
}
|
|
2908
|
+
if (input === "c") {
|
|
2909
|
+
dispatch({ type: "SET_VIEW", view: "chat" });
|
|
2910
|
+
return;
|
|
2911
|
+
}
|
|
2681
2912
|
if (state.view === "agent" || state.view === "memory") return;
|
|
2682
2913
|
if (input === "b") dispatch({ type: "GO_BACK" });
|
|
2683
2914
|
if (input === "n") dispatch({ type: "NEXT_PAGE" });
|
|
@@ -2686,38 +2917,41 @@ function DashboardApp({ onReady }) {
|
|
|
2686
2917
|
let viewComponent;
|
|
2687
2918
|
switch (state.view) {
|
|
2688
2919
|
case "overview":
|
|
2689
|
-
viewComponent = /* @__PURE__ */
|
|
2920
|
+
viewComponent = /* @__PURE__ */ jsx13(OverviewView, {});
|
|
2690
2921
|
break;
|
|
2691
2922
|
case "agent":
|
|
2692
|
-
viewComponent = /* @__PURE__ */
|
|
2923
|
+
viewComponent = /* @__PURE__ */ jsx13(AgentView, {});
|
|
2693
2924
|
break;
|
|
2694
2925
|
case "goals":
|
|
2695
|
-
viewComponent = /* @__PURE__ */
|
|
2926
|
+
viewComponent = /* @__PURE__ */ jsx13(GoalsView, {});
|
|
2696
2927
|
break;
|
|
2697
2928
|
case "hypotheses":
|
|
2698
|
-
viewComponent = /* @__PURE__ */
|
|
2929
|
+
viewComponent = /* @__PURE__ */ jsx13(HypothesesView, {});
|
|
2699
2930
|
break;
|
|
2700
2931
|
case "memory":
|
|
2701
|
-
viewComponent = /* @__PURE__ */
|
|
2932
|
+
viewComponent = /* @__PURE__ */ jsx13(MemoryTreeView, {});
|
|
2702
2933
|
break;
|
|
2703
2934
|
case "rawlog":
|
|
2704
|
-
viewComponent = /* @__PURE__ */
|
|
2935
|
+
viewComponent = /* @__PURE__ */ jsx13(RawLogView, {});
|
|
2936
|
+
break;
|
|
2937
|
+
case "chat":
|
|
2938
|
+
viewComponent = /* @__PURE__ */ jsx13(ChatView, {});
|
|
2705
2939
|
break;
|
|
2706
2940
|
default:
|
|
2707
|
-
viewComponent = /* @__PURE__ */
|
|
2941
|
+
viewComponent = /* @__PURE__ */ jsx13(OverviewView, {});
|
|
2708
2942
|
}
|
|
2709
|
-
return /* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
2712
|
-
/* @__PURE__ */
|
|
2943
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", height: process.stdout.rows || 40, children: [
|
|
2944
|
+
/* @__PURE__ */ jsx13(Header, {}),
|
|
2945
|
+
/* @__PURE__ */ jsx13(Notification, {}),
|
|
2946
|
+
/* @__PURE__ */ jsx13(Box12, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: showConfig ? /* @__PURE__ */ jsx13(ConfigDialog, { onClose: () => {
|
|
2713
2947
|
setShowConfig(false);
|
|
2714
2948
|
void persistConfig();
|
|
2715
2949
|
} }) : viewComponent }),
|
|
2716
|
-
/* @__PURE__ */
|
|
2950
|
+
/* @__PURE__ */ jsx13(Footer, {})
|
|
2717
2951
|
] });
|
|
2718
2952
|
}
|
|
2719
2953
|
function App({ onReady }) {
|
|
2720
|
-
return /* @__PURE__ */
|
|
2954
|
+
return /* @__PURE__ */ jsx13(DashboardProvider, { children: /* @__PURE__ */ jsx13(DashboardApp, { onReady }) });
|
|
2721
2955
|
}
|
|
2722
2956
|
|
|
2723
2957
|
// src/cli/dashboard/index.ts
|
|
@@ -2727,7 +2961,7 @@ var InteractiveDashboard = class {
|
|
|
2727
2961
|
getConfigFn = null;
|
|
2728
2962
|
async start() {
|
|
2729
2963
|
this.app = render(
|
|
2730
|
-
|
|
2964
|
+
React10.createElement(App, {
|
|
2731
2965
|
onReady: (handler, getConfig) => {
|
|
2732
2966
|
this.updateHandler = handler;
|
|
2733
2967
|
this.getConfigFn = getConfig;
|
|
@@ -2761,4 +2995,4 @@ export {
|
|
|
2761
2995
|
getOutputManager,
|
|
2762
2996
|
InteractiveDashboard
|
|
2763
2997
|
};
|
|
2764
|
-
//# sourceMappingURL=chunk-
|
|
2998
|
+
//# sourceMappingURL=chunk-3YDNSKKP.js.map
|