@triedotdev/mcp 1.0.136 → 1.0.138
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/{autonomy-config-QA6ATWLJ.js → autonomy-config-TZ6HF4FA.js} +3 -3
- package/dist/{chat-store-HFOOWZYN.js → chat-store-OJLJCJFI.js} +3 -3
- package/dist/{chunk-DFPVUMVE.js → chunk-23RJT5WT.js} +5 -4
- package/dist/chunk-23RJT5WT.js.map +1 -0
- package/dist/{chunk-4YJ6KLGI.js → chunk-3MUCUZ46.js} +8 -8
- package/dist/chunk-3MUCUZ46.js.map +1 -0
- package/dist/{chunk-6VIMBFUZ.js → chunk-3RRXWX3V.js} +21 -17
- package/dist/chunk-3RRXWX3V.js.map +1 -0
- package/dist/{chunk-WHIQAGB7.js → chunk-4C67GV3O.js} +2 -2
- package/dist/{chunk-WS6OA7H6.js → chunk-4MJ52WBH.js} +2 -3
- package/dist/chunk-4MJ52WBH.js.map +1 -0
- package/dist/{chunk-AJ34GCMD.js → chunk-67GSG2ST.js} +41 -38
- package/dist/chunk-67GSG2ST.js.map +1 -0
- package/dist/{chunk-UHX4462X.js → chunk-6LLH3TBZ.js} +24 -25
- package/dist/chunk-6LLH3TBZ.js.map +1 -0
- package/dist/{chunk-DFHMB44X.js → chunk-D3AS5LY7.js} +6 -10
- package/dist/chunk-D3AS5LY7.js.map +1 -0
- package/dist/{chunk-6OUWNVLX.js → chunk-EDDT4ZIH.js} +8 -8
- package/dist/chunk-EDDT4ZIH.js.map +1 -0
- package/dist/{chunk-Z4DN527J.js → chunk-FG467PDD.js} +156 -39
- package/dist/chunk-FG467PDD.js.map +1 -0
- package/dist/{chunk-T4THB2OR.js → chunk-FOCXXIXY.js} +49 -28
- package/dist/chunk-FOCXXIXY.js.map +1 -0
- package/dist/{goal-validator-PDKYZSNP.js → chunk-GFFUDJMK.js} +97 -40
- package/dist/chunk-GFFUDJMK.js.map +1 -0
- package/dist/{chunk-ZEXMMTIQ.js → chunk-J5EMP4XW.js} +2 -2
- package/dist/{chunk-UHMMANC2.js → chunk-LT6VUZG2.js} +21 -18
- package/dist/chunk-LT6VUZG2.js.map +1 -0
- package/dist/{chunk-55CBWOEZ.js → chunk-QSWUPSLK.js} +2 -2
- package/dist/{chunk-45Y5TLQZ.js → chunk-SH7H3WRU.js} +3 -6
- package/dist/chunk-SH7H3WRU.js.map +1 -0
- package/dist/{chunk-VRLMTOB6.js → chunk-TIMIKBY2.js} +1 -1
- package/dist/chunk-TIMIKBY2.js.map +1 -0
- package/dist/{chunk-POHBQUG7.js → chunk-X3F5QDER.js} +1224 -448
- package/dist/chunk-X3F5QDER.js.map +1 -0
- package/dist/{chunk-O6OTJI3W.js → chunk-Y32FM3MR.js} +2 -2
- package/dist/{chunk-G5PRBQIQ.js → chunk-YOKQ25IW.js} +102 -82
- package/dist/chunk-YOKQ25IW.js.map +1 -0
- package/dist/{chunk-JAKMZI5S.js → chunk-Z2P4WST6.js} +291 -180
- package/dist/chunk-Z2P4WST6.js.map +1 -0
- package/dist/cli/create-agent.js +1 -1
- package/dist/cli/main.js +113 -86
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +19 -19
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{client-BZHI675W.js → client-JTU5TRLB.js} +3 -3
- package/dist/{codebase-index-CR6Q2HEI.js → codebase-index-FNJ4GCBE.js} +3 -3
- package/dist/{goal-manager-FAK7H4RR.js → goal-manager-6BJQ36AH.js} +7 -8
- package/dist/goal-validator-GISXYANK.js +22 -0
- package/dist/{graph-PAUZ5EMP.js → graph-X2FMRQLG.js} +3 -3
- package/dist/{hypothesis-L5446W36.js → hypothesis-K3KQJOXJ.js} +7 -8
- package/dist/{incident-index-ZCDSJ42L.js → incident-index-BWW2UEY7.js} +3 -3
- package/dist/index.js +343 -288
- package/dist/index.js.map +1 -1
- package/dist/{insight-store-F5KDBY5Y.js → insight-store-A5XXMFD6.js} +6 -6
- package/dist/issue-store-BO5OWLJW.js +32 -0
- package/dist/{output-manager-BOTMXSND.js → output-manager-DZO5LGSG.js} +2 -2
- package/dist/{tiered-storage-QW2G7GSG.js → tiered-storage-VZL7KK64.js} +3 -3
- package/dist/trie-agent-XMSGMD7E.js +26 -0
- package/dist/trie-agent-XMSGMD7E.js.map +1 -0
- package/dist/ui/chat.html +260 -67
- package/dist/ui/goals.html +246 -3
- package/dist/ui/hypotheses.html +248 -5
- package/dist/ui/ledger.html +252 -9
- package/dist/ui/nudges.html +244 -1
- package/package.json +1 -1
- package/dist/chunk-45Y5TLQZ.js.map +0 -1
- package/dist/chunk-4YJ6KLGI.js.map +0 -1
- package/dist/chunk-6OUWNVLX.js.map +0 -1
- package/dist/chunk-6VIMBFUZ.js.map +0 -1
- package/dist/chunk-AJ34GCMD.js.map +0 -1
- package/dist/chunk-DFHMB44X.js.map +0 -1
- package/dist/chunk-DFPVUMVE.js.map +0 -1
- package/dist/chunk-G5PRBQIQ.js.map +0 -1
- package/dist/chunk-JAKMZI5S.js.map +0 -1
- package/dist/chunk-PEJEYWVR.js +0 -135
- package/dist/chunk-PEJEYWVR.js.map +0 -1
- package/dist/chunk-POHBQUG7.js.map +0 -1
- package/dist/chunk-T4THB2OR.js.map +0 -1
- package/dist/chunk-UHMMANC2.js.map +0 -1
- package/dist/chunk-UHX4462X.js.map +0 -1
- package/dist/chunk-VRLMTOB6.js.map +0 -1
- package/dist/chunk-WS6OA7H6.js.map +0 -1
- package/dist/chunk-Z4DN527J.js.map +0 -1
- package/dist/goal-validator-PDKYZSNP.js.map +0 -1
- package/dist/guardian-agent-4RHGIXUD.js +0 -27
- package/dist/ledger-WKVJWHBX.js +0 -17
- /package/dist/{autonomy-config-QA6ATWLJ.js.map → autonomy-config-TZ6HF4FA.js.map} +0 -0
- /package/dist/{chat-store-HFOOWZYN.js.map → chat-store-OJLJCJFI.js.map} +0 -0
- /package/dist/{chunk-WHIQAGB7.js.map → chunk-4C67GV3O.js.map} +0 -0
- /package/dist/{chunk-ZEXMMTIQ.js.map → chunk-J5EMP4XW.js.map} +0 -0
- /package/dist/{chunk-55CBWOEZ.js.map → chunk-QSWUPSLK.js.map} +0 -0
- /package/dist/{chunk-O6OTJI3W.js.map → chunk-Y32FM3MR.js.map} +0 -0
- /package/dist/{client-BZHI675W.js.map → client-JTU5TRLB.js.map} +0 -0
- /package/dist/{codebase-index-CR6Q2HEI.js.map → codebase-index-FNJ4GCBE.js.map} +0 -0
- /package/dist/{goal-manager-FAK7H4RR.js.map → goal-manager-6BJQ36AH.js.map} +0 -0
- /package/dist/{graph-PAUZ5EMP.js.map → goal-validator-GISXYANK.js.map} +0 -0
- /package/dist/{guardian-agent-4RHGIXUD.js.map → graph-X2FMRQLG.js.map} +0 -0
- /package/dist/{hypothesis-L5446W36.js.map → hypothesis-K3KQJOXJ.js.map} +0 -0
- /package/dist/{incident-index-ZCDSJ42L.js.map → incident-index-BWW2UEY7.js.map} +0 -0
- /package/dist/{insight-store-F5KDBY5Y.js.map → insight-store-A5XXMFD6.js.map} +0 -0
- /package/dist/{ledger-WKVJWHBX.js.map → issue-store-BO5OWLJW.js.map} +0 -0
- /package/dist/{output-manager-BOTMXSND.js.map → output-manager-DZO5LGSG.js.map} +0 -0
- /package/dist/{tiered-storage-QW2G7GSG.js.map → tiered-storage-VZL7KK64.js.map} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
getTrieAgent
|
|
3
|
+
} from "./chunk-YOKQ25IW.js";
|
|
4
4
|
import {
|
|
5
5
|
getChatStore
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-23RJT5WT.js";
|
|
7
7
|
import {
|
|
8
8
|
LearningEngine,
|
|
9
9
|
exportToJson,
|
|
@@ -13,53 +13,56 @@ import {
|
|
|
13
13
|
perceiveCurrentChanges,
|
|
14
14
|
reasonAboutChangesHumanReadable,
|
|
15
15
|
saveCheckpoint
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-EDDT4ZIH.js";
|
|
17
17
|
import {
|
|
18
18
|
IncidentIndex
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-4C67GV3O.js";
|
|
20
20
|
import {
|
|
21
21
|
findCrossProjectPatterns
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-6LLH3TBZ.js";
|
|
23
|
+
import {
|
|
24
|
+
measureInitialGoalValue
|
|
25
|
+
} from "./chunk-GFFUDJMK.js";
|
|
23
26
|
import {
|
|
24
27
|
getKeyFromKeychain,
|
|
25
28
|
isAIAvailable,
|
|
26
29
|
runAIWithTools,
|
|
27
30
|
setAPIKey
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-Y32FM3MR.js";
|
|
29
32
|
import {
|
|
30
|
-
|
|
31
|
-
} from "./chunk-
|
|
33
|
+
getProjectState
|
|
34
|
+
} from "./chunk-LT6VUZG2.js";
|
|
32
35
|
import {
|
|
33
36
|
TieredStorage,
|
|
34
37
|
getStorage
|
|
35
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-FG467PDD.js";
|
|
36
39
|
import {
|
|
37
40
|
ContextGraph
|
|
38
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-QSWUPSLK.js";
|
|
39
42
|
import {
|
|
40
43
|
getOutputManager
|
|
41
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-TIMIKBY2.js";
|
|
42
45
|
import {
|
|
43
46
|
getLedgerBlocks
|
|
44
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-Z2P4WST6.js";
|
|
45
48
|
import {
|
|
46
49
|
getTrieDirectory,
|
|
47
50
|
getWorkingDirectory
|
|
48
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-SH7H3WRU.js";
|
|
49
52
|
import {
|
|
50
53
|
isInteractiveMode
|
|
51
54
|
} from "./chunk-APMV77PU.js";
|
|
52
55
|
|
|
53
56
|
// src/tools/scan.ts
|
|
57
|
+
var hasLoggedRefocus = false;
|
|
54
58
|
var TrieScanTool = class {
|
|
55
59
|
async execute(_input) {
|
|
56
|
-
if (!isInteractiveMode()) {
|
|
60
|
+
if (!isInteractiveMode() && !hasLoggedRefocus) {
|
|
61
|
+
hasLoggedRefocus = true;
|
|
57
62
|
console.error("Trie scan has been refocused on decision ledger");
|
|
58
63
|
console.error(" trie tell - report incidents");
|
|
59
64
|
console.error(" trie gotcha - predict risks");
|
|
60
65
|
console.error(" trie learn - learn from history");
|
|
61
|
-
} else {
|
|
62
|
-
getOutputManager().log("info", "Scan refocused on decision ledger");
|
|
63
66
|
}
|
|
64
67
|
return {
|
|
65
68
|
content: [{
|
|
@@ -300,7 +303,7 @@ import React11 from "react";
|
|
|
300
303
|
|
|
301
304
|
// src/cli/dashboard/App.tsx
|
|
302
305
|
import { useState as useState3, useEffect as useEffect5, useCallback as useCallback7, useRef as useRef2 } from "react";
|
|
303
|
-
import { Box as Box14, useInput as useInput10, useApp } from "ink";
|
|
306
|
+
import { Box as Box14, useInput as useInput10, useApp, useStdout as useStdout11 } from "ink";
|
|
304
307
|
|
|
305
308
|
// src/cli/dashboard/state.tsx
|
|
306
309
|
import React, { createContext, useContext, useReducer } from "react";
|
|
@@ -315,7 +318,7 @@ function getVisibleInsights(state) {
|
|
|
315
318
|
}
|
|
316
319
|
function getMemoryTreeNodes(state) {
|
|
317
320
|
const nodes = [];
|
|
318
|
-
const { expandedNodes, snapshot, globalPatterns,
|
|
321
|
+
const { expandedNodes, snapshot, globalPatterns, storageGovernance, storageGotchas, ledgerBlocks } = state.memoryTree;
|
|
319
322
|
const decisionNodes = snapshot?.nodes.filter((n) => n.type === "decision") ?? [];
|
|
320
323
|
const incidentNodes = snapshot?.nodes.filter((n) => n.type === "incident") ?? [];
|
|
321
324
|
const patternNodes = snapshot?.nodes.filter((n) => n.type === "pattern") ?? [];
|
|
@@ -324,7 +327,7 @@ function getMemoryTreeNodes(state) {
|
|
|
324
327
|
const risk = n.data.riskLevel;
|
|
325
328
|
return risk === "critical" || risk === "high";
|
|
326
329
|
});
|
|
327
|
-
const
|
|
330
|
+
const governance = storageGovernance.length > 0 ? storageGovernance : decisionNodes.map((n) => ({
|
|
328
331
|
id: n.id,
|
|
329
332
|
decision: n.data.decision,
|
|
330
333
|
context: n.data.context,
|
|
@@ -333,12 +336,16 @@ function getMemoryTreeNodes(state) {
|
|
|
333
336
|
}));
|
|
334
337
|
nodes.push({ id: "decisions", level: 0 });
|
|
335
338
|
if (expandedNodes.has("decisions")) {
|
|
336
|
-
|
|
339
|
+
governance.slice(0, 10).forEach((g) => nodes.push({ id: `decision-${g.id}`, level: 1 }));
|
|
337
340
|
}
|
|
338
341
|
nodes.push({ id: "incidents", level: 0 });
|
|
339
342
|
if (expandedNodes.has("incidents")) {
|
|
340
343
|
incidentNodes.slice(0, 10).forEach((n) => nodes.push({ id: `incident-${n.id}`, level: 1 }));
|
|
341
344
|
}
|
|
345
|
+
nodes.push({ id: "gotchas", level: 0 });
|
|
346
|
+
if (expandedNodes.has("gotchas")) {
|
|
347
|
+
storageGotchas.slice(0, 10).forEach((g) => nodes.push({ id: `gotcha-${g.id}`, level: 1 }));
|
|
348
|
+
}
|
|
342
349
|
nodes.push({ id: "patterns", level: 0 });
|
|
343
350
|
if (expandedNodes.has("patterns")) {
|
|
344
351
|
patternNodes.slice(0, 10).forEach((n) => nodes.push({ id: `pattern-${n.id}`, level: 1 }));
|
|
@@ -396,7 +403,7 @@ function handleStreamUpdate(state, update) {
|
|
|
396
403
|
if (update.data.severity === "critical" || update.data.severity === "serious") {
|
|
397
404
|
const icon = update.data.severity === "critical" ? "[!]" : "[x]";
|
|
398
405
|
const fileName = update.data.file?.split("/").pop() || "unknown";
|
|
399
|
-
s = addActivity(s, `${icon} ${update.data.severity.toUpperCase()}: ${update.data.message
|
|
406
|
+
s = addActivity(s, `${icon} ${update.data.severity.toUpperCase()}: ${update.data.message || fileName}`);
|
|
400
407
|
if (update.data.severity === "critical") {
|
|
401
408
|
s.alerts = { hasCritical: true, lastCriticalAt: update.timestamp };
|
|
402
409
|
}
|
|
@@ -421,7 +428,7 @@ function handleStreamUpdate(state, update) {
|
|
|
421
428
|
filesScannedSession: s.watch.filesScannedSession
|
|
422
429
|
};
|
|
423
430
|
if (update.data.watching !== void 0) {
|
|
424
|
-
s = addActivity(s, update.data.watching ? `[*] Watch mode: ACTIVE (${update.data.directories ?? 0}
|
|
431
|
+
s = addActivity(s, update.data.watching ? `[*] Watch mode: ACTIVE (${update.data.directories ?? 0} subdirectories in your project)` : "[*] Watch mode: OFF");
|
|
425
432
|
}
|
|
426
433
|
break;
|
|
427
434
|
case "watch_change": {
|
|
@@ -438,14 +445,14 @@ function handleStreamUpdate(state, update) {
|
|
|
438
445
|
}
|
|
439
446
|
case "signal_extracted": {
|
|
440
447
|
const se = { ...s.signalExtraction };
|
|
441
|
-
if (update.data.
|
|
448
|
+
if (update.data.governance) se.governanceExtracted += update.data.governance;
|
|
442
449
|
if (update.data.facts) se.factsExtracted += update.data.facts;
|
|
443
450
|
if (update.data.blockers) se.blockersExtracted += update.data.blockers;
|
|
444
451
|
if (update.data.questions) se.questionsExtracted += update.data.questions;
|
|
445
452
|
s.signalExtraction = se;
|
|
446
|
-
const total = (update.data.
|
|
453
|
+
const total = (update.data.governance || 0) + (update.data.facts || 0) + (update.data.blockers || 0) + (update.data.questions || 0);
|
|
447
454
|
if (total > 0) {
|
|
448
|
-
s = addActivity(s, `[+] Extracted ${total} signals (${update.data.
|
|
455
|
+
s = addActivity(s, `[+] Extracted ${total} signals (${update.data.governance}g, ${update.data.facts}f, ${update.data.blockers}b)`);
|
|
449
456
|
}
|
|
450
457
|
break;
|
|
451
458
|
}
|
|
@@ -571,7 +578,9 @@ function dashboardReducer(state, action) {
|
|
|
571
578
|
});
|
|
572
579
|
}
|
|
573
580
|
if (newOnes.length > 0) {
|
|
574
|
-
|
|
581
|
+
for (const insight of newOnes) {
|
|
582
|
+
s = addActivity(s, `Trie: ${insight.message}`);
|
|
583
|
+
}
|
|
575
584
|
}
|
|
576
585
|
return s;
|
|
577
586
|
}
|
|
@@ -615,7 +624,7 @@ function dashboardReducer(state, action) {
|
|
|
615
624
|
let s = { ...state, agentInsights: insights };
|
|
616
625
|
s.selectedInsight = Math.min(s.selectedInsight, Math.max(0, remaining.length - 1));
|
|
617
626
|
s.expandedInsight = s.expandedInsight === action.index ? null : s.expandedInsight;
|
|
618
|
-
s = addActivity(s, `Ignored: ${insight.message
|
|
627
|
+
s = addActivity(s, `Ignored: ${insight.message}`);
|
|
619
628
|
return s;
|
|
620
629
|
}
|
|
621
630
|
case "CLEAR_DISMISSED_INSIGHTS": {
|
|
@@ -641,6 +650,8 @@ function dashboardReducer(state, action) {
|
|
|
641
650
|
return { ...state, goalsPanel: { ...state.goalsPanel, inputBuffer: action.buffer } };
|
|
642
651
|
case "SELECT_GOAL":
|
|
643
652
|
return { ...state, goalsPanel: { ...state.goalsPanel, selectedIndex: action.index } };
|
|
653
|
+
case "SET_GOAL_SCANNING":
|
|
654
|
+
return { ...state, goalsPanel: { ...state.goalsPanel, scanningGoalId: action.goalId, scanningProgress: action.progress } };
|
|
644
655
|
case "SET_HYPOTHESES":
|
|
645
656
|
return { ...state, hypothesesPanel: { ...state.hypothesesPanel, hypotheses: action.hypotheses } };
|
|
646
657
|
case "SET_HYPOTHESES_INPUT_MODE":
|
|
@@ -649,7 +660,12 @@ function dashboardReducer(state, action) {
|
|
|
649
660
|
return { ...state, hypothesesPanel: { ...state.hypothesesPanel, inputBuffer: action.buffer } };
|
|
650
661
|
case "SELECT_HYPOTHESIS":
|
|
651
662
|
return { ...state, hypothesesPanel: { ...state.hypothesesPanel, selectedIndex: action.index } };
|
|
652
|
-
case "SET_MEMORY_TREE":
|
|
663
|
+
case "SET_MEMORY_TREE": {
|
|
664
|
+
const blocks = action.ledgerBlocks ?? state.memoryTree.ledgerBlocks;
|
|
665
|
+
const gotchas = action.storageGotchas ?? state.memoryTree.storageGotchas;
|
|
666
|
+
const expanded = new Set(state.memoryTree.expandedNodes);
|
|
667
|
+
if (blocks.length > 0) expanded.add("ledger-chain");
|
|
668
|
+
if (gotchas.length > 0) expanded.add("gotchas");
|
|
653
669
|
return {
|
|
654
670
|
...state,
|
|
655
671
|
memoryTree: {
|
|
@@ -657,10 +673,15 @@ function dashboardReducer(state, action) {
|
|
|
657
673
|
loaded: true,
|
|
658
674
|
snapshot: action.snapshot,
|
|
659
675
|
globalPatterns: action.patterns,
|
|
660
|
-
|
|
661
|
-
|
|
676
|
+
storageGovernance: action.storageGovernance ?? state.memoryTree.storageGovernance,
|
|
677
|
+
storageGotchas: gotchas,
|
|
678
|
+
ledgerBlocks: blocks,
|
|
679
|
+
expandedNodes: expanded
|
|
662
680
|
}
|
|
663
681
|
};
|
|
682
|
+
}
|
|
683
|
+
case "INVALIDATE_MEMORY_TREE":
|
|
684
|
+
return { ...state, memoryTree: { ...state.memoryTree, loaded: false } };
|
|
664
685
|
case "SELECT_MEMORY_NODE":
|
|
665
686
|
return { ...state, memoryTree: { ...state.memoryTree, selectedNode: action.nodeId } };
|
|
666
687
|
case "SET_MEMORY_EXPANDED_ITEM":
|
|
@@ -669,8 +690,31 @@ function dashboardReducer(state, action) {
|
|
|
669
690
|
const expandable = ["decisions", "incidents", "patterns", "cross-project", "hotspots", "ledger-chain"];
|
|
670
691
|
if (expandable.includes(action.nodeId)) {
|
|
671
692
|
const expanded = new Set(state.memoryTree.expandedNodes);
|
|
672
|
-
if (expanded.has(action.nodeId))
|
|
673
|
-
|
|
693
|
+
if (expanded.has(action.nodeId)) {
|
|
694
|
+
if (action.nodeId === "ledger-chain" && state.memoryTree.ledgerBlocks.length > 0) {
|
|
695
|
+
return {
|
|
696
|
+
...state,
|
|
697
|
+
memoryTree: {
|
|
698
|
+
...state.memoryTree,
|
|
699
|
+
expandedItemId: "ledger-block-0",
|
|
700
|
+
selectedNode: "ledger-block-0"
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
expanded.delete(action.nodeId);
|
|
705
|
+
} else {
|
|
706
|
+
expanded.add(action.nodeId);
|
|
707
|
+
if (action.nodeId === "ledger-chain" && state.memoryTree.ledgerBlocks.length > 0) {
|
|
708
|
+
return {
|
|
709
|
+
...state,
|
|
710
|
+
memoryTree: {
|
|
711
|
+
...state.memoryTree,
|
|
712
|
+
expandedNodes: expanded,
|
|
713
|
+
selectedNode: "ledger-block-0"
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
}
|
|
674
718
|
return { ...state, memoryTree: { ...state.memoryTree, expandedNodes: expanded } };
|
|
675
719
|
}
|
|
676
720
|
const current = state.memoryTree.expandedItemId;
|
|
@@ -683,7 +727,7 @@ function dashboardReducer(state, action) {
|
|
|
683
727
|
agentBrain: {
|
|
684
728
|
...state.agentBrain,
|
|
685
729
|
loaded: true,
|
|
686
|
-
|
|
730
|
+
governance: action.governance,
|
|
687
731
|
patterns: action.patterns,
|
|
688
732
|
ledgerHash: action.ledgerHash
|
|
689
733
|
}
|
|
@@ -864,7 +908,7 @@ function createInitialState() {
|
|
|
864
908
|
quietMode: false,
|
|
865
909
|
signalExtraction: {
|
|
866
910
|
enabled: !!process.env["ANTHROPIC_API_KEY"],
|
|
867
|
-
|
|
911
|
+
governanceExtracted: 0,
|
|
868
912
|
factsExtracted: 0,
|
|
869
913
|
blockersExtracted: 0,
|
|
870
914
|
questionsExtracted: 0
|
|
@@ -893,10 +937,10 @@ function createInitialState() {
|
|
|
893
937
|
riskThresholds: { critical: 70, high: 40, medium: 20 },
|
|
894
938
|
aiWatcher: { enabled: true, hourlyTokenLimit: 5e4, scanCooldownSec: 30, cleanFileCooldownSec: 300, maxFilesPerScan: 5, maxCharsPerFile: 4e3 }
|
|
895
939
|
},
|
|
896
|
-
goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
940
|
+
goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningGoalId: null, scanningProgress: "" },
|
|
897
941
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
898
|
-
memoryTree: { loaded: false, snapshot: null, globalPatterns: [],
|
|
899
|
-
agentBrain: { loaded: false,
|
|
942
|
+
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], storageGovernance: [], storageGotchas: [], ledgerBlocks: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), expandedItemId: null, selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
943
|
+
agentBrain: { loaded: false, governance: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
|
|
900
944
|
chatState: { messages: [], inputBuffer: "", loading: false, progress: null, messageQueue: [], currentSessionId: null, currentSessionTitle: null },
|
|
901
945
|
chatArchivePanel: { sessions: [], selectedIndex: 0, showArchived: false, loading: false, inputMode: "browse", inputBuffer: "" },
|
|
902
946
|
pendingFixes: [],
|
|
@@ -929,7 +973,7 @@ function Header() {
|
|
|
929
973
|
const { stdout } = useStdout();
|
|
930
974
|
const cols = stdout?.columns || 80;
|
|
931
975
|
const narrow = cols < 50;
|
|
932
|
-
const totalExtracted = signalExtraction.
|
|
976
|
+
const totalExtracted = signalExtraction.governanceExtracted + signalExtraction.factsExtracted + signalExtraction.blockersExtracted + signalExtraction.questionsExtracted;
|
|
933
977
|
let status;
|
|
934
978
|
if (watch.watching) {
|
|
935
979
|
status = totalExtracted > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
@@ -1020,7 +1064,9 @@ var CONTEXT_HINTS_SHORT = {
|
|
|
1020
1064
|
};
|
|
1021
1065
|
function Footer() {
|
|
1022
1066
|
const { state } = useDashboard();
|
|
1023
|
-
const { view, goalsPanel, hypothesesPanel, unreadNudgesCount } = state;
|
|
1067
|
+
const { view, goalsPanel, hypothesesPanel, unreadNudgesCount, memoryTree } = state;
|
|
1068
|
+
const incidentSelected = view === "memory" && (memoryTree.selectedNode?.startsWith("incident-") || memoryTree.expandedItemId?.startsWith("incident-"));
|
|
1069
|
+
const ledgerBlockSelected = view === "memory" && memoryTree.selectedNode?.startsWith("ledger-block-");
|
|
1024
1070
|
const { stdout } = useStdout2();
|
|
1025
1071
|
const cols = stdout?.columns || 80;
|
|
1026
1072
|
const narrow = cols < 60;
|
|
@@ -1040,6 +1086,12 @@ function Footer() {
|
|
|
1040
1086
|
const insight = alerts[state.selectedInsight];
|
|
1041
1087
|
const isFixable = insight && parseGoalViolation(insight.message);
|
|
1042
1088
|
hints = isFixable ? narrow ? "/ f" : "/ help \xB7 f fix" : (narrow ? CONTEXT_HINTS_SHORT : CONTEXT_HINTS).agent ?? (narrow ? "/" : "/ help");
|
|
1089
|
+
} else if (incidentSelected) {
|
|
1090
|
+
hints = narrow ? "d r" : "d delete \xB7 r resolve";
|
|
1091
|
+
} else if (ledgerBlockSelected) {
|
|
1092
|
+
hints = narrow ? "enter" : "Enter details \xB7 Esc close";
|
|
1093
|
+
} else if (view === "goals" && goalsPanel.goals.filter((g) => g.status === "achieved").length > 0 && goalsPanel.goals.filter((g) => g.status === "active").length === 0) {
|
|
1094
|
+
hints = narrow ? "U" : "U reactivate all achieved";
|
|
1043
1095
|
} else {
|
|
1044
1096
|
const hintMap = narrow ? CONTEXT_HINTS_SHORT : CONTEXT_HINTS;
|
|
1045
1097
|
hints = hintMap[view] || (narrow ? "/" : "/ help");
|
|
@@ -1056,14 +1108,11 @@ function Footer() {
|
|
|
1056
1108
|
" (",
|
|
1057
1109
|
unreadNudgesCount,
|
|
1058
1110
|
")"
|
|
1059
|
-
] }) : /* @__PURE__ */ jsx3(Text2, {
|
|
1060
|
-
!isLast && /* @__PURE__ */ jsx3(Text2, {
|
|
1111
|
+
] }) : /* @__PURE__ */ jsx3(Text2, { color: "green", children: labels[v] }),
|
|
1112
|
+
!isLast && /* @__PURE__ */ jsx3(Text2, { color: "green", children: " \xB7 " })
|
|
1061
1113
|
] }, v);
|
|
1062
1114
|
}) }),
|
|
1063
|
-
hints && /* @__PURE__ */
|
|
1064
|
-
hints,
|
|
1065
|
-
" \xB7 q quit"
|
|
1066
|
-
] })
|
|
1115
|
+
hints && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: hints })
|
|
1067
1116
|
] });
|
|
1068
1117
|
}
|
|
1069
1118
|
return /* @__PURE__ */ jsxs2(Box2, { paddingX: 1, justifyContent: "space-between", children: [
|
|
@@ -1077,33 +1126,26 @@ function Footer() {
|
|
|
1077
1126
|
" (",
|
|
1078
1127
|
unreadNudgesCount,
|
|
1079
1128
|
")"
|
|
1080
|
-
] }) : /* @__PURE__ */ jsx3(Text2, {
|
|
1081
|
-
!isLast && /* @__PURE__ */ jsx3(Text2, {
|
|
1129
|
+
] }) : /* @__PURE__ */ jsx3(Text2, { color: "green", children: labels[v] }),
|
|
1130
|
+
!isLast && /* @__PURE__ */ jsx3(Text2, { color: "green", children: " \xB7 " })
|
|
1082
1131
|
] }, v);
|
|
1083
1132
|
}) }),
|
|
1084
|
-
hints && /* @__PURE__ */
|
|
1085
|
-
hints,
|
|
1086
|
-
" \xB7 q quit"
|
|
1087
|
-
] })
|
|
1133
|
+
hints && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: hints })
|
|
1088
1134
|
] });
|
|
1089
1135
|
}
|
|
1090
1136
|
|
|
1091
1137
|
// src/cli/dashboard/components/Notification.tsx
|
|
1092
|
-
import { Box as Box3, Text as Text3
|
|
1138
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
1093
1139
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1094
1140
|
function Notification() {
|
|
1095
1141
|
const { state } = useDashboard();
|
|
1096
1142
|
const { notification } = state;
|
|
1097
|
-
const { stdout } = useStdout3();
|
|
1098
|
-
const cols = stdout?.columns || 80;
|
|
1099
1143
|
if (!notification || !notification.active) return null;
|
|
1100
1144
|
if (notification.autoHideAt && Date.now() > notification.autoHideAt) return null;
|
|
1101
1145
|
const color = notification.severity === "critical" ? "red" : notification.severity === "warning" ? "yellow" : "blue";
|
|
1102
|
-
const maxMsgLen = Math.max(20, cols - 8);
|
|
1103
|
-
const msg = notification.message.length > maxMsgLen ? notification.message.slice(0, maxMsgLen - 1) + "..." : notification.message;
|
|
1104
1146
|
return /* @__PURE__ */ jsxs3(Box3, { paddingX: 1, children: [
|
|
1105
1147
|
/* @__PURE__ */ jsx4(Text3, { color, bold: true, children: "\u25CF " }),
|
|
1106
|
-
/* @__PURE__ */ jsx4(Text3, { wrap: "
|
|
1148
|
+
/* @__PURE__ */ jsx4(Text3, { wrap: "wrap", children: notification.message })
|
|
1107
1149
|
] });
|
|
1108
1150
|
}
|
|
1109
1151
|
|
|
@@ -1135,15 +1177,29 @@ function ConfigDialog({ onClose }) {
|
|
|
1135
1177
|
const loadStats = async () => {
|
|
1136
1178
|
try {
|
|
1137
1179
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1138
|
-
const { CodebaseIndex } = await import("./codebase-index-
|
|
1180
|
+
const { CodebaseIndex } = await import("./codebase-index-FNJ4GCBE.js");
|
|
1139
1181
|
const index = new CodebaseIndex(workDir);
|
|
1140
1182
|
const stats = index.getStats();
|
|
1183
|
+
let lastUpdatedDisplay = "Never";
|
|
1184
|
+
if (stats.lastUpdated) {
|
|
1185
|
+
try {
|
|
1186
|
+
const date = new Date(stats.lastUpdated);
|
|
1187
|
+
lastUpdatedDisplay = date.toLocaleString("en-US", {
|
|
1188
|
+
month: "short",
|
|
1189
|
+
day: "numeric",
|
|
1190
|
+
hour: "numeric",
|
|
1191
|
+
minute: "2-digit"
|
|
1192
|
+
});
|
|
1193
|
+
} catch {
|
|
1194
|
+
lastUpdatedDisplay = "Unknown";
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1141
1197
|
setIndexStats({
|
|
1142
|
-
fileCount: stats.
|
|
1143
|
-
lastUpdated:
|
|
1198
|
+
fileCount: stats.totalFiles,
|
|
1199
|
+
lastUpdated: lastUpdatedDisplay
|
|
1144
1200
|
});
|
|
1145
1201
|
} catch {
|
|
1146
|
-
setIndexStats(
|
|
1202
|
+
setIndexStats({ fileCount: 0, lastUpdated: "Never" });
|
|
1147
1203
|
}
|
|
1148
1204
|
};
|
|
1149
1205
|
void loadStats();
|
|
@@ -1292,11 +1348,11 @@ function ConfigDialog({ onClose }) {
|
|
|
1292
1348
|
const loadStats = async () => {
|
|
1293
1349
|
try {
|
|
1294
1350
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1295
|
-
const { CodebaseIndex } = await import("./codebase-index-
|
|
1351
|
+
const { CodebaseIndex } = await import("./codebase-index-FNJ4GCBE.js");
|
|
1296
1352
|
const index = new CodebaseIndex(workDir);
|
|
1297
1353
|
const stats = index.getStats();
|
|
1298
1354
|
setIndexStats({
|
|
1299
|
-
fileCount: stats.
|
|
1355
|
+
fileCount: stats.totalFiles,
|
|
1300
1356
|
lastUpdated: stats.lastUpdated || "Never"
|
|
1301
1357
|
});
|
|
1302
1358
|
} catch {
|
|
@@ -1367,7 +1423,7 @@ function ConfigDialog({ onClose }) {
|
|
|
1367
1423
|
}
|
|
1368
1424
|
async function reindexCodebase() {
|
|
1369
1425
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1370
|
-
const { CodebaseIndex } = await import("./codebase-index-
|
|
1426
|
+
const { CodebaseIndex } = await import("./codebase-index-FNJ4GCBE.js");
|
|
1371
1427
|
const { glob } = await import("glob");
|
|
1372
1428
|
const index = new CodebaseIndex(workDir);
|
|
1373
1429
|
const indexPattern = `${workDir}/**/*.{ts,tsx,js,jsx,mjs,vue,svelte,astro,py,go,rs,java,c,cpp,h,hpp,cs,rb,php,css,scss,html}`;
|
|
@@ -1424,7 +1480,7 @@ function ConfigDialog({ onClose }) {
|
|
|
1424
1480
|
" ",
|
|
1425
1481
|
indexStats.lastUpdated
|
|
1426
1482
|
] }),
|
|
1427
|
-
/* @__PURE__ */ jsx5(
|
|
1483
|
+
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Actions:" }) })
|
|
1428
1484
|
] }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Loading index stats..." }),
|
|
1429
1485
|
codebaseIndexItems.map((item, idx) => {
|
|
1430
1486
|
const isSelected = selectedIndex === idx;
|
|
@@ -1437,7 +1493,7 @@ function ConfigDialog({ onClose }) {
|
|
|
1437
1493
|
] })
|
|
1438
1494
|
] }, item.key);
|
|
1439
1495
|
}),
|
|
1440
|
-
indexing ? /* @__PURE__ */ jsx5(
|
|
1496
|
+
indexing ? /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Re-indexing codebase..." }) }) : /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to execute \xB7 esc back" }) })
|
|
1441
1497
|
] }),
|
|
1442
1498
|
!showConfirmClear && section === "apiKeys" && !editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1443
1499
|
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
@@ -1478,7 +1534,7 @@ function ConfigDialog({ onClose }) {
|
|
|
1478
1534
|
}
|
|
1479
1535
|
|
|
1480
1536
|
// src/cli/dashboard/components/HelpDialog.tsx
|
|
1481
|
-
import { Box as Box5, Text as Text5 } from "ink";
|
|
1537
|
+
import { Box as Box5, Text as Text5, useStdout as useStdout3 } from "ink";
|
|
1482
1538
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1483
1539
|
var VIEW_HELP = {
|
|
1484
1540
|
overview: [
|
|
@@ -1509,6 +1565,8 @@ var VIEW_HELP = {
|
|
|
1509
1565
|
{ key: "r", description: "Run check on selected goal" },
|
|
1510
1566
|
{ key: "enter", description: "Mark goal as complete" },
|
|
1511
1567
|
{ key: "d", description: "Delete selected goal" },
|
|
1568
|
+
{ key: "u", description: "Reactivate most recent achieved" },
|
|
1569
|
+
{ key: "U", description: "Reactivate all achieved goals" },
|
|
1512
1570
|
{ key: "x", description: "Clear all achieved goals" },
|
|
1513
1571
|
{ key: "tab", description: "Navigate between views" },
|
|
1514
1572
|
{ key: "s", description: "Open Settings" },
|
|
@@ -1568,27 +1626,29 @@ var VIEW_HELP = {
|
|
|
1568
1626
|
function HelpDialog({ view }) {
|
|
1569
1627
|
const shortcuts = VIEW_HELP[view] || VIEW_HELP.overview;
|
|
1570
1628
|
const viewName = view.charAt(0).toUpperCase() + view.slice(1);
|
|
1629
|
+
const { stdout } = useStdout3();
|
|
1630
|
+
const cols = stdout?.columns || 80;
|
|
1631
|
+
const narrow = cols < 70;
|
|
1632
|
+
const dialogWidth = narrow ? "95%" : "80%";
|
|
1633
|
+
const keyWidth = narrow ? 10 : 12;
|
|
1571
1634
|
return /* @__PURE__ */ jsxs5(
|
|
1572
1635
|
Box5,
|
|
1573
1636
|
{
|
|
1574
1637
|
flexDirection: "column",
|
|
1575
1638
|
borderStyle: "round",
|
|
1576
1639
|
borderColor: "cyan",
|
|
1577
|
-
paddingX: 2,
|
|
1640
|
+
paddingX: narrow ? 1 : 2,
|
|
1578
1641
|
paddingY: 1,
|
|
1579
|
-
width:
|
|
1642
|
+
width: dialogWidth,
|
|
1580
1643
|
alignSelf: "center",
|
|
1581
|
-
marginTop: 2,
|
|
1644
|
+
marginTop: narrow ? 1 : 2,
|
|
1582
1645
|
children: [
|
|
1583
|
-
/* @__PURE__ */
|
|
1584
|
-
|
|
1585
|
-
"
|
|
1586
|
-
] }),
|
|
1587
|
-
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "column", gap: 0, children: shortcuts.map(({ key, description }, idx) => /* @__PURE__ */ jsxs5(Box5, { gap: 2, children: [
|
|
1588
|
-
/* @__PURE__ */ jsx6(Box5, { width: 12, children: /* @__PURE__ */ jsx6(Text5, { color: "yellow", children: key }) }),
|
|
1646
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: narrow ? `${viewName} Keys` : `${viewName} View - Keyboard Shortcuts` }),
|
|
1647
|
+
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "column", gap: 0, children: shortcuts.map(({ key, description }, idx) => /* @__PURE__ */ jsxs5(Box5, { gap: narrow ? 1 : 2, children: [
|
|
1648
|
+
/* @__PURE__ */ jsx6(Box5, { width: keyWidth, children: /* @__PURE__ */ jsx6(Text5, { color: "yellow", children: key }) }),
|
|
1589
1649
|
/* @__PURE__ */ jsx6(Text5, { children: description })
|
|
1590
1650
|
] }, idx)) }),
|
|
1591
|
-
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "Press / or ? again to close" }) })
|
|
1651
|
+
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: narrow ? "/ or ? to close" : "Press / or ? again to close" }) })
|
|
1592
1652
|
]
|
|
1593
1653
|
}
|
|
1594
1654
|
);
|
|
@@ -1641,10 +1701,10 @@ function OverviewView() {
|
|
|
1641
1701
|
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs6(Text6, { wrap: "truncate", children: [
|
|
1642
1702
|
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1643
1703
|
" Signal extraction",
|
|
1644
|
-
!narrow && (signalExtraction.
|
|
1704
|
+
!narrow && (signalExtraction.governanceExtracted > 0 || signalExtraction.factsExtracted > 0 || signalExtraction.blockersExtracted > 0) && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1645
1705
|
" ",
|
|
1646
|
-
signalExtraction.
|
|
1647
|
-
"
|
|
1706
|
+
signalExtraction.governanceExtracted,
|
|
1707
|
+
"g \xB7 ",
|
|
1648
1708
|
signalExtraction.factsExtracted,
|
|
1649
1709
|
"f \xB7 ",
|
|
1650
1710
|
signalExtraction.blockersExtracted,
|
|
@@ -1708,11 +1768,11 @@ function OverviewView() {
|
|
|
1708
1768
|
] }),
|
|
1709
1769
|
/* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, children: [
|
|
1710
1770
|
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Activity" }),
|
|
1711
|
-
pageActivities.map((entry, i) => /* @__PURE__ */ jsxs6(Text6, { wrap: "
|
|
1771
|
+
pageActivities.map((entry, i) => /* @__PURE__ */ jsxs6(Text6, { wrap: "wrap", children: [
|
|
1712
1772
|
" ",
|
|
1713
1773
|
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: entry.time }),
|
|
1714
1774
|
" ",
|
|
1715
|
-
|
|
1775
|
+
entry.message
|
|
1716
1776
|
] }, i)),
|
|
1717
1777
|
pageActivities.length === 0 && /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " No activity yet" })
|
|
1718
1778
|
] })
|
|
@@ -1760,7 +1820,7 @@ function progressBar(current, total, width = 10) {
|
|
|
1760
1820
|
}
|
|
1761
1821
|
|
|
1762
1822
|
// src/cli/dashboard/views/AgentView.tsx
|
|
1763
|
-
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1823
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1764
1824
|
function timeAgo(iso) {
|
|
1765
1825
|
const ms = Date.now() - new Date(iso).getTime();
|
|
1766
1826
|
const mins = Math.floor(ms / 6e4);
|
|
@@ -1774,21 +1834,23 @@ function AgentView() {
|
|
|
1774
1834
|
const { agentInsights, agentBrain, selectedInsight, expandedInsight } = state;
|
|
1775
1835
|
const { stdout } = useStdout5();
|
|
1776
1836
|
const cols = stdout?.columns || 80;
|
|
1837
|
+
const narrow = cols < 60;
|
|
1777
1838
|
const msgLen = Math.max(20, cols - 25);
|
|
1778
1839
|
const visibleInsights = getVisibleInsights(state);
|
|
1779
1840
|
const alerts = visibleInsights.filter((i) => i.type === "warning");
|
|
1780
|
-
const {
|
|
1841
|
+
const { governance, patterns, loaded } = agentBrain;
|
|
1842
|
+
const decisions = governance;
|
|
1781
1843
|
const loadBrain = useCallback(async () => {
|
|
1782
1844
|
try {
|
|
1783
1845
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1784
1846
|
const storage = new TieredStorage(workDir);
|
|
1785
1847
|
const graph = new ContextGraph(workDir);
|
|
1786
1848
|
const [decs, snap] = await Promise.all([
|
|
1787
|
-
storage.
|
|
1849
|
+
storage.queryGovernance({ limit: 20 }),
|
|
1788
1850
|
graph.getSnapshot()
|
|
1789
1851
|
]);
|
|
1790
1852
|
const patternData = snap.nodes.filter((n) => n.type === "pattern").map((n) => n.data);
|
|
1791
|
-
dispatch({ type: "SET_AGENT_BRAIN",
|
|
1853
|
+
dispatch({ type: "SET_AGENT_BRAIN", governance: decs, patterns: patternData, ledgerHash: null });
|
|
1792
1854
|
} catch {
|
|
1793
1855
|
dispatch({ type: "ADD_ACTIVITY", message: "Agent brain load error" });
|
|
1794
1856
|
}
|
|
@@ -1809,10 +1871,10 @@ function AgentView() {
|
|
|
1809
1871
|
if (!insight) return;
|
|
1810
1872
|
try {
|
|
1811
1873
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1812
|
-
const { getInsightStore } = await import("./insight-store-
|
|
1874
|
+
const { getInsightStore } = await import("./insight-store-A5XXMFD6.js");
|
|
1813
1875
|
const store = getInsightStore(workDir);
|
|
1814
1876
|
await store.dismissInsight(insight.id);
|
|
1815
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
1877
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-VZL7KK64.js");
|
|
1816
1878
|
const storage = getStorage2(workDir);
|
|
1817
1879
|
await storage.dismissNudge(insight.id).catch(() => {
|
|
1818
1880
|
});
|
|
@@ -1837,7 +1899,7 @@ function AgentView() {
|
|
|
1837
1899
|
file: parsed.file,
|
|
1838
1900
|
goal: parsed.goal,
|
|
1839
1901
|
violation: parsed.violation,
|
|
1840
|
-
suggestedFix: insight.suggestedAction
|
|
1902
|
+
...insight.suggestedAction ? { suggestedFix: insight.suggestedAction } : {},
|
|
1841
1903
|
cwd: workDir
|
|
1842
1904
|
});
|
|
1843
1905
|
dispatch({ type: "ADD_ACTIVITY", message: `Spawned Claude Code to fix ${parsed.file}` });
|
|
@@ -1881,7 +1943,10 @@ function AgentView() {
|
|
|
1881
1943
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 1, children: [
|
|
1882
1944
|
/* @__PURE__ */ jsxs7(Text7, { children: [
|
|
1883
1945
|
/* @__PURE__ */ jsx8(Text7, { bold: true, children: "Nudges" }),
|
|
1884
|
-
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1946
|
+
narrow ? /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1947
|
+
" ",
|
|
1948
|
+
alertCount
|
|
1949
|
+
] }) : /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1885
1950
|
" ",
|
|
1886
1951
|
alertCount,
|
|
1887
1952
|
" alerts \xB7 ",
|
|
@@ -1903,7 +1968,7 @@ function AgentView() {
|
|
|
1903
1968
|
riskColor ? /* @__PURE__ */ jsx8(Text7, { color: riskColor, children: "\u25CF" }) : /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "\u25CB" }),
|
|
1904
1969
|
" ",
|
|
1905
1970
|
isSelected ? /* @__PURE__ */ jsx8(Text7, { bold: true, children: msg }) : /* @__PURE__ */ jsx8(Text7, { children: msg }),
|
|
1906
|
-
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1971
|
+
narrow ? null : /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1907
1972
|
" ",
|
|
1908
1973
|
insight.category,
|
|
1909
1974
|
" \xB7 ",
|
|
@@ -1925,13 +1990,14 @@ function AgentView() {
|
|
|
1925
1990
|
decisions.slice(0, 10).map((dec) => {
|
|
1926
1991
|
const ago = timeAgo(dec.when);
|
|
1927
1992
|
const active = dec.status === "active";
|
|
1928
|
-
|
|
1993
|
+
const decWidth = Math.max(20, cols - 18);
|
|
1994
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
1929
1995
|
" ",
|
|
1930
1996
|
active ? /* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "\u25CB" }),
|
|
1931
1997
|
" ",
|
|
1932
|
-
dec.decision.slice(0,
|
|
1933
|
-
dec.decision.length >
|
|
1934
|
-
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1998
|
+
dec.decision.slice(0, decWidth),
|
|
1999
|
+
dec.decision.length > decWidth ? "..." : "",
|
|
2000
|
+
narrow ? null : /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1935
2001
|
" ",
|
|
1936
2002
|
ago
|
|
1937
2003
|
] })
|
|
@@ -1943,19 +2009,22 @@ function AgentView() {
|
|
|
1943
2009
|
patterns.slice(0, 8).map((pat, idx) => {
|
|
1944
2010
|
const conf = Math.round(pat.confidence * 100);
|
|
1945
2011
|
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
1946
|
-
|
|
2012
|
+
const patWidth = Math.max(20, cols - 18);
|
|
2013
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
1947
2014
|
" ",
|
|
1948
2015
|
pat.isAntiPattern ? /* @__PURE__ */ jsx8(Text7, { color: "red", children: "\u25CF" }) : /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "\u25CB" }),
|
|
1949
2016
|
" ",
|
|
1950
|
-
pat.description.slice(0,
|
|
1951
|
-
pat.description.length >
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
2017
|
+
pat.description.slice(0, patWidth),
|
|
2018
|
+
pat.description.length > patWidth ? "..." : "",
|
|
2019
|
+
narrow ? null : /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2020
|
+
" ",
|
|
2021
|
+
confColor ? /* @__PURE__ */ jsxs7(Text7, { color: confColor, children: [
|
|
2022
|
+
conf,
|
|
2023
|
+
"%"
|
|
2024
|
+
] }) : /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2025
|
+
conf,
|
|
2026
|
+
"%"
|
|
2027
|
+
] })
|
|
1959
2028
|
] })
|
|
1960
2029
|
] }, idx);
|
|
1961
2030
|
})
|
|
@@ -1980,13 +2049,19 @@ function AgentView() {
|
|
|
1980
2049
|
|
|
1981
2050
|
// src/cli/dashboard/views/GoalsView.tsx
|
|
1982
2051
|
import { useCallback as useCallback2 } from "react";
|
|
1983
|
-
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
1984
|
-
import { Fragment as
|
|
2052
|
+
import { Box as Box8, Text as Text8, useInput as useInput4, useStdout as useStdout6 } from "ink";
|
|
2053
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1985
2054
|
function calculateGoalProgress(goal) {
|
|
1986
|
-
if (goal.target
|
|
2055
|
+
if (goal.target === 0 && goal.currentValue === 0) return 100;
|
|
2056
|
+
if (goal.target === 0) {
|
|
2057
|
+
const startValue2 = goal.startValue ?? goal.currentValue;
|
|
2058
|
+
if (startValue2 === 0) return 0;
|
|
2059
|
+
return Math.round((1 - goal.currentValue / startValue2) * 100);
|
|
2060
|
+
}
|
|
1987
2061
|
const startValue = goal.startValue ?? goal.currentValue;
|
|
1988
2062
|
if (startValue > goal.target) {
|
|
1989
2063
|
const totalReduction = startValue - goal.target;
|
|
2064
|
+
if (totalReduction === 0) return 100;
|
|
1990
2065
|
const actualReduction = startValue - goal.currentValue;
|
|
1991
2066
|
return Math.round(actualReduction / totalReduction * 100);
|
|
1992
2067
|
}
|
|
@@ -1995,39 +2070,45 @@ function calculateGoalProgress(goal) {
|
|
|
1995
2070
|
function GoalsView() {
|
|
1996
2071
|
const { state, dispatch } = useDashboard();
|
|
1997
2072
|
const { goalsPanel } = state;
|
|
2073
|
+
const { stdout } = useStdout6();
|
|
2074
|
+
const cols = stdout?.columns || 80;
|
|
2075
|
+
const narrow = cols < 60;
|
|
2076
|
+
const contentWidth = Math.max(20, cols - 4);
|
|
1998
2077
|
const activeGoals = goalsPanel.goals.filter((g) => g.status === "active");
|
|
1999
2078
|
const achievedGoals = goalsPanel.goals.filter((g) => g.status === "achieved");
|
|
2000
2079
|
const otherGoals = goalsPanel.goals.filter((g) => g.status !== "active" && g.status !== "achieved" && g.status !== "rejected");
|
|
2001
2080
|
const refreshGoals = useCallback2(async () => {
|
|
2002
2081
|
try {
|
|
2003
2082
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2004
|
-
const agentState =
|
|
2083
|
+
const agentState = getProjectState(workDir);
|
|
2005
2084
|
await agentState.load();
|
|
2006
2085
|
const goals = agentState.getAllGoals();
|
|
2007
2086
|
dispatch({
|
|
2008
2087
|
type: "SET_GOALS",
|
|
2009
2088
|
goals: goals.map((g) => {
|
|
2010
|
-
const base = { id: g.id, description: g.description, type: g.type, target: g.target, currentValue: g.currentValue, status: g.status, autoGenerated: g.autoGenerated, updatedAt: g.updatedAt };
|
|
2011
|
-
return
|
|
2089
|
+
const base = { id: g.id, description: g.description, type: g.type, target: g.target, currentValue: g.currentValue, status: g.status, autoGenerated: g.autoGenerated, updatedAt: g.updatedAt, ...g.achievedAt != null ? { achievedAt: g.achievedAt } : {}, ...g.achievedBy != null ? { achievedBy: g.achievedBy } : {}, ...g.category != null ? { category: g.category } : {} };
|
|
2090
|
+
return base;
|
|
2012
2091
|
})
|
|
2013
2092
|
});
|
|
2014
|
-
} catch {
|
|
2093
|
+
} catch (err) {
|
|
2094
|
+
console.debug("[GoalsView] refreshGoals failed:", err);
|
|
2015
2095
|
}
|
|
2016
2096
|
}, [dispatch]);
|
|
2017
2097
|
const addGoal = useCallback2(async (description) => {
|
|
2018
2098
|
if (!description.trim()) return;
|
|
2019
2099
|
try {
|
|
2020
2100
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2021
|
-
const agentState =
|
|
2101
|
+
const agentState = getProjectState(workDir);
|
|
2022
2102
|
await agentState.load();
|
|
2103
|
+
const initialValue = await measureInitialGoalValue(description.trim(), workDir);
|
|
2023
2104
|
const goal = {
|
|
2024
2105
|
id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2025
2106
|
description: description.trim(),
|
|
2026
2107
|
type: "reduction",
|
|
2027
2108
|
metric: "semantic",
|
|
2028
2109
|
target: 0,
|
|
2029
|
-
currentValue:
|
|
2030
|
-
startValue:
|
|
2110
|
+
currentValue: initialValue,
|
|
2111
|
+
startValue: initialValue,
|
|
2031
2112
|
status: "active",
|
|
2032
2113
|
autoGenerated: false,
|
|
2033
2114
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -2035,52 +2116,85 @@ function GoalsView() {
|
|
|
2035
2116
|
deadline: new Date(Date.now() + 14 * 864e5).toISOString()
|
|
2036
2117
|
};
|
|
2037
2118
|
await agentState.addGoal(goal);
|
|
2038
|
-
dispatch({ type: "ADD_ACTIVITY", message: `Goal added: ${description
|
|
2119
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Goal added: ${description}` });
|
|
2039
2120
|
await refreshGoals();
|
|
2040
|
-
} catch {
|
|
2121
|
+
} catch (err) {
|
|
2122
|
+
console.debug("[GoalsView] addGoal failed:", err);
|
|
2041
2123
|
}
|
|
2042
2124
|
}, [dispatch, refreshGoals]);
|
|
2043
2125
|
const completeGoal = useCallback2(async (goalId) => {
|
|
2044
2126
|
try {
|
|
2045
2127
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2046
|
-
const agentState =
|
|
2128
|
+
const agentState = getProjectState(workDir);
|
|
2047
2129
|
await agentState.load();
|
|
2048
2130
|
const goals = agentState.getAllGoals();
|
|
2049
2131
|
const goal = goals.find((g) => g.id === goalId);
|
|
2050
2132
|
if (goal) {
|
|
2051
2133
|
await agentState.updateGoal(goalId, { status: "achieved", currentValue: goal.target, achievedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
2052
|
-
|
|
2134
|
+
const currentIndex = goalsPanel.selectedIndex;
|
|
2135
|
+
const newActiveCount = activeGoals.length - 1;
|
|
2136
|
+
const newIndex = Math.min(currentIndex, Math.max(0, newActiveCount - 1));
|
|
2137
|
+
dispatch({ type: "SELECT_GOAL", index: newIndex });
|
|
2138
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Goal achieved: ${goal.description}` });
|
|
2053
2139
|
await refreshGoals();
|
|
2054
2140
|
}
|
|
2055
|
-
} catch {
|
|
2141
|
+
} catch (err) {
|
|
2142
|
+
console.debug("[GoalsView] completeGoal failed:", err);
|
|
2056
2143
|
}
|
|
2057
|
-
}, [dispatch, refreshGoals]);
|
|
2144
|
+
}, [dispatch, refreshGoals, goalsPanel.selectedIndex, activeGoals.length]);
|
|
2058
2145
|
const deleteGoal = useCallback2(async (goalId) => {
|
|
2059
2146
|
try {
|
|
2060
2147
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2061
|
-
const agentState =
|
|
2148
|
+
const agentState = getProjectState(workDir);
|
|
2062
2149
|
await agentState.load();
|
|
2063
2150
|
await agentState.updateGoal(goalId, { status: "rejected" });
|
|
2151
|
+
const currentIndex = goalsPanel.selectedIndex;
|
|
2152
|
+
const newActiveCount = activeGoals.length - 1;
|
|
2153
|
+
const newIndex = Math.min(currentIndex, Math.max(0, newActiveCount - 1));
|
|
2154
|
+
dispatch({ type: "SELECT_GOAL", index: newIndex });
|
|
2064
2155
|
dispatch({ type: "ADD_ACTIVITY", message: "Goal removed" });
|
|
2065
2156
|
await refreshGoals();
|
|
2066
|
-
} catch {
|
|
2157
|
+
} catch (err) {
|
|
2158
|
+
console.debug("[GoalsView] deleteGoal failed:", err);
|
|
2067
2159
|
}
|
|
2068
|
-
}, [dispatch, refreshGoals]);
|
|
2160
|
+
}, [dispatch, refreshGoals, goalsPanel.selectedIndex, activeGoals.length]);
|
|
2069
2161
|
const reactivateGoal = useCallback2(async (goalId) => {
|
|
2070
2162
|
try {
|
|
2071
2163
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2072
|
-
const agentState =
|
|
2164
|
+
const agentState = getProjectState(workDir);
|
|
2073
2165
|
await agentState.load();
|
|
2074
|
-
await agentState.updateGoal(goalId, { status: "active", achievedAt: void 0 });
|
|
2166
|
+
await agentState.updateGoal(goalId, { status: "active", achievedAt: void 0, achievedBy: void 0 });
|
|
2075
2167
|
dispatch({ type: "ADD_ACTIVITY", message: "Goal reactivated" });
|
|
2076
2168
|
await refreshGoals();
|
|
2077
|
-
} catch {
|
|
2169
|
+
} catch (err) {
|
|
2170
|
+
console.debug("[GoalsView] reactivateGoal failed:", err);
|
|
2078
2171
|
}
|
|
2079
2172
|
}, [dispatch, refreshGoals]);
|
|
2173
|
+
const reactivateAllAchievedGoals = useCallback2(async () => {
|
|
2174
|
+
try {
|
|
2175
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
2176
|
+
const agentState = getProjectState(workDir);
|
|
2177
|
+
await agentState.load();
|
|
2178
|
+
const achieved = goalsPanel.goals.filter((g) => g.status === "achieved");
|
|
2179
|
+
if (achieved.length === 0) {
|
|
2180
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "No achieved goals to reactivate", severity: "info", autoHideMs: 3e3 });
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
for (const goal of achieved) {
|
|
2184
|
+
await agentState.updateGoal(goal.id, { status: "active", achievedAt: void 0 });
|
|
2185
|
+
}
|
|
2186
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Reactivated ${achieved.length} goal${achieved.length > 1 ? "s" : ""}`, severity: "info", autoHideMs: 3e3 });
|
|
2187
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Reactivated ${achieved.length} goal${achieved.length > 1 ? "s" : ""}` });
|
|
2188
|
+
await refreshGoals();
|
|
2189
|
+
} catch (err) {
|
|
2190
|
+
console.debug("[GoalsView] reactivateAllAchievedGoals failed:", err);
|
|
2191
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "Failed to reactivate goals", severity: "warning", autoHideMs: 5e3 });
|
|
2192
|
+
}
|
|
2193
|
+
}, [dispatch, refreshGoals, goalsPanel.goals]);
|
|
2080
2194
|
const clearAchievedGoals = useCallback2(async () => {
|
|
2081
2195
|
try {
|
|
2082
2196
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2083
|
-
const agentState =
|
|
2197
|
+
const agentState = getProjectState(workDir);
|
|
2084
2198
|
await agentState.load();
|
|
2085
2199
|
const achieved = goalsPanel.goals.filter((g) => g.status === "achieved");
|
|
2086
2200
|
if (achieved.length === 0) {
|
|
@@ -2102,18 +2216,31 @@ function GoalsView() {
|
|
|
2102
2216
|
const checkGoalNow = useCallback2(async (goalId) => {
|
|
2103
2217
|
try {
|
|
2104
2218
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2105
|
-
const
|
|
2106
|
-
if (!
|
|
2107
|
-
dispatch({ type: "
|
|
2108
|
-
dispatch({ type: "
|
|
2109
|
-
|
|
2110
|
-
const
|
|
2219
|
+
const goalSummary = goalsPanel.goals.find((g) => g.id === goalId);
|
|
2220
|
+
if (!goalSummary) return;
|
|
2221
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Starting scan..." });
|
|
2222
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Scanning goal: ${goalSummary.description}...` });
|
|
2223
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Loading goal configuration..." });
|
|
2224
|
+
const { checkFilesForGoalViolations } = await import("./goal-validator-GISXYANK.js");
|
|
2225
|
+
const agentState = getProjectState(workDir);
|
|
2226
|
+
await agentState.load();
|
|
2227
|
+
const fullGoal = agentState.getAllGoals().find((g) => g.id === goalId);
|
|
2228
|
+
if (!fullGoal) {
|
|
2229
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId: null, progress: "" });
|
|
2230
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Goal not found: ${goalId}`, severity: "warning", autoHideMs: 5e3 });
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Analyzing codebase..." });
|
|
2234
|
+
const violations = await checkFilesForGoalViolations([fullGoal], workDir, void 0, (progressMsg) => {
|
|
2235
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: progressMsg });
|
|
2236
|
+
});
|
|
2237
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId: null, progress: "" });
|
|
2111
2238
|
if (violations.length === 0) {
|
|
2112
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `\u2713 No violations found for: ${
|
|
2113
|
-
dispatch({ type: "ADD_ACTIVITY", message:
|
|
2239
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `\u2713 No violations found for: ${goalSummary.description}`, severity: "info", autoHideMs: 5e3 });
|
|
2240
|
+
dispatch({ type: "ADD_ACTIVITY", message: `\u2713 Scan complete - no violations found` });
|
|
2114
2241
|
} else {
|
|
2115
|
-
dispatch({ type: "SHOW_NOTIFICATION", message:
|
|
2116
|
-
dispatch({ type: "ADD_ACTIVITY", message:
|
|
2242
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `\u26A0 Found ${violations.length} violation(s) - check Nudges tab`, severity: "warning", autoHideMs: 5e3 });
|
|
2243
|
+
dispatch({ type: "ADD_ACTIVITY", message: `\u26A0 Scan complete - ${violations.length} violation(s) found` });
|
|
2117
2244
|
for (const violation of violations) {
|
|
2118
2245
|
dispatch({ type: "ADD_INSIGHTS", insights: [{
|
|
2119
2246
|
id: `scan-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
@@ -2128,9 +2255,10 @@ function GoalsView() {
|
|
|
2128
2255
|
}
|
|
2129
2256
|
}
|
|
2130
2257
|
} catch (error) {
|
|
2258
|
+
dispatch({ type: "SET_GOAL_SCANNING", goalId: null, progress: "" });
|
|
2131
2259
|
const errorMsg = error instanceof Error ? error.message : "unknown error";
|
|
2132
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `
|
|
2133
|
-
dispatch({ type: "ADD_ACTIVITY", message:
|
|
2260
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Scan failed: ${errorMsg}`, severity: "warning", autoHideMs: 5e3 });
|
|
2261
|
+
dispatch({ type: "ADD_ACTIVITY", message: `\u2717 Scan failed: ${errorMsg}` });
|
|
2134
2262
|
}
|
|
2135
2263
|
}, [dispatch, goalsPanel.goals]);
|
|
2136
2264
|
useInput4((_input, key) => {
|
|
@@ -2164,6 +2292,8 @@ function GoalsView() {
|
|
|
2164
2292
|
} else if (_input === "u") {
|
|
2165
2293
|
const recent = goalsPanel.goals.filter((g) => g.status === "achieved").sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
2166
2294
|
if (recent[0]) void reactivateGoal(recent[0].id);
|
|
2295
|
+
} else if (_input === "U") {
|
|
2296
|
+
void reactivateAllAchievedGoals();
|
|
2167
2297
|
}
|
|
2168
2298
|
});
|
|
2169
2299
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
@@ -2174,40 +2304,65 @@ function GoalsView() {
|
|
|
2174
2304
|
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "|" })
|
|
2175
2305
|
] }) }),
|
|
2176
2306
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2177
|
-
] }) : /* @__PURE__ */ jsx9(
|
|
2307
|
+
] }) : /* @__PURE__ */ jsx9(Fragment4, { children: goalsPanel.goals.length === 0 ? /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " No goals yet. Press a to add one." }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2178
2308
|
activeGoals.length === 0 && goalsPanel.goals.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginBottom: 1, paddingX: 1, borderStyle: "round", borderColor: "yellow", children: [
|
|
2179
2309
|
/* @__PURE__ */ jsx9(Text8, { color: "yellow", bold: true, children: "\u26A0 No Active Goals" }),
|
|
2180
2310
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Goals exist but none are active. Violations won't be detected." }),
|
|
2181
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children:
|
|
2311
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Press U to reactivate all achieved goals, or a to add a new goal." })
|
|
2182
2312
|
] }),
|
|
2183
2313
|
activeGoals.map((goal, idx) => {
|
|
2184
2314
|
const isSelected = goalsPanel.selectedIndex === idx;
|
|
2315
|
+
const isScanning = goalsPanel.scanningGoalId === goal.id;
|
|
2185
2316
|
const progress = calculateGoalProgress(goal);
|
|
2186
|
-
const
|
|
2187
|
-
const
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
/* @__PURE__ */ jsx9(
|
|
2191
|
-
|
|
2192
|
-
|
|
2317
|
+
const barWidth = narrow ? 6 : Math.min(12, Math.floor(contentWidth / 8));
|
|
2318
|
+
const bar = progressBar(progress, 100, barWidth);
|
|
2319
|
+
const sourceLabel = goal.autoGenerated ? "AI" : "you";
|
|
2320
|
+
if (isScanning) {
|
|
2321
|
+
return /* @__PURE__ */ jsx9(Box8, { borderStyle: "round", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2322
|
+
/* @__PURE__ */ jsxs8(Text8, { wrap: "wrap", children: [
|
|
2323
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: "\u27F3 " }),
|
|
2324
|
+
/* @__PURE__ */ jsx9(Text8, { color: "cyan", bold: true, children: goal.description })
|
|
2325
|
+
] }),
|
|
2326
|
+
/* @__PURE__ */ jsx9(Text8, { color: "cyan", dimColor: true, children: goalsPanel.scanningProgress || "Scanning..." })
|
|
2327
|
+
] }) }, goal.id);
|
|
2328
|
+
}
|
|
2329
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2330
|
+
/* @__PURE__ */ jsxs8(Text8, { wrap: "wrap", children: [
|
|
2331
|
+
isSelected ? /* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "> " }) : " ",
|
|
2332
|
+
goal.autoGenerated ? /* @__PURE__ */ jsx9(Text8, { color: "cyan", children: "\u25C7" }) : /* @__PURE__ */ jsx9(Text8, { color: "green", children: "\u25CB" }),
|
|
2333
|
+
" ",
|
|
2334
|
+
goal.description,
|
|
2335
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2336
|
+
" [",
|
|
2337
|
+
sourceLabel,
|
|
2338
|
+
"]"
|
|
2339
|
+
] })
|
|
2340
|
+
] }),
|
|
2193
2341
|
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2194
|
-
"
|
|
2342
|
+
" ",
|
|
2195
2343
|
bar,
|
|
2196
2344
|
" ",
|
|
2197
2345
|
progress,
|
|
2198
|
-
"%"
|
|
2199
|
-
source ? ` ${source}` : ""
|
|
2346
|
+
"%"
|
|
2200
2347
|
] })
|
|
2201
2348
|
] }, goal.id);
|
|
2202
2349
|
}),
|
|
2203
2350
|
achievedGoals.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
2204
2351
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Achieved" }),
|
|
2205
|
-
achievedGoals.slice(0, 5).map((g) =>
|
|
2206
|
-
"
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2352
|
+
achievedGoals.slice(0, 5).map((g) => {
|
|
2353
|
+
const byLabel = g.achievedBy === "agent" ? "AI" : "you";
|
|
2354
|
+
return /* @__PURE__ */ jsxs8(Text8, { wrap: "wrap", children: [
|
|
2355
|
+
" ",
|
|
2356
|
+
g.achievedBy === "agent" ? /* @__PURE__ */ jsx9(Text8, { color: "cyan", children: "\u25CF" }) : /* @__PURE__ */ jsx9(Text8, { color: "green", children: "\u25CF" }),
|
|
2357
|
+
" ",
|
|
2358
|
+
g.description,
|
|
2359
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2360
|
+
" [",
|
|
2361
|
+
byLabel,
|
|
2362
|
+
"]"
|
|
2363
|
+
] })
|
|
2364
|
+
] }, g.id);
|
|
2365
|
+
}),
|
|
2211
2366
|
achievedGoals.length > 5 && /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2212
2367
|
" +",
|
|
2213
2368
|
achievedGoals.length - 5,
|
|
@@ -2216,14 +2371,16 @@ function GoalsView() {
|
|
|
2216
2371
|
] }),
|
|
2217
2372
|
otherGoals.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
2218
2373
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Other" }),
|
|
2219
|
-
otherGoals.slice(0, 2).map((g) =>
|
|
2220
|
-
"
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2374
|
+
otherGoals.slice(0, 2).map((g) => {
|
|
2375
|
+
return /* @__PURE__ */ jsxs8(Text8, { wrap: "wrap", children: [
|
|
2376
|
+
" ",
|
|
2377
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "\u25CB" }),
|
|
2378
|
+
" ",
|
|
2379
|
+
g.description,
|
|
2380
|
+
" ",
|
|
2381
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: g.status })
|
|
2382
|
+
] }, g.id);
|
|
2383
|
+
})
|
|
2227
2384
|
] })
|
|
2228
2385
|
] }) })
|
|
2229
2386
|
] });
|
|
@@ -2231,74 +2388,83 @@ function GoalsView() {
|
|
|
2231
2388
|
|
|
2232
2389
|
// src/cli/dashboard/views/HypothesesView.tsx
|
|
2233
2390
|
import { useCallback as useCallback3 } from "react";
|
|
2234
|
-
import { Box as Box9, Text as Text9, useInput as useInput5 } from "ink";
|
|
2235
|
-
import { Fragment as
|
|
2391
|
+
import { Box as Box9, Text as Text9, useInput as useInput5, useStdout as useStdout7 } from "ink";
|
|
2392
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2236
2393
|
function HypothesesView() {
|
|
2237
2394
|
const { state, dispatch } = useDashboard();
|
|
2238
2395
|
const { hypothesesPanel } = state;
|
|
2396
|
+
const { stdout } = useStdout7();
|
|
2397
|
+
const cols = stdout?.columns || 80;
|
|
2398
|
+
const narrow = cols < 60;
|
|
2399
|
+
const contentWidth = Math.max(20, cols - 4);
|
|
2239
2400
|
const testing = hypothesesPanel.hypotheses.filter((h) => h.status === "testing");
|
|
2240
2401
|
const validated = hypothesesPanel.hypotheses.filter((h) => h.status === "validated");
|
|
2241
2402
|
const invalidated = hypothesesPanel.hypotheses.filter((h) => h.status === "invalidated");
|
|
2242
2403
|
const refreshHypotheses = useCallback3(async () => {
|
|
2243
2404
|
try {
|
|
2244
2405
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2245
|
-
const agentState =
|
|
2406
|
+
const agentState = getProjectState(workDir);
|
|
2246
2407
|
await agentState.load();
|
|
2247
2408
|
const hypotheses = agentState.getAllHypotheses();
|
|
2248
2409
|
dispatch({
|
|
2249
2410
|
type: "SET_HYPOTHESES",
|
|
2250
2411
|
hypotheses: hypotheses.map((h) => {
|
|
2251
|
-
const base = { id: h.id, statement: h.statement, confidence: h.confidence, status: h.status, evidenceCount: h.evidence.length, updatedAt: h.updatedAt };
|
|
2252
|
-
return
|
|
2412
|
+
const base = { id: h.id, statement: h.statement, confidence: h.confidence, status: h.status, evidenceCount: h.evidence.length, updatedAt: h.updatedAt, ...h.autoGenerated != null ? { autoGenerated: h.autoGenerated } : {}, ...h.validatedBy != null ? { validatedBy: h.validatedBy } : {}, ...h.category != null ? { category: h.category } : {} };
|
|
2413
|
+
return base;
|
|
2253
2414
|
})
|
|
2254
2415
|
});
|
|
2255
|
-
} catch {
|
|
2416
|
+
} catch (err) {
|
|
2417
|
+
console.debug("[HypothesesView] refreshHypotheses failed:", err);
|
|
2256
2418
|
}
|
|
2257
2419
|
}, [dispatch]);
|
|
2258
2420
|
const addHypothesis = useCallback3(async (statement) => {
|
|
2259
2421
|
if (!statement.trim()) return;
|
|
2260
2422
|
try {
|
|
2261
2423
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2262
|
-
const agentState =
|
|
2424
|
+
const agentState = getProjectState(workDir);
|
|
2263
2425
|
await agentState.load();
|
|
2264
2426
|
const hypothesis = {
|
|
2265
2427
|
id: `hypo-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2266
2428
|
statement: statement.trim(),
|
|
2267
|
-
confidence: 0
|
|
2429
|
+
confidence: 0,
|
|
2268
2430
|
status: "testing",
|
|
2269
2431
|
evidence: [],
|
|
2270
2432
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2271
2433
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2272
|
-
testCriteria: "Collect evidence from scans"
|
|
2434
|
+
testCriteria: "Collect evidence from scans",
|
|
2435
|
+
autoGenerated: false
|
|
2273
2436
|
};
|
|
2274
2437
|
await agentState.addHypothesis(hypothesis);
|
|
2275
|
-
dispatch({ type: "ADD_ACTIVITY", message: `Hypothesis added: ${statement
|
|
2438
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Hypothesis added: ${statement}` });
|
|
2276
2439
|
await refreshHypotheses();
|
|
2277
|
-
} catch {
|
|
2440
|
+
} catch (err) {
|
|
2441
|
+
console.debug("[HypothesesView] addHypothesis failed:", err);
|
|
2278
2442
|
}
|
|
2279
2443
|
}, [dispatch, refreshHypotheses]);
|
|
2280
2444
|
const updateHypothesis = useCallback3(async (hypoId, action) => {
|
|
2281
2445
|
try {
|
|
2282
2446
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2283
|
-
const agentState =
|
|
2447
|
+
const agentState = getProjectState(workDir);
|
|
2284
2448
|
await agentState.load();
|
|
2285
|
-
if (action === "validate") await agentState.updateHypothesis(hypoId, { status: "validated", confidence: 0.9 });
|
|
2449
|
+
if (action === "validate") await agentState.updateHypothesis(hypoId, { status: "validated", confidence: 0.9, validatedBy: "user" });
|
|
2286
2450
|
else if (action === "invalidate") await agentState.updateHypothesis(hypoId, { status: "invalidated", confidence: 0.1 });
|
|
2287
2451
|
else await agentState.updateHypothesis(hypoId, { status: "retired" });
|
|
2288
2452
|
dispatch({ type: "ADD_ACTIVITY", message: `Hypothesis ${action === "validate" ? "validated" : action === "invalidate" ? "invalidated" : "removed"}` });
|
|
2289
2453
|
await refreshHypotheses();
|
|
2290
|
-
} catch {
|
|
2454
|
+
} catch (err) {
|
|
2455
|
+
console.debug("[HypothesesView] updateHypothesis failed:", err);
|
|
2291
2456
|
}
|
|
2292
2457
|
}, [dispatch, refreshHypotheses]);
|
|
2293
2458
|
const reactivateHypothesis = useCallback3(async (hypoId) => {
|
|
2294
2459
|
try {
|
|
2295
2460
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2296
|
-
const agentState =
|
|
2461
|
+
const agentState = getProjectState(workDir);
|
|
2297
2462
|
await agentState.load();
|
|
2298
|
-
await agentState.updateHypothesis(hypoId, { status: "testing", confidence: 0
|
|
2463
|
+
await agentState.updateHypothesis(hypoId, { status: "testing", confidence: 0, validatedAt: void 0, validatedBy: void 0 });
|
|
2299
2464
|
dispatch({ type: "ADD_ACTIVITY", message: "Hypothesis reactivated" });
|
|
2300
2465
|
await refreshHypotheses();
|
|
2301
|
-
} catch {
|
|
2466
|
+
} catch (err) {
|
|
2467
|
+
console.debug("[HypothesesView] reactivateHypothesis failed:", err);
|
|
2302
2468
|
}
|
|
2303
2469
|
}, [dispatch, refreshHypotheses]);
|
|
2304
2470
|
const checkHypothesisNow = useCallback3(async (hypoId) => {
|
|
@@ -2306,12 +2472,12 @@ function HypothesesView() {
|
|
|
2306
2472
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2307
2473
|
const hypo = hypothesesPanel.hypotheses.find((h) => h.id === hypoId);
|
|
2308
2474
|
if (!hypo) return;
|
|
2309
|
-
dispatch({ type: "ADD_ACTIVITY", message: `Testing hypothesis: ${hypo.statement
|
|
2475
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Testing hypothesis: ${hypo.statement}` });
|
|
2310
2476
|
dispatch({ type: "SHOW_NOTIFICATION", message: `Gathering evidence for hypothesis...`, severity: "info", autoHideMs: 3e3 });
|
|
2311
|
-
const { gatherEvidenceForHypothesis } = await import("./hypothesis-
|
|
2477
|
+
const { gatherEvidenceForHypothesis } = await import("./hypothesis-K3KQJOXJ.js");
|
|
2312
2478
|
const evidence = await gatherEvidenceForHypothesis(hypoId, workDir);
|
|
2313
2479
|
if (evidence.length === 0) {
|
|
2314
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `No evidence found for: ${hypo.statement
|
|
2480
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `No evidence found for: ${hypo.statement}`, severity: "info", autoHideMs: 5e3 });
|
|
2315
2481
|
dispatch({ type: "ADD_ACTIVITY", message: `No evidence found` });
|
|
2316
2482
|
} else {
|
|
2317
2483
|
const supporting = evidence.filter((e) => e.supports).length;
|
|
@@ -2353,7 +2519,7 @@ function HypothesesView() {
|
|
|
2353
2519
|
} else if (_input === "d") {
|
|
2354
2520
|
const selected = testing[hypothesesPanel.selectedIndex];
|
|
2355
2521
|
if (selected) void updateHypothesis(selected.id, "delete");
|
|
2356
|
-
} else if (_input === "
|
|
2522
|
+
} else if (_input === "c") {
|
|
2357
2523
|
const completed = hypothesesPanel.hypotheses.filter((h) => h.status === "validated" || h.status === "invalidated");
|
|
2358
2524
|
if (completed[0]) void updateHypothesis(completed[0].id, "delete");
|
|
2359
2525
|
} else if (_input === "u") {
|
|
@@ -2369,7 +2535,7 @@ function HypothesesView() {
|
|
|
2369
2535
|
/* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "|" })
|
|
2370
2536
|
] }) }),
|
|
2371
2537
|
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2372
|
-
] }) : /* @__PURE__ */ jsx10(
|
|
2538
|
+
] }) : /* @__PURE__ */ jsx10(Fragment5, { children: hypothesesPanel.hypotheses.length === 0 ? /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " No hypotheses yet. Press a to add one." }) : /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
2373
2539
|
testing.length === 0 && hypothesesPanel.hypotheses.length > 0 && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginBottom: 1, paddingX: 1, borderStyle: "round", borderColor: "yellow", children: [
|
|
2374
2540
|
/* @__PURE__ */ jsx10(Text9, { color: "yellow", bold: true, children: "\u26A0 No Active Hypotheses" }),
|
|
2375
2541
|
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "Hypotheses exist but none are being tested. Evidence won't be gathered." }),
|
|
@@ -2377,29 +2543,39 @@ function HypothesesView() {
|
|
|
2377
2543
|
] }),
|
|
2378
2544
|
testing.map((hypo, idx) => {
|
|
2379
2545
|
const isSelected = hypothesesPanel.selectedIndex === idx;
|
|
2380
|
-
const
|
|
2381
|
-
|
|
2546
|
+
const hasEvidence = hypo.evidenceCount > 0;
|
|
2547
|
+
const confLabel = hasEvidence ? `${Math.round(hypo.confidence * 100)}%` : "untested";
|
|
2548
|
+
const statementWidth = Math.max(25, contentWidth - 25);
|
|
2549
|
+
const sourceLabel = hypo.autoGenerated ? "AI" : "you";
|
|
2550
|
+
return /* @__PURE__ */ jsxs9(Text9, { wrap: "truncate", children: [
|
|
2382
2551
|
isSelected ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
2383
|
-
/* @__PURE__ */ jsx10(Text9, { color: "
|
|
2552
|
+
hypo.autoGenerated ? /* @__PURE__ */ jsx10(Text9, { color: "cyan", children: "\u25C7" }) : /* @__PURE__ */ jsx10(Text9, { color: "green", children: "\u25CB" }),
|
|
2384
2553
|
" ",
|
|
2385
|
-
hypo.statement.slice(0,
|
|
2554
|
+
hypo.statement.slice(0, statementWidth),
|
|
2386
2555
|
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2387
|
-
" ",
|
|
2388
|
-
|
|
2389
|
-
"
|
|
2390
|
-
|
|
2391
|
-
" evidence
|
|
2556
|
+
" [",
|
|
2557
|
+
sourceLabel,
|
|
2558
|
+
"] ",
|
|
2559
|
+
confLabel,
|
|
2560
|
+
narrow ? "" : ` \xB7 ${hypo.evidenceCount} evidence`
|
|
2392
2561
|
] })
|
|
2393
2562
|
] }, hypo.id);
|
|
2394
2563
|
}),
|
|
2395
2564
|
validated.length > 0 && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginTop: 1, children: [
|
|
2396
2565
|
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " Validated" }),
|
|
2397
|
-
validated.slice(0, 3).map((h) =>
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
" "
|
|
2401
|
-
|
|
2402
|
-
|
|
2566
|
+
validated.slice(0, 3).map((h) => {
|
|
2567
|
+
const statementWidth = Math.max(30, contentWidth - 12);
|
|
2568
|
+
const sourceLabel = h.autoGenerated ? "AI" : "you";
|
|
2569
|
+
const validatedByLabel = h.validatedBy === "agent" ? "AI" : "you";
|
|
2570
|
+
const suffix = sourceLabel !== validatedByLabel ? ` [${sourceLabel}\u2192${validatedByLabel}]` : ` [${sourceLabel}]`;
|
|
2571
|
+
return /* @__PURE__ */ jsxs9(Text9, { wrap: "truncate", children: [
|
|
2572
|
+
" ",
|
|
2573
|
+
h.autoGenerated ? /* @__PURE__ */ jsx10(Text9, { color: "cyan", children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { color: "green", children: "\u25CF" }),
|
|
2574
|
+
" ",
|
|
2575
|
+
h.statement.slice(0, statementWidth),
|
|
2576
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: suffix })
|
|
2577
|
+
] }, h.id);
|
|
2578
|
+
}),
|
|
2403
2579
|
validated.length > 3 && /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2404
2580
|
" +",
|
|
2405
2581
|
validated.length - 3,
|
|
@@ -2408,12 +2584,21 @@ function HypothesesView() {
|
|
|
2408
2584
|
] }),
|
|
2409
2585
|
invalidated.length > 0 && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginTop: 1, children: [
|
|
2410
2586
|
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " Invalidated" }),
|
|
2411
|
-
invalidated.slice(0, 2).map((h) =>
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2587
|
+
invalidated.slice(0, 2).map((h) => {
|
|
2588
|
+
const statementWidth = Math.max(30, contentWidth - 12);
|
|
2589
|
+
const sourceLabel = h.autoGenerated ? "AI" : "you";
|
|
2590
|
+
return /* @__PURE__ */ jsxs9(Text9, { wrap: "truncate", children: [
|
|
2591
|
+
" ",
|
|
2592
|
+
h.autoGenerated ? /* @__PURE__ */ jsx10(Text9, { color: "cyan", children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { color: "red", children: "\u25CF" }),
|
|
2593
|
+
" ",
|
|
2594
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: h.statement.slice(0, statementWidth) }),
|
|
2595
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2596
|
+
" [",
|
|
2597
|
+
sourceLabel,
|
|
2598
|
+
"]"
|
|
2599
|
+
] })
|
|
2600
|
+
] }, h.id);
|
|
2601
|
+
}),
|
|
2417
2602
|
invalidated.length > 2 && /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2418
2603
|
" +",
|
|
2419
2604
|
invalidated.length - 2,
|
|
@@ -2426,8 +2611,8 @@ function HypothesesView() {
|
|
|
2426
2611
|
|
|
2427
2612
|
// src/cli/dashboard/views/MemoryTreeView.tsx
|
|
2428
2613
|
import { useEffect as useEffect2, useCallback as useCallback4 } from "react";
|
|
2429
|
-
import { Box as Box10, Text as Text10, useInput as useInput6 } from "ink";
|
|
2430
|
-
import { Fragment as
|
|
2614
|
+
import { Box as Box10, Text as Text10, useInput as useInput6, useStdout as useStdout8 } from "ink";
|
|
2615
|
+
import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2431
2616
|
function timeAgo2(iso) {
|
|
2432
2617
|
const ms = Date.now() - new Date(iso).getTime();
|
|
2433
2618
|
const mins = Math.floor(ms / 6e4);
|
|
@@ -2439,20 +2624,26 @@ function timeAgo2(iso) {
|
|
|
2439
2624
|
function MemoryTreeView() {
|
|
2440
2625
|
const { state, dispatch } = useDashboard();
|
|
2441
2626
|
const { memoryTree } = state;
|
|
2442
|
-
const { snapshot, globalPatterns,
|
|
2627
|
+
const { snapshot, globalPatterns, storageGovernance, storageGotchas, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded } = memoryTree;
|
|
2628
|
+
const { stdout } = useStdout8();
|
|
2629
|
+
const cols = stdout?.columns || 80;
|
|
2630
|
+
const narrow = cols < 60;
|
|
2631
|
+
const contentWidth = Math.max(20, cols - 4);
|
|
2443
2632
|
const loadData = useCallback4(async () => {
|
|
2444
2633
|
try {
|
|
2445
2634
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2446
2635
|
const graph = new ContextGraph(workDir);
|
|
2447
2636
|
const storage = new TieredStorage(workDir);
|
|
2448
|
-
const [snap, patterns,
|
|
2637
|
+
const [snap, patterns, governance2, gotchas, blocks] = await Promise.all([
|
|
2449
2638
|
graph.getSnapshot(),
|
|
2450
2639
|
findCrossProjectPatterns(2),
|
|
2451
|
-
storage.
|
|
2640
|
+
storage.queryGovernance({ limit: 20 }).catch(() => []),
|
|
2641
|
+
storage.queryGotchas({ limit: 20, resolved: false }).catch(() => []),
|
|
2452
2642
|
getLedgerBlocks(workDir).catch(() => [])
|
|
2453
2643
|
]);
|
|
2454
|
-
dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns,
|
|
2455
|
-
} catch {
|
|
2644
|
+
dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns, storageGovernance: governance2, storageGotchas: gotchas, ledgerBlocks: blocks });
|
|
2645
|
+
} catch (err) {
|
|
2646
|
+
console.debug("[MemoryTreeView] loadData failed:", err);
|
|
2456
2647
|
dispatch({ type: "ADD_ACTIVITY", message: "Context graph load error" });
|
|
2457
2648
|
}
|
|
2458
2649
|
}, [dispatch]);
|
|
@@ -2461,7 +2652,40 @@ function MemoryTreeView() {
|
|
|
2461
2652
|
void loadData();
|
|
2462
2653
|
}
|
|
2463
2654
|
}, [loaded, loadData]);
|
|
2655
|
+
const handleIncidentAction = useCallback4(async (action) => {
|
|
2656
|
+
const incidentId = (selectedNode?.startsWith("incident-") ? selectedNode : expandedItemId?.startsWith("incident-") ? expandedItemId : null)?.replace(/^incident-/, "");
|
|
2657
|
+
if (!incidentId) return;
|
|
2658
|
+
try {
|
|
2659
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
2660
|
+
const graph = new ContextGraph(workDir);
|
|
2661
|
+
if (action === "delete") {
|
|
2662
|
+
await graph.deleteNode("incident", incidentId);
|
|
2663
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Incident deleted" });
|
|
2664
|
+
} else {
|
|
2665
|
+
await graph.updateNode("incident", incidentId, { resolved: true, resolution: "self-resolved" });
|
|
2666
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Incident resolved" });
|
|
2667
|
+
}
|
|
2668
|
+
dispatch({ type: "SET_MEMORY_EXPANDED_ITEM", itemId: null });
|
|
2669
|
+
void loadData();
|
|
2670
|
+
} catch (err) {
|
|
2671
|
+
console.debug("[MemoryTreeView] incident action failed:", err);
|
|
2672
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Failed to update incident" });
|
|
2673
|
+
}
|
|
2674
|
+
}, [selectedNode, expandedItemId, loadData, dispatch]);
|
|
2464
2675
|
useInput6((_input, key) => {
|
|
2676
|
+
const incidentSelected = selectedNode?.startsWith("incident-") || expandedItemId?.startsWith("incident-");
|
|
2677
|
+
if (incidentSelected && (_input === "d" || _input === "D")) {
|
|
2678
|
+
void handleIncidentAction("delete");
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
if (incidentSelected && (_input === "r" || _input === "c")) {
|
|
2682
|
+
void handleIncidentAction("resolve");
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
if (_input === "R" || !incidentSelected && _input === "r") {
|
|
2686
|
+
dispatch({ type: "INVALIDATE_MEMORY_TREE" });
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
2465
2689
|
if (key.upArrow || _input === "k") dispatch({ type: "NAVIGATE_UP" });
|
|
2466
2690
|
else if (key.downArrow || _input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
2467
2691
|
else if (key.return) dispatch({ type: "TOGGLE_MEMORY_NODE", nodeId: selectedNode });
|
|
@@ -2478,23 +2702,29 @@ function MemoryTreeView() {
|
|
|
2478
2702
|
const incidentNodes = snapshot?.nodes.filter((n) => n.type === "incident") ?? [];
|
|
2479
2703
|
const patternNodes = snapshot?.nodes.filter((n) => n.type === "pattern") ?? [];
|
|
2480
2704
|
const fileNodes = snapshot?.nodes.filter((n) => n.type === "file") ?? [];
|
|
2481
|
-
const
|
|
2705
|
+
const governance = storageGovernance.length > 0 ? storageGovernance : decisionNodes.map((n) => ({
|
|
2482
2706
|
id: n.id,
|
|
2483
2707
|
decision: n.data.decision,
|
|
2484
2708
|
context: n.data.context,
|
|
2485
|
-
reasoning: n.data.reasoning ?? void 0,
|
|
2486
2709
|
when: n.data.timestamp,
|
|
2487
2710
|
files: [],
|
|
2488
2711
|
tags: [],
|
|
2489
2712
|
status: "active",
|
|
2490
|
-
|
|
2713
|
+
...n.data.reasoning != null ? { reasoning: n.data.reasoning } : {},
|
|
2714
|
+
...n.data.outcome != null ? { outcome: n.data.outcome } : {}
|
|
2491
2715
|
}));
|
|
2492
2716
|
const hotspots = fileNodes.filter((n) => n.data.riskLevel === "critical" || n.data.riskLevel === "high").sort((a, b) => {
|
|
2493
2717
|
const order = { critical: 0, high: 1 };
|
|
2494
2718
|
return (order[a.data.riskLevel] ?? 2) - (order[b.data.riskLevel] ?? 2);
|
|
2495
2719
|
});
|
|
2496
|
-
const totalEntries =
|
|
2497
|
-
const
|
|
2720
|
+
const totalEntries = governance.length + incidentNodes.length + patternNodes.length + globalPatterns.length + hotspots.length + ledgerBlocks.length;
|
|
2721
|
+
const expandedGovernance = expandedItemId?.startsWith("decision-") ? governance.find((g) => `decision-${g.id}` === expandedItemId) : null;
|
|
2722
|
+
const expandedIncident = expandedItemId?.startsWith("incident-") ? incidentNodes.find((n) => `incident-${n.id}` === expandedItemId) : null;
|
|
2723
|
+
const expandedGotcha = expandedItemId?.startsWith("gotcha-") ? storageGotchas.find((g) => `gotcha-${g.id}` === expandedItemId) ?? null : null;
|
|
2724
|
+
const expandedLedgerBlock = expandedItemId?.startsWith("ledger-block-") ? (() => {
|
|
2725
|
+
const blockIndex = parseInt(expandedItemId.replace("ledger-block-", ""), 10);
|
|
2726
|
+
return ledgerBlocks[blockIndex] || null;
|
|
2727
|
+
})() : null;
|
|
2498
2728
|
function renderHeader(id, label, count, emptyHint) {
|
|
2499
2729
|
const expanded = expandedNodes.has(id);
|
|
2500
2730
|
const isEmpty = count === 0;
|
|
@@ -2520,145 +2750,303 @@ function MemoryTreeView() {
|
|
|
2520
2750
|
" ",
|
|
2521
2751
|
totalEntries,
|
|
2522
2752
|
" entries"
|
|
2523
|
-
] })
|
|
2753
|
+
] }),
|
|
2754
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " \xB7 r to refresh" })
|
|
2524
2755
|
] }),
|
|
2525
|
-
|
|
2526
|
-
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: "
|
|
2527
|
-
/* @__PURE__ */
|
|
2756
|
+
expandedGovernance && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
|
|
2757
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: "Governance detail (Enter or Esc to close)" }),
|
|
2758
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2528
2759
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Decision:" }),
|
|
2529
2760
|
" ",
|
|
2530
|
-
|
|
2531
|
-
] }),
|
|
2532
|
-
/* @__PURE__ */
|
|
2761
|
+
expandedGovernance.decision
|
|
2762
|
+
] }) }),
|
|
2763
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2533
2764
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Context:" }),
|
|
2534
2765
|
" ",
|
|
2535
|
-
|
|
2536
|
-
] }),
|
|
2537
|
-
|
|
2766
|
+
expandedGovernance.context
|
|
2767
|
+
] }) }),
|
|
2768
|
+
expandedGovernance.reasoning && /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2538
2769
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Reasoning:" }),
|
|
2539
2770
|
" ",
|
|
2540
|
-
|
|
2541
|
-
] }),
|
|
2542
|
-
|
|
2771
|
+
expandedGovernance.reasoning
|
|
2772
|
+
] }) }),
|
|
2773
|
+
expandedGovernance.hash && /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2543
2774
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Hash:" }),
|
|
2544
2775
|
" ",
|
|
2545
|
-
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children:
|
|
2546
|
-
] }),
|
|
2547
|
-
|
|
2776
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: expandedGovernance.hash })
|
|
2777
|
+
] }) }),
|
|
2778
|
+
expandedGovernance.files?.length ? /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2548
2779
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Files:" }),
|
|
2549
2780
|
" ",
|
|
2550
|
-
|
|
2551
|
-
] }) : null,
|
|
2552
|
-
|
|
2781
|
+
expandedGovernance.files.join(", ")
|
|
2782
|
+
] }) }) : null,
|
|
2783
|
+
expandedGovernance.tags?.length ? /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2784
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Tags:" }),
|
|
2785
|
+
" ",
|
|
2786
|
+
expandedGovernance.tags.join(", ")
|
|
2787
|
+
] }) }) : null,
|
|
2788
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: expandedGovernance.when }) })
|
|
2789
|
+
] }),
|
|
2790
|
+
expandedGotcha && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
|
|
2791
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "yellow", children: "Gotcha \xB7 Esc close" }),
|
|
2792
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2793
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Message:" }),
|
|
2794
|
+
" ",
|
|
2795
|
+
expandedGotcha.message
|
|
2796
|
+
] }) }),
|
|
2797
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2798
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Risk:" }),
|
|
2799
|
+
" ",
|
|
2800
|
+
expandedGotcha.riskLevel === "critical" ? /* @__PURE__ */ jsx11(Text10, { color: "red", children: expandedGotcha.riskLevel }) : expandedGotcha.riskLevel === "high" ? /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: expandedGotcha.riskLevel }) : /* @__PURE__ */ jsx11(Text10, { children: expandedGotcha.riskLevel }),
|
|
2801
|
+
" \xB7 ",
|
|
2802
|
+
Math.round(expandedGotcha.confidence * 100),
|
|
2803
|
+
"% confidence"
|
|
2804
|
+
] }) }),
|
|
2805
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2806
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Recommendation:" }),
|
|
2807
|
+
" ",
|
|
2808
|
+
expandedGotcha.recommendation
|
|
2809
|
+
] }) }),
|
|
2810
|
+
expandedGotcha.file && /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2811
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "File:" }),
|
|
2812
|
+
" ",
|
|
2813
|
+
expandedGotcha.file
|
|
2814
|
+
] }) }),
|
|
2815
|
+
expandedGotcha.tags?.length ? /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2553
2816
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Tags:" }),
|
|
2554
2817
|
" ",
|
|
2555
|
-
|
|
2556
|
-
] }) : null,
|
|
2557
|
-
/* @__PURE__ */ jsx11(
|
|
2818
|
+
expandedGotcha.tags.join(", ")
|
|
2819
|
+
] }) }) : null,
|
|
2820
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: expandedGotcha.timestamp }) })
|
|
2821
|
+
] }),
|
|
2822
|
+
expandedIncident && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
|
|
2823
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "yellow", children: "Incident \xB7 d delete \xB7 r resolve \xB7 Esc close" }),
|
|
2824
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2825
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Description:" }),
|
|
2826
|
+
" ",
|
|
2827
|
+
expandedIncident.data.description
|
|
2828
|
+
] }) }),
|
|
2829
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2830
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Severity:" }),
|
|
2831
|
+
" ",
|
|
2832
|
+
expandedIncident.data.severity
|
|
2833
|
+
] }) }),
|
|
2834
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2835
|
+
expandedIncident.data.timestamp,
|
|
2836
|
+
" \xB7 ",
|
|
2837
|
+
expandedIncident.data.resolved ? "resolved" : "open"
|
|
2838
|
+
] }) })
|
|
2839
|
+
] }),
|
|
2840
|
+
expandedLedgerBlock && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "magenta", paddingX: 1, paddingY: 1, children: [
|
|
2841
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "magenta", children: "Ledger Block Details \xB7 Esc close" }),
|
|
2842
|
+
(() => {
|
|
2843
|
+
const aiAgents = /* @__PURE__ */ new Set(["goal-violation", "claude", "agent", "ai"]);
|
|
2844
|
+
const hasAIAgents = expandedLedgerBlock.entries.some((e) => aiAgents.has(e.agent));
|
|
2845
|
+
const hasLegacyAgents = expandedLedgerBlock.entries.some((e) => !aiAgents.has(e.agent));
|
|
2846
|
+
const sourceLabel = hasAIAgents && !hasLegacyAgents ? "AI (Claude)" : hasLegacyAgents && !hasAIAgents ? "Legacy (deterministic agents)" : "Mixed (legacy + AI)";
|
|
2847
|
+
const sourceColor = hasAIAgents && !hasLegacyAgents ? "green" : hasLegacyAgents && !hasAIAgents ? "yellow" : "cyan";
|
|
2848
|
+
return /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2849
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Source:" }),
|
|
2850
|
+
" ",
|
|
2851
|
+
/* @__PURE__ */ jsx11(Text10, { color: sourceColor, children: sourceLabel }),
|
|
2852
|
+
hasLegacyAgents ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " New blocks use AI via watch + trie_scan_for_goal_violations" }) : null
|
|
2853
|
+
] }) });
|
|
2854
|
+
})(),
|
|
2855
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2856
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Date:" }),
|
|
2857
|
+
" ",
|
|
2858
|
+
expandedLedgerBlock.date,
|
|
2859
|
+
" (",
|
|
2860
|
+
expandedLedgerBlock.entries.length,
|
|
2861
|
+
" issues)"
|
|
2862
|
+
] }) }),
|
|
2863
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2864
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Block Hash:" }),
|
|
2865
|
+
" ",
|
|
2866
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: expandedLedgerBlock.blockHash })
|
|
2867
|
+
] }) }),
|
|
2868
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2869
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Merkle Root:" }),
|
|
2870
|
+
" ",
|
|
2871
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: expandedLedgerBlock.merkleRoot })
|
|
2872
|
+
] }) }),
|
|
2873
|
+
(() => {
|
|
2874
|
+
const severityCounts = expandedLedgerBlock.entries.reduce((acc, entry) => {
|
|
2875
|
+
acc[entry.severity] = (acc[entry.severity] || 0) + 1;
|
|
2876
|
+
return acc;
|
|
2877
|
+
}, {});
|
|
2878
|
+
const agentCounts = expandedLedgerBlock.entries.reduce((acc, entry) => {
|
|
2879
|
+
acc[entry.agent] = (acc[entry.agent] || 0) + 1;
|
|
2880
|
+
return acc;
|
|
2881
|
+
}, {});
|
|
2882
|
+
const aiAgents = /* @__PURE__ */ new Set(["goal-violation", "claude", "agent", "ai"]);
|
|
2883
|
+
const aiEntries = Object.entries(agentCounts).filter(([a]) => aiAgents.has(a));
|
|
2884
|
+
const legacyEntries = Object.entries(agentCounts).filter(([a]) => !aiAgents.has(a));
|
|
2885
|
+
const agentsDisplay = [...aiEntries, ...legacyEntries].map(([agent, count]) => `${agent} (${count})`).join(", ");
|
|
2886
|
+
const fileCounts = expandedLedgerBlock.entries.reduce((acc, entry) => {
|
|
2887
|
+
acc[entry.file] = (acc[entry.file] || 0) + 1;
|
|
2888
|
+
return acc;
|
|
2889
|
+
}, {});
|
|
2890
|
+
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2891
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2892
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Severity:" }),
|
|
2893
|
+
" ",
|
|
2894
|
+
Object.entries(severityCounts).map(([sev, count]) => `${count} ${sev}`).join(", ")
|
|
2895
|
+
] }) }),
|
|
2896
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2897
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Agents:" }),
|
|
2898
|
+
" ",
|
|
2899
|
+
agentsDisplay
|
|
2900
|
+
] }) }),
|
|
2901
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2902
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Top Files:" }),
|
|
2903
|
+
" ",
|
|
2904
|
+
Object.entries(fileCounts).sort((a, b) => b[1] - a[1]).slice(0, 3).map(([file, count]) => `${file.split("/").pop()} (${count})`).join(", ")
|
|
2905
|
+
] }) })
|
|
2906
|
+
] });
|
|
2907
|
+
})(),
|
|
2908
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2909
|
+
"Created: ",
|
|
2910
|
+
expandedLedgerBlock.createdAt
|
|
2911
|
+
] }) })
|
|
2558
2912
|
] }),
|
|
2559
2913
|
/* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, children: [
|
|
2560
|
-
renderHeader("decisions", "
|
|
2561
|
-
expandedNodes.has("decisions") &&
|
|
2562
|
-
const nodeId = `decision-${
|
|
2563
|
-
const
|
|
2564
|
-
const
|
|
2565
|
-
|
|
2914
|
+
renderHeader("decisions", "Product Governance", governance.length, "-- use trie tell or chat"),
|
|
2915
|
+
expandedNodes.has("decisions") && governance.slice(0, 10).map((g) => {
|
|
2916
|
+
const nodeId = `decision-${g.id}`;
|
|
2917
|
+
const decWidth = Math.max(30, contentWidth - 25);
|
|
2918
|
+
const dec = g.decision.length > decWidth ? g.decision.slice(0, decWidth - 3) + "..." : g.decision;
|
|
2919
|
+
const outcomeColor = g.outcome === "good" ? "green" : g.outcome === "bad" ? "red" : void 0;
|
|
2920
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2566
2921
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2567
2922
|
" ",
|
|
2568
2923
|
outcomeColor ? /* @__PURE__ */ jsx11(Text10, { color: outcomeColor, children: "\u25CF" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" }),
|
|
2569
2924
|
" ",
|
|
2570
2925
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: dec }) : /* @__PURE__ */ jsx11(Text10, { children: dec }),
|
|
2571
|
-
|
|
2926
|
+
!narrow && g.hash ? /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2572
2927
|
" [",
|
|
2573
|
-
|
|
2928
|
+
g.hash.slice(0, 8),
|
|
2574
2929
|
"]"
|
|
2575
2930
|
] }) : null,
|
|
2576
|
-
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2931
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2577
2932
|
" ",
|
|
2578
|
-
timeAgo2(
|
|
2933
|
+
timeAgo2(g.when)
|
|
2579
2934
|
] }),
|
|
2580
|
-
outcomeColor ? /* @__PURE__ */ jsxs10(Text10, { color: outcomeColor, children: [
|
|
2935
|
+
outcomeColor && !narrow ? /* @__PURE__ */ jsxs10(Text10, { color: outcomeColor, children: [
|
|
2581
2936
|
" ",
|
|
2582
|
-
|
|
2937
|
+
g.outcome
|
|
2583
2938
|
] }) : null
|
|
2584
|
-
] },
|
|
2939
|
+
] }, g.id);
|
|
2585
2940
|
})
|
|
2586
2941
|
] }),
|
|
2587
2942
|
renderHeader("incidents", "Incidents", incidentNodes.length, "-- use trie tell"),
|
|
2588
2943
|
expandedNodes.has("incidents") && incidentNodes.slice(0, 10).map((n) => {
|
|
2589
2944
|
const nodeId = `incident-${n.id}`;
|
|
2590
2945
|
const sevColor = n.data.severity === "critical" ? "red" : n.data.severity === "major" ? "yellow" : void 0;
|
|
2591
|
-
const
|
|
2592
|
-
|
|
2946
|
+
const descWidth = Math.max(30, contentWidth - 20);
|
|
2947
|
+
const desc = n.data.description.length > descWidth ? n.data.description.slice(0, descWidth - 3) + "..." : n.data.description;
|
|
2948
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2593
2949
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2594
2950
|
" ",
|
|
2595
2951
|
sevColor ? /* @__PURE__ */ jsx11(Text10, { color: sevColor, children: "\u25CF" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" }),
|
|
2596
2952
|
" ",
|
|
2597
2953
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
2598
|
-
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2954
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2599
2955
|
" ",
|
|
2600
2956
|
timeAgo2(n.data.timestamp)
|
|
2601
2957
|
] }),
|
|
2602
|
-
|
|
2603
|
-
|
|
2958
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2959
|
+
" ",
|
|
2960
|
+
n.data.resolved ? /* @__PURE__ */ jsx11(Text10, { color: "green", children: "resolved" }) : /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "open" })
|
|
2961
|
+
] })
|
|
2604
2962
|
] }, n.id);
|
|
2605
2963
|
}),
|
|
2964
|
+
renderHeader("gotchas", "Gotchas", storageGotchas.length, "-- potential risks from AI (run trie gotcha or watch)"),
|
|
2965
|
+
expandedNodes.has("gotchas") && storageGotchas.slice(0, 10).map((g) => {
|
|
2966
|
+
const nodeId = `gotcha-${g.id}`;
|
|
2967
|
+
const riskColor = g.riskLevel === "critical" ? "red" : g.riskLevel === "high" ? "yellow" : void 0;
|
|
2968
|
+
const msgWidth = Math.max(30, contentWidth - 25);
|
|
2969
|
+
const msg = g.message.length > msgWidth ? g.message.slice(0, msgWidth - 3) + "..." : g.message;
|
|
2970
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2971
|
+
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2972
|
+
" ",
|
|
2973
|
+
riskColor ? /* @__PURE__ */ jsx11(Text10, { color: riskColor, children: "\u25CF" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" }),
|
|
2974
|
+
" ",
|
|
2975
|
+
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: msg }) : /* @__PURE__ */ jsx11(Text10, { children: msg }),
|
|
2976
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2977
|
+
" ",
|
|
2978
|
+
g.riskLevel
|
|
2979
|
+
] }),
|
|
2980
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2981
|
+
" ",
|
|
2982
|
+
timeAgo2(g.timestamp)
|
|
2983
|
+
] })
|
|
2984
|
+
] }, g.id);
|
|
2985
|
+
}),
|
|
2606
2986
|
renderHeader("patterns", "Learned Patterns", patternNodes.length, "-- Trie learns as you work"),
|
|
2607
2987
|
expandedNodes.has("patterns") && patternNodes.slice(0, 10).map((n) => {
|
|
2608
2988
|
const nodeId = `pattern-${n.id}`;
|
|
2609
2989
|
const conf = Math.round(n.data.confidence * 100);
|
|
2610
2990
|
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
2611
|
-
const
|
|
2612
|
-
|
|
2991
|
+
const descWidth = Math.max(30, contentWidth - 15);
|
|
2992
|
+
const desc = n.data.description.length > descWidth ? n.data.description.slice(0, descWidth - 3) + "..." : n.data.description;
|
|
2993
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2613
2994
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2614
2995
|
" ",
|
|
2615
2996
|
n.data.isAntiPattern ? /* @__PURE__ */ jsx11(Text10, { color: "red", children: "!" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" }),
|
|
2616
2997
|
" ",
|
|
2617
2998
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2999
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3000
|
+
" ",
|
|
3001
|
+
confColor ? /* @__PURE__ */ jsxs10(Text10, { color: confColor, children: [
|
|
3002
|
+
conf,
|
|
3003
|
+
"%"
|
|
3004
|
+
] }) : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3005
|
+
conf,
|
|
3006
|
+
"%"
|
|
3007
|
+
] })
|
|
2625
3008
|
] })
|
|
2626
3009
|
] }, n.id);
|
|
2627
3010
|
}),
|
|
2628
3011
|
renderHeader("cross-project", "Cross-Project", globalPatterns.length),
|
|
2629
3012
|
expandedNodes.has("cross-project") && globalPatterns.slice(0, 8).map((pattern) => {
|
|
2630
3013
|
const patternId = `global-${pattern.id}`;
|
|
2631
|
-
const
|
|
2632
|
-
|
|
3014
|
+
const descWidth = Math.max(25, contentWidth - 35);
|
|
3015
|
+
const desc = pattern.pattern.length > descWidth ? pattern.pattern.slice(0, descWidth - 3) + "..." : pattern.pattern;
|
|
3016
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2633
3017
|
sel(patternId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2634
3018
|
" ",
|
|
2635
3019
|
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" }),
|
|
2636
3020
|
" ",
|
|
2637
3021
|
sel(patternId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
2638
|
-
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3022
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2639
3023
|
" ",
|
|
2640
3024
|
pattern.projects.length,
|
|
2641
|
-
"
|
|
3025
|
+
"p \xB7 ",
|
|
2642
3026
|
pattern.occurrences,
|
|
2643
|
-
"
|
|
3027
|
+
"x"
|
|
2644
3028
|
] })
|
|
2645
3029
|
] }, pattern.id);
|
|
2646
3030
|
}),
|
|
2647
|
-
hotspots.length > 0 && /* @__PURE__ */ jsxs10(
|
|
3031
|
+
hotspots.length > 0 && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2648
3032
|
renderHeader("hotspots", "Risk Hotspots", hotspots.length),
|
|
2649
3033
|
expandedNodes.has("hotspots") && hotspots.slice(0, 10).map((n) => {
|
|
2650
3034
|
const nodeId = `file-${n.id}`;
|
|
2651
3035
|
const path2 = n.data.path.split("/").slice(-2).join("/");
|
|
2652
3036
|
const isCritical = n.data.riskLevel === "critical";
|
|
2653
|
-
|
|
3037
|
+
const pathWidth = Math.max(20, contentWidth - 30);
|
|
3038
|
+
const displayPath = path2.length > pathWidth ? path2.slice(-pathWidth) : path2;
|
|
3039
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2654
3040
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2655
3041
|
" ",
|
|
2656
3042
|
/* @__PURE__ */ jsx11(Text10, { color: isCritical ? "red" : "yellow", children: "\u25CF" }),
|
|
2657
3043
|
" ",
|
|
2658
|
-
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children:
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
3044
|
+
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: displayPath }) : /* @__PURE__ */ jsx11(Text10, { children: displayPath }),
|
|
3045
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3046
|
+
" ",
|
|
3047
|
+
/* @__PURE__ */ jsx11(Text10, { color: isCritical ? "red" : "yellow", children: n.data.riskLevel })
|
|
3048
|
+
] }),
|
|
3049
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2662
3050
|
" ",
|
|
2663
3051
|
n.data.changeCount,
|
|
2664
3052
|
" changes"
|
|
@@ -2666,14 +3054,33 @@ function MemoryTreeView() {
|
|
|
2666
3054
|
] }, n.id);
|
|
2667
3055
|
})
|
|
2668
3056
|
] }),
|
|
2669
|
-
ledgerBlocks.length > 0 && /* @__PURE__ */ jsxs10(
|
|
3057
|
+
ledgerBlocks.length > 0 && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2670
3058
|
renderHeader("ledger-chain", "Ledger Chain (hashes)", ledgerBlocks.length),
|
|
2671
3059
|
expandedNodes.has("ledger-chain") && ledgerBlocks.map((block, i) => {
|
|
2672
3060
|
const nodeId = `ledger-block-${i}`;
|
|
2673
|
-
|
|
3061
|
+
const aiAgents = /* @__PURE__ */ new Set(["goal-violation", "claude", "agent", "ai"]);
|
|
3062
|
+
const hasAIAgents = block.entries.some((e) => aiAgents.has(e.agent));
|
|
3063
|
+
const hasLegacyAgents = block.entries.some((e) => !aiAgents.has(e.agent));
|
|
3064
|
+
const blockSource = hasAIAgents && !hasLegacyAgents ? "AI" : hasLegacyAgents && !hasAIAgents ? "legacy" : "mixed";
|
|
3065
|
+
const severityCounts = block.entries.reduce((acc, entry) => {
|
|
3066
|
+
acc[entry.severity] = (acc[entry.severity] || 0) + 1;
|
|
3067
|
+
return acc;
|
|
3068
|
+
}, {});
|
|
3069
|
+
const topSeverity = Object.keys(severityCounts).sort((a, b) => {
|
|
3070
|
+
const order = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
3071
|
+
return (order[a] ?? 5) - (order[b] ?? 5);
|
|
3072
|
+
})[0];
|
|
3073
|
+
const agentCounts = block.entries.reduce((acc, entry) => {
|
|
3074
|
+
acc[entry.agent] = (acc[entry.agent] || 0) + 1;
|
|
3075
|
+
return acc;
|
|
3076
|
+
}, {});
|
|
3077
|
+
const topAgent = Object.keys(agentCounts).sort((a, b) => (agentCounts[b] ?? 0) - (agentCounts[a] ?? 0))[0];
|
|
3078
|
+
const blkShort = block.blockHash?.slice(0, 6) || "\u2014";
|
|
3079
|
+
const mkShort = block.merkleRoot?.slice(0, 6) || "\u2014";
|
|
3080
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
2674
3081
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
|
|
2675
3082
|
" ",
|
|
2676
|
-
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CF" }),
|
|
3083
|
+
blockSource === "AI" ? /* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u25CF" }) : blockSource === "legacy" ? /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "\u25CF" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CF" }),
|
|
2677
3084
|
" ",
|
|
2678
3085
|
sel(nodeId) ? /* @__PURE__ */ jsxs10(Text10, { bold: true, color: "green", children: [
|
|
2679
3086
|
"Block ",
|
|
@@ -2682,28 +3089,53 @@ function MemoryTreeView() {
|
|
|
2682
3089
|
"Block ",
|
|
2683
3090
|
i + 1
|
|
2684
3091
|
] }),
|
|
2685
|
-
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3092
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2686
3093
|
" ",
|
|
2687
3094
|
block.date
|
|
2688
3095
|
] }),
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
3096
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3097
|
+
" ",
|
|
3098
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3099
|
+
"[",
|
|
3100
|
+
blockSource,
|
|
3101
|
+
"]"
|
|
3102
|
+
] })
|
|
2695
3103
|
] }),
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
3104
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3105
|
+
" ",
|
|
3106
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3107
|
+
"blk:",
|
|
3108
|
+
blkShort,
|
|
3109
|
+
"\u2026 mk:",
|
|
3110
|
+
mkShort,
|
|
3111
|
+
"\u2026"
|
|
3112
|
+
] })
|
|
2701
3113
|
] }),
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
3114
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3115
|
+
" ",
|
|
3116
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3117
|
+
block.entries.length,
|
|
3118
|
+
" entries"
|
|
3119
|
+
] })
|
|
3120
|
+
] }),
|
|
3121
|
+
narrow ? null : topSeverity != null ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3122
|
+
" ",
|
|
3123
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3124
|
+
"(",
|
|
3125
|
+
severityCounts[topSeverity] ?? 0,
|
|
3126
|
+
" ",
|
|
3127
|
+
topSeverity,
|
|
3128
|
+
")"
|
|
3129
|
+
] })
|
|
3130
|
+
] }) : null,
|
|
3131
|
+
narrow ? null : topAgent != null ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3132
|
+
" ",
|
|
3133
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3134
|
+
"by ",
|
|
3135
|
+
topAgent
|
|
3136
|
+
] })
|
|
3137
|
+
] }) : null,
|
|
3138
|
+
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " [Enter: details]" }) : null
|
|
2707
3139
|
] }, nodeId);
|
|
2708
3140
|
})
|
|
2709
3141
|
] })
|
|
@@ -2738,13 +3170,13 @@ function RawLogView() {
|
|
|
2738
3170
|
] }),
|
|
2739
3171
|
rawLog.length === 0 ? /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " No log entries yet" }) : logs.map((entry, i) => {
|
|
2740
3172
|
const dot = entry.level === "error" ? /* @__PURE__ */ jsx12(Text11, { color: "red", children: "\u25CF" }) : entry.level === "warn" ? /* @__PURE__ */ jsx12(Text11, { color: "yellow", children: "\u25CF" }) : entry.level === "info" ? /* @__PURE__ */ jsx12(Text11, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u25CB" });
|
|
2741
|
-
return /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
3173
|
+
return /* @__PURE__ */ jsxs11(Text11, { wrap: "wrap", children: [
|
|
2742
3174
|
" ",
|
|
2743
3175
|
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: entry.time }),
|
|
2744
3176
|
" ",
|
|
2745
3177
|
dot,
|
|
2746
3178
|
" ",
|
|
2747
|
-
entry.message
|
|
3179
|
+
entry.message
|
|
2748
3180
|
] }, i);
|
|
2749
3181
|
})
|
|
2750
3182
|
] });
|
|
@@ -2752,7 +3184,7 @@ function RawLogView() {
|
|
|
2752
3184
|
|
|
2753
3185
|
// src/cli/dashboard/views/ChatView.tsx
|
|
2754
3186
|
import { useCallback as useCallback5, useRef, useEffect as useEffect3, useState as useState2 } from "react";
|
|
2755
|
-
import { Box as Box12, Text as Text12, useInput as useInput8 } from "ink";
|
|
3187
|
+
import { Box as Box12, Text as Text12, useInput as useInput8, useStdout as useStdout9 } from "ink";
|
|
2756
3188
|
|
|
2757
3189
|
// src/tools/tell.ts
|
|
2758
3190
|
import path from "path";
|
|
@@ -2791,7 +3223,7 @@ CRITICAL: Extract rich metadata:
|
|
|
2791
3223
|
|
|
2792
3224
|
Format as JSON:
|
|
2793
3225
|
{
|
|
2794
|
-
"
|
|
3226
|
+
"governance": [{
|
|
2795
3227
|
"decision": "Use bcrypt for password hashing",
|
|
2796
3228
|
"context": "Security requirement for user authentication",
|
|
2797
3229
|
"reasoning": "Industry standard, resistant to GPU attacks",
|
|
@@ -2863,7 +3295,8 @@ ${content}`
|
|
|
2863
3295
|
metadata.sourceId = sourceId;
|
|
2864
3296
|
}
|
|
2865
3297
|
const signal = {
|
|
2866
|
-
|
|
3298
|
+
gotchas: [],
|
|
3299
|
+
governance: extracted.governance.map((d, i) => ({
|
|
2867
3300
|
id: `dec-${Date.now()}-${i}`,
|
|
2868
3301
|
decision: d.decision || "",
|
|
2869
3302
|
context: d.context || "",
|
|
@@ -2914,12 +3347,18 @@ ${content}`
|
|
|
2914
3347
|
try {
|
|
2915
3348
|
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
2916
3349
|
if (jsonMatch) {
|
|
2917
|
-
|
|
3350
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
3351
|
+
return {
|
|
3352
|
+
governance: parsed.governance,
|
|
3353
|
+
facts: parsed.facts,
|
|
3354
|
+
blockers: parsed.blockers,
|
|
3355
|
+
questions: parsed.questions
|
|
3356
|
+
};
|
|
2918
3357
|
}
|
|
2919
3358
|
} catch (e) {
|
|
2920
3359
|
}
|
|
2921
3360
|
return {
|
|
2922
|
-
|
|
3361
|
+
governance: [],
|
|
2923
3362
|
facts: [],
|
|
2924
3363
|
blockers: [],
|
|
2925
3364
|
questions: []
|
|
@@ -2933,12 +3372,12 @@ ${content}`
|
|
|
2933
3372
|
const hasDecision = /\b(decided|decision|chose|picked)\b/i.test(content);
|
|
2934
3373
|
const hasBlocker = /\b(blocked|blocker|blocked by|can't|cannot|unable)\b/i.test(content);
|
|
2935
3374
|
const hasQuestion = /\?|what|how|why|should we/i.test(content);
|
|
2936
|
-
const
|
|
3375
|
+
const governance = [];
|
|
2937
3376
|
const facts = [];
|
|
2938
3377
|
const blockers = [];
|
|
2939
3378
|
const questions = [];
|
|
2940
3379
|
if (hasDecision) {
|
|
2941
|
-
|
|
3380
|
+
governance.push({
|
|
2942
3381
|
id: `dec-${Date.now()}`,
|
|
2943
3382
|
decision: content.substring(0, 200),
|
|
2944
3383
|
context: sourceType,
|
|
@@ -2976,10 +3415,11 @@ ${content}`
|
|
|
2976
3415
|
metadata.sourceId = sourceId;
|
|
2977
3416
|
}
|
|
2978
3417
|
return {
|
|
2979
|
-
|
|
3418
|
+
governance,
|
|
2980
3419
|
facts,
|
|
2981
3420
|
blockers,
|
|
2982
3421
|
questions,
|
|
3422
|
+
gotchas: [],
|
|
2983
3423
|
metadata
|
|
2984
3424
|
};
|
|
2985
3425
|
}
|
|
@@ -3035,7 +3475,7 @@ var MetadataEnricher = class {
|
|
|
3035
3475
|
expandedTags: this.expandTags(signal),
|
|
3036
3476
|
codebaseArea: this.inferCodebaseArea(signal),
|
|
3037
3477
|
domain: this.inferDomain(signal),
|
|
3038
|
-
|
|
3478
|
+
relatedGovernance: [],
|
|
3039
3479
|
// Will be populated by storage layer
|
|
3040
3480
|
extractedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3041
3481
|
};
|
|
@@ -3053,8 +3493,8 @@ var MetadataEnricher = class {
|
|
|
3053
3493
|
*/
|
|
3054
3494
|
expandTags(signal) {
|
|
3055
3495
|
const allTags = /* @__PURE__ */ new Set();
|
|
3056
|
-
for (const
|
|
3057
|
-
|
|
3496
|
+
for (const gov of signal.governance) {
|
|
3497
|
+
gov.tags.forEach((tag) => allTags.add(tag.toLowerCase()));
|
|
3058
3498
|
}
|
|
3059
3499
|
for (const fact of signal.facts) {
|
|
3060
3500
|
fact.tags.forEach((tag) => allTags.add(tag.toLowerCase()));
|
|
@@ -3077,8 +3517,8 @@ var MetadataEnricher = class {
|
|
|
3077
3517
|
*/
|
|
3078
3518
|
async findRelatedFiles(signal) {
|
|
3079
3519
|
const relatedFiles = /* @__PURE__ */ new Set();
|
|
3080
|
-
for (const
|
|
3081
|
-
|
|
3520
|
+
for (const gov of signal.governance) {
|
|
3521
|
+
gov.files.forEach((file) => relatedFiles.add(file));
|
|
3082
3522
|
}
|
|
3083
3523
|
const inferredFiles = await this.inferFilesFromTags(signal);
|
|
3084
3524
|
inferredFiles.forEach((file) => relatedFiles.add(file));
|
|
@@ -3090,7 +3530,7 @@ var MetadataEnricher = class {
|
|
|
3090
3530
|
async extractDependencies(signal) {
|
|
3091
3531
|
const dependencies = /* @__PURE__ */ new Set();
|
|
3092
3532
|
const allText = [
|
|
3093
|
-
...signal.
|
|
3533
|
+
...signal.governance.map((d) => `${d.decision} ${d.context} ${d.reasoning}`),
|
|
3094
3534
|
...signal.facts.map((f) => `${f.fact} ${f.source}`)
|
|
3095
3535
|
].join(" ");
|
|
3096
3536
|
const packagePatterns = [
|
|
@@ -3107,8 +3547,8 @@ var MetadataEnricher = class {
|
|
|
3107
3547
|
*/
|
|
3108
3548
|
inferCodebaseArea(signal) {
|
|
3109
3549
|
const areas = /* @__PURE__ */ new Set();
|
|
3110
|
-
for (const
|
|
3111
|
-
for (const file of
|
|
3550
|
+
for (const gov of signal.governance) {
|
|
3551
|
+
for (const file of gov.files) {
|
|
3112
3552
|
const area = this.filePathToArea(file);
|
|
3113
3553
|
if (area) areas.add(area);
|
|
3114
3554
|
}
|
|
@@ -3227,7 +3667,7 @@ var ExtractionPipeline = class {
|
|
|
3227
3667
|
outputManager.debug("Extracting signals from content...");
|
|
3228
3668
|
let extractedSignal = await this.extractor.extract(content, context.sourceType, context.sourceId);
|
|
3229
3669
|
extractedSignal = this.addIds(extractedSignal, context);
|
|
3230
|
-
outputManager.debug(`Extracted ${extractedSignal.
|
|
3670
|
+
outputManager.debug(`Extracted ${extractedSignal.governance.length} governance, ${extractedSignal.facts.length} facts, ${extractedSignal.blockers.length} blockers, ${extractedSignal.questions.length} questions`);
|
|
3231
3671
|
outputManager.debug("Enriching with metadata...");
|
|
3232
3672
|
const { metadata: enrichedMeta } = await this.enricher.enrichSignal(extractedSignal, {
|
|
3233
3673
|
workingDirectory: this.workDir
|
|
@@ -3268,17 +3708,18 @@ var ExtractionPipeline = class {
|
|
|
3268
3708
|
metadata.sourceId = context.sourceId;
|
|
3269
3709
|
}
|
|
3270
3710
|
return {
|
|
3271
|
-
|
|
3272
|
-
|
|
3711
|
+
gotchas: signal.gotchas ?? [],
|
|
3712
|
+
governance: signal.governance.map((d) => {
|
|
3713
|
+
const gov = {
|
|
3273
3714
|
...d,
|
|
3274
3715
|
id: d.id || this.generateId(),
|
|
3275
3716
|
when: d.when || now,
|
|
3276
3717
|
status: d.status || "active"
|
|
3277
3718
|
};
|
|
3278
3719
|
if (context.who !== void 0) {
|
|
3279
|
-
|
|
3720
|
+
gov.who = d.who || context.who;
|
|
3280
3721
|
}
|
|
3281
|
-
return
|
|
3722
|
+
return gov;
|
|
3282
3723
|
}),
|
|
3283
3724
|
facts: signal.facts.map((f) => ({
|
|
3284
3725
|
...f,
|
|
@@ -3400,8 +3841,8 @@ var TrieTellTool = class {
|
|
|
3400
3841
|
const mentionedFiles = extractFilePathsFromDescription(description);
|
|
3401
3842
|
mentionedFiles.forEach((f) => linkedFiles.add(f));
|
|
3402
3843
|
if (extractedSignal) {
|
|
3403
|
-
for (const
|
|
3404
|
-
|
|
3844
|
+
for (const gov of extractedSignal.governance) {
|
|
3845
|
+
gov.files.forEach((f) => linkedFiles.add(f));
|
|
3405
3846
|
}
|
|
3406
3847
|
}
|
|
3407
3848
|
const incidentIndex = new IncidentIndex(graph, projectPath);
|
|
@@ -3410,7 +3851,7 @@ var TrieTellTool = class {
|
|
|
3410
3851
|
let responseText = `Incident recorded${change ? ` and linked to change ${change.id}` : ""}.`;
|
|
3411
3852
|
if (extractedSignal) {
|
|
3412
3853
|
const counts = [
|
|
3413
|
-
extractedSignal.
|
|
3854
|
+
extractedSignal.governance.length > 0 ? `${extractedSignal.governance.length} governance` : null,
|
|
3414
3855
|
extractedSignal.facts.length > 0 ? `${extractedSignal.facts.length} fact(s)` : null,
|
|
3415
3856
|
extractedSignal.blockers.length > 0 ? `${extractedSignal.blockers.length} blocker(s)` : null,
|
|
3416
3857
|
extractedSignal.questions.length > 0 ? `${extractedSignal.questions.length} question(s)` : null
|
|
@@ -4886,7 +5327,7 @@ trie_explain type:"risk" target:"Adding Stripe integration for payments"
|
|
|
4886
5327
|
};
|
|
4887
5328
|
|
|
4888
5329
|
// src/tools/query-tools.ts
|
|
4889
|
-
var
|
|
5330
|
+
var TrieGetGovernanceTool = class {
|
|
4890
5331
|
async execute(input) {
|
|
4891
5332
|
const workDir = input.directory || getWorkingDirectory(void 0, true);
|
|
4892
5333
|
const storage = getStorage(workDir);
|
|
@@ -4909,48 +5350,56 @@ var TrieGetDecisionsTool = class {
|
|
|
4909
5350
|
if (input.relatedTo) query.relatedTo = input.relatedTo;
|
|
4910
5351
|
if (input.tags) query.tags = input.tags;
|
|
4911
5352
|
if (timeWindow) query.timeWindow = timeWindow;
|
|
4912
|
-
const
|
|
5353
|
+
const governance = await storage.queryGovernance(query);
|
|
4913
5354
|
return {
|
|
4914
5355
|
content: [{
|
|
4915
5356
|
type: "text",
|
|
4916
|
-
text: this.
|
|
5357
|
+
text: this.formatGovernance(governance)
|
|
4917
5358
|
}]
|
|
4918
5359
|
};
|
|
4919
5360
|
}
|
|
4920
|
-
|
|
4921
|
-
if (
|
|
4922
|
-
return "No
|
|
5361
|
+
formatGovernance(governance) {
|
|
5362
|
+
if (governance.length === 0) {
|
|
5363
|
+
return "No governance records found matching query.";
|
|
4923
5364
|
}
|
|
4924
|
-
let output = `Found ${
|
|
5365
|
+
let output = `Found ${governance.length} governance record(s):
|
|
4925
5366
|
|
|
4926
5367
|
`;
|
|
4927
|
-
for (const
|
|
4928
|
-
const when = new Date(
|
|
4929
|
-
output += `\u{1F4CB} ${
|
|
5368
|
+
for (const gov of governance) {
|
|
5369
|
+
const when = new Date(gov.when).toLocaleDateString();
|
|
5370
|
+
output += `\u{1F4CB} ${gov.decision}
|
|
4930
5371
|
`;
|
|
4931
|
-
output += ` Context: ${
|
|
5372
|
+
output += ` Context: ${gov.context}
|
|
4932
5373
|
`;
|
|
4933
|
-
if (
|
|
4934
|
-
output += ` Reasoning: ${
|
|
5374
|
+
if (gov.reasoning) {
|
|
5375
|
+
output += ` Reasoning: ${gov.reasoning}
|
|
4935
5376
|
`;
|
|
4936
5377
|
}
|
|
4937
|
-
if (
|
|
4938
|
-
output += ` Tradeoffs considered: ${
|
|
5378
|
+
if (gov.tradeoffs && gov.tradeoffs.length > 0) {
|
|
5379
|
+
output += ` Tradeoffs considered: ${gov.tradeoffs.join(", ")}
|
|
4939
5380
|
`;
|
|
4940
5381
|
}
|
|
4941
5382
|
output += ` When: ${when}
|
|
4942
5383
|
`;
|
|
4943
|
-
if (
|
|
4944
|
-
output += ` Files: ${
|
|
5384
|
+
if (gov.files.length > 0) {
|
|
5385
|
+
output += ` Files: ${gov.files.join(", ")}
|
|
4945
5386
|
`;
|
|
4946
5387
|
}
|
|
4947
|
-
output += ` Tags: ${
|
|
5388
|
+
output += ` Tags: ${gov.tags.join(", ")}
|
|
4948
5389
|
`;
|
|
4949
5390
|
output += `
|
|
4950
5391
|
`;
|
|
4951
5392
|
}
|
|
4952
5393
|
return output;
|
|
4953
5394
|
}
|
|
5395
|
+
/**
|
|
5396
|
+
* @deprecated Use formatGovernance instead
|
|
5397
|
+
*/
|
|
5398
|
+
formatDecisions(decisions) {
|
|
5399
|
+
return this.formatGovernance(decisions);
|
|
5400
|
+
}
|
|
5401
|
+
};
|
|
5402
|
+
var TrieGetDecisionsTool = class extends TrieGetGovernanceTool {
|
|
4954
5403
|
};
|
|
4955
5404
|
var TrieGetBlockersTool = class {
|
|
4956
5405
|
async execute(input) {
|
|
@@ -4993,7 +5442,7 @@ var TrieGetBlockersTool = class {
|
|
|
4993
5442
|
return output;
|
|
4994
5443
|
}
|
|
4995
5444
|
};
|
|
4996
|
-
var
|
|
5445
|
+
var TrieGetRelatedGovernanceTool = class {
|
|
4997
5446
|
async execute(input) {
|
|
4998
5447
|
const workDir = input.directory || getWorkingDirectory(void 0, true);
|
|
4999
5448
|
const storage = getStorage(workDir);
|
|
@@ -5003,40 +5452,185 @@ var TrieGetRelatedDecisionsTool = class {
|
|
|
5003
5452
|
};
|
|
5004
5453
|
const relatedTo = input.file || input.topic;
|
|
5005
5454
|
if (relatedTo) query.relatedTo = relatedTo;
|
|
5006
|
-
const
|
|
5455
|
+
const governance = await storage.queryGovernance(query);
|
|
5007
5456
|
return {
|
|
5008
5457
|
content: [{
|
|
5009
5458
|
type: "text",
|
|
5010
|
-
text: new
|
|
5459
|
+
text: new TrieGetGovernanceTool().formatGovernance(governance)
|
|
5011
5460
|
}]
|
|
5012
5461
|
};
|
|
5013
5462
|
}
|
|
5014
5463
|
};
|
|
5464
|
+
var TrieGetRelatedDecisionsTool = class extends TrieGetRelatedGovernanceTool {
|
|
5465
|
+
};
|
|
5466
|
+
function formatGoals(goals, hasRecentNudges) {
|
|
5467
|
+
if (goals.length === 0) return "No goals found.";
|
|
5468
|
+
const unchecked = hasRecentNudges === false;
|
|
5469
|
+
let out = `Found ${goals.length} goal(s):
|
|
5470
|
+
|
|
5471
|
+
`;
|
|
5472
|
+
for (const g of goals) {
|
|
5473
|
+
const caught = g.metadata?.caughtCount ?? 0;
|
|
5474
|
+
out += `\u{1F3AF} ${g.description}
|
|
5475
|
+
`;
|
|
5476
|
+
out += ` Status: ${g.status}${g.category ? ` \xB7 Category: ${g.category}` : ""}`;
|
|
5477
|
+
if (g.target != null && g.currentValue != null) {
|
|
5478
|
+
out += ` \xB7 Progress: ${g.currentValue}/${g.target}`;
|
|
5479
|
+
}
|
|
5480
|
+
if (caught > 0) out += ` \xB7 ${caught} violation(s) caught`;
|
|
5481
|
+
if (unchecked) out += ` (UNCHECKED - use trie_scan_for_goal_violations to verify)`;
|
|
5482
|
+
out += "\n\n";
|
|
5483
|
+
}
|
|
5484
|
+
return out;
|
|
5485
|
+
}
|
|
5486
|
+
function formatHypotheses(hypotheses) {
|
|
5487
|
+
if (hypotheses.length === 0) return "No hypotheses found.";
|
|
5488
|
+
let out = `Found ${hypotheses.length} hypothesis/hypotheses:
|
|
5489
|
+
|
|
5490
|
+
`;
|
|
5491
|
+
for (const h of hypotheses) {
|
|
5492
|
+
const hasEvidence = (h.evidence?.length ?? 0) > 0;
|
|
5493
|
+
const confLabel = hasEvidence && h.confidence != null ? `${Math.round((h.confidence ?? 0) * 100)}%` : "untested";
|
|
5494
|
+
const evidenceCount = h.evidence?.length ?? 0;
|
|
5495
|
+
const untested = evidenceCount === 0;
|
|
5496
|
+
out += `\u{1F52C} ${h.statement}
|
|
5497
|
+
`;
|
|
5498
|
+
out += ` ID: ${h.id} \xB7 Status: ${h.status}${h.category ? ` \xB7 Category: ${h.category}` : ""} \xB7 ${confLabel} \xB7 ${evidenceCount} evidence`;
|
|
5499
|
+
if (untested) out += ` (use trie_test_hypothesis with hypothesisId: "${h.id}" to gather evidence)`;
|
|
5500
|
+
out += "\n\n";
|
|
5501
|
+
}
|
|
5502
|
+
return out;
|
|
5503
|
+
}
|
|
5504
|
+
function formatNudges(nudges) {
|
|
5505
|
+
if (nudges.length === 0) return "No nudges (goal violations) found.";
|
|
5506
|
+
let out = `Found ${nudges.length} nudge(s) / goal violation(s):
|
|
5507
|
+
|
|
5508
|
+
`;
|
|
5509
|
+
for (const n of nudges) {
|
|
5510
|
+
out += `\u26A0\uFE0F [${n.severity}] ${n.message}
|
|
5511
|
+
`;
|
|
5512
|
+
if (n.file) out += ` File: ${n.file}
|
|
5513
|
+
`;
|
|
5514
|
+
if (n.suggestedAction) out += ` Suggested: ${n.suggestedAction}
|
|
5515
|
+
`;
|
|
5516
|
+
out += "\n";
|
|
5517
|
+
}
|
|
5518
|
+
return out;
|
|
5519
|
+
}
|
|
5015
5520
|
var TrieQueryContextTool = class {
|
|
5016
5521
|
async execute(input) {
|
|
5017
5522
|
const workDir = input.directory || getWorkingDirectory(void 0, true);
|
|
5018
5523
|
const storage = getStorage(workDir);
|
|
5019
5524
|
await storage.initialize();
|
|
5020
5525
|
const keywords = input.query.toLowerCase().split(/\s+/);
|
|
5526
|
+
const limit = input.limit ?? 10;
|
|
5021
5527
|
let output = `Query: "${input.query}"
|
|
5022
5528
|
|
|
5023
5529
|
`;
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5530
|
+
const includeGoals = !input.type || input.type === "goals" || input.type === "all";
|
|
5531
|
+
const includeHypotheses = !input.type || input.type === "hypotheses" || input.type === "all";
|
|
5532
|
+
const includeNudges = !input.type || input.type === "nudges" || input.type === "all";
|
|
5533
|
+
const includeGovernance = !input.type || input.type === "governance" || input.type === "decisions" || input.type === "all";
|
|
5534
|
+
const includeBlockers = !input.type || input.type === "blockers" || input.type === "all";
|
|
5535
|
+
if (includeGoals) {
|
|
5536
|
+
try {
|
|
5537
|
+
const projectState = getProjectState(workDir);
|
|
5538
|
+
await projectState.load();
|
|
5539
|
+
const allGoals = projectState.getAllGoals();
|
|
5540
|
+
const matches = keywords.length === 0 || keywords.some((kw) => kw === "goal" || kw === "goals" || kw === "all") ? allGoals : allGoals.filter(
|
|
5541
|
+
(g) => keywords.some(
|
|
5542
|
+
(kw) => g.description.toLowerCase().includes(kw) || (g.category || "").toLowerCase().includes(kw) || g.status.toLowerCase().includes(kw)
|
|
5543
|
+
)
|
|
5544
|
+
);
|
|
5545
|
+
const toShow = matches.slice(0, limit);
|
|
5546
|
+
if (toShow.length > 0) {
|
|
5547
|
+
const nudges = await storage.queryNudges({ resolved: false, limit: 1 }).catch(() => []);
|
|
5548
|
+
const hasRecentNudges = nudges.length > 0;
|
|
5549
|
+
output += `\u{1F3AF} GOALS (${toShow.length}):
|
|
5550
|
+
`;
|
|
5551
|
+
output += formatGoals(toShow.map((g) => ({
|
|
5552
|
+
description: g.description,
|
|
5553
|
+
status: g.status,
|
|
5554
|
+
...g.category != null ? { category: g.category } : {},
|
|
5555
|
+
...g.currentValue != null ? { currentValue: g.currentValue } : {},
|
|
5556
|
+
...g.target != null ? { target: g.target } : {},
|
|
5557
|
+
...g.metadata ? { metadata: g.metadata } : {}
|
|
5558
|
+
})), hasRecentNudges);
|
|
5559
|
+
output += "\n";
|
|
5560
|
+
}
|
|
5561
|
+
} catch (e) {
|
|
5562
|
+
output += `(Goals unavailable: ${e instanceof Error ? e.message : "unknown"})
|
|
5563
|
+
|
|
5564
|
+
`;
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
if (includeHypotheses) {
|
|
5568
|
+
try {
|
|
5569
|
+
const projectState = getProjectState(workDir);
|
|
5570
|
+
await projectState.load();
|
|
5571
|
+
const allHypotheses = projectState.getAllHypotheses();
|
|
5572
|
+
const matches = keywords.length === 0 || keywords.some((kw) => kw === "hypothesis" || kw === "hypotheses" || kw === "all") ? allHypotheses : allHypotheses.filter(
|
|
5573
|
+
(h) => keywords.some(
|
|
5574
|
+
(kw) => h.statement.toLowerCase().includes(kw) || (h.category || "").toLowerCase().includes(kw) || h.status.toLowerCase().includes(kw)
|
|
5575
|
+
)
|
|
5576
|
+
);
|
|
5577
|
+
const toShow = matches.slice(0, limit);
|
|
5578
|
+
if (toShow.length > 0) {
|
|
5579
|
+
output += `\u{1F52C} HYPOTHESES (${toShow.length}):
|
|
5580
|
+
`;
|
|
5581
|
+
output += formatHypotheses(toShow.map((h) => ({
|
|
5582
|
+
id: h.id,
|
|
5583
|
+
statement: h.statement,
|
|
5584
|
+
status: h.status,
|
|
5585
|
+
...h.confidence != null ? { confidence: h.confidence } : {},
|
|
5586
|
+
...h.category != null ? { category: h.category } : {},
|
|
5587
|
+
...h.evidence ? { evidence: h.evidence } : {}
|
|
5588
|
+
})));
|
|
5589
|
+
output += "\n";
|
|
5590
|
+
}
|
|
5591
|
+
} catch (e) {
|
|
5592
|
+
output += `(Hypotheses unavailable: ${e instanceof Error ? e.message : "unknown"})
|
|
5593
|
+
|
|
5594
|
+
`;
|
|
5595
|
+
}
|
|
5596
|
+
}
|
|
5597
|
+
if (includeNudges) {
|
|
5598
|
+
try {
|
|
5599
|
+
const nudges = await storage.queryNudges({ resolved: false, limit });
|
|
5600
|
+
const matches = nudges.length === 0 ? [] : keywords.length === 0 || keywords.some((kw) => kw === "nudge" || kw === "nudges" || kw === "violation" || kw === "violations" || kw === "all") ? nudges : nudges.filter(
|
|
5601
|
+
(n) => keywords.some(
|
|
5602
|
+
(kw) => (n.message || "").toLowerCase().includes(kw) || (n.file || "").toLowerCase().includes(kw)
|
|
5603
|
+
)
|
|
5604
|
+
);
|
|
5605
|
+
const toShow = matches.slice(0, limit);
|
|
5606
|
+
if (toShow.length > 0) {
|
|
5607
|
+
output += `\u26A0\uFE0F NUDGES / GOAL VIOLATIONS (${toShow.length}):
|
|
5608
|
+
`;
|
|
5609
|
+
output += formatNudges(toShow);
|
|
5610
|
+
output += "\n";
|
|
5611
|
+
}
|
|
5612
|
+
} catch (e) {
|
|
5613
|
+
output += `(Nudges unavailable: ${e instanceof Error ? e.message : "unknown"})
|
|
5614
|
+
|
|
5615
|
+
`;
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
if (includeGovernance) {
|
|
5619
|
+
const governance = await storage.queryGovernance({ limit });
|
|
5620
|
+
const matches = governance.filter(
|
|
5621
|
+
(g) => keywords.some(
|
|
5622
|
+
(kw) => g.decision.toLowerCase().includes(kw) || g.context.toLowerCase().includes(kw) || g.tags.some((t) => t.toLowerCase().includes(kw))
|
|
5029
5623
|
)
|
|
5030
5624
|
);
|
|
5031
5625
|
if (matches.length > 0) {
|
|
5032
|
-
output += `\u{1F4CB}
|
|
5626
|
+
output += `\u{1F4CB} GOVERNANCE (${matches.length}):
|
|
5033
5627
|
`;
|
|
5034
|
-
output += new
|
|
5628
|
+
output += new TrieGetGovernanceTool().formatGovernance(matches);
|
|
5035
5629
|
output += "\n";
|
|
5036
5630
|
}
|
|
5037
5631
|
}
|
|
5038
|
-
if (
|
|
5039
|
-
const blockers = await storage.queryBlockers({ limit
|
|
5632
|
+
if (includeBlockers) {
|
|
5633
|
+
const blockers = await storage.queryBlockers({ limit });
|
|
5040
5634
|
const matches = blockers.filter(
|
|
5041
5635
|
(b) => keywords.some(
|
|
5042
5636
|
(kw) => b.blocker.toLowerCase().includes(kw) || b.tags.some((t) => t.toLowerCase().includes(kw))
|
|
@@ -5168,13 +5762,24 @@ var CHAT_TOOLS = [
|
|
|
5168
5762
|
required: ["type", "target"]
|
|
5169
5763
|
}
|
|
5170
5764
|
},
|
|
5765
|
+
{
|
|
5766
|
+
name: "trie_get_governance",
|
|
5767
|
+
description: "Query the governance ledger \u2014 architectural decisions, standards, and team agreements recorded by Trie.",
|
|
5768
|
+
input_schema: {
|
|
5769
|
+
type: "object",
|
|
5770
|
+
properties: {
|
|
5771
|
+
relatedTo: { type: "string", description: "Filter governance records related to a topic or file" },
|
|
5772
|
+
limit: { type: "number", description: "Max results (default 10)" }
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
5775
|
+
},
|
|
5171
5776
|
{
|
|
5172
5777
|
name: "trie_get_decisions",
|
|
5173
|
-
description: "Query the
|
|
5778
|
+
description: "[DEPRECATED - use trie_get_governance] Query the governance ledger \u2014 architectural decisions, standards, and team agreements.",
|
|
5174
5779
|
input_schema: {
|
|
5175
5780
|
type: "object",
|
|
5176
5781
|
properties: {
|
|
5177
|
-
relatedTo: { type: "string", description: "Filter
|
|
5782
|
+
relatedTo: { type: "string", description: "Filter governance records related to a topic or file" },
|
|
5178
5783
|
limit: { type: "number", description: "Max results (default 10)" }
|
|
5179
5784
|
}
|
|
5180
5785
|
}
|
|
@@ -5191,12 +5796,12 @@ var CHAT_TOOLS = [
|
|
|
5191
5796
|
},
|
|
5192
5797
|
{
|
|
5193
5798
|
name: "trie_query_context",
|
|
5194
|
-
description:
|
|
5799
|
+
description: 'Natural-language search across ALL Trie context: goals, hypotheses, nudges (goal violations), governance, blockers, facts, and questions. Use for "what are my goals", "show hypotheses", "any nudges", "recent governance", etc.',
|
|
5195
5800
|
input_schema: {
|
|
5196
5801
|
type: "object",
|
|
5197
5802
|
properties: {
|
|
5198
|
-
query: { type: "string", description:
|
|
5199
|
-
type: { type: "string", enum: ["decisions", "blockers", "facts", "questions", "all"], description: "Narrow to a specific category (default all)" },
|
|
5803
|
+
query: { type: "string", description: 'Natural language search query (e.g. "goals", "hypotheses", "nudges", "governance")' },
|
|
5804
|
+
type: { type: "string", enum: ["goals", "hypotheses", "nudges", "governance", "decisions", "blockers", "facts", "questions", "all"], description: "Narrow to a specific category (default all)" },
|
|
5200
5805
|
limit: { type: "number", description: "Max results (default 10)" }
|
|
5201
5806
|
},
|
|
5202
5807
|
required: ["query"]
|
|
@@ -5339,6 +5944,20 @@ var CHAT_TOOLS = [
|
|
|
5339
5944
|
}
|
|
5340
5945
|
}
|
|
5341
5946
|
}
|
|
5947
|
+
},
|
|
5948
|
+
{
|
|
5949
|
+
name: "trie_test_hypothesis",
|
|
5950
|
+
description: "Gather evidence for a hypothesis using AI analysis of the codebase. Use when hypotheses have 0 evidence (untested) \u2014 proactively offer to run this to validate/invalidate them. Runs Anthropic RAG-style analysis across Trie context.",
|
|
5951
|
+
input_schema: {
|
|
5952
|
+
type: "object",
|
|
5953
|
+
properties: {
|
|
5954
|
+
hypothesisId: {
|
|
5955
|
+
type: "string",
|
|
5956
|
+
description: "ID of the hypothesis to test (from trie_query_context or project context)"
|
|
5957
|
+
}
|
|
5958
|
+
},
|
|
5959
|
+
required: ["hypothesisId"]
|
|
5960
|
+
}
|
|
5342
5961
|
}
|
|
5343
5962
|
];
|
|
5344
5963
|
async function executeTool(name, input, onProgress) {
|
|
@@ -5366,6 +5985,11 @@ async function executeTool(name, input, onProgress) {
|
|
|
5366
5985
|
const result = await tool.execute(withDir);
|
|
5367
5986
|
return textFromResult(result);
|
|
5368
5987
|
}
|
|
5988
|
+
case "trie_get_governance": {
|
|
5989
|
+
const tool = new TrieGetGovernanceTool();
|
|
5990
|
+
const result = await tool.execute(withDir);
|
|
5991
|
+
return textFromResult(result);
|
|
5992
|
+
}
|
|
5369
5993
|
case "trie_get_decisions": {
|
|
5370
5994
|
const tool = new TrieGetDecisionsTool();
|
|
5371
5995
|
const result = await tool.execute(withDir);
|
|
@@ -5389,16 +6013,17 @@ async function executeTool(name, input, onProgress) {
|
|
|
5389
6013
|
const desc = String(input.description || "").trim();
|
|
5390
6014
|
if (!desc) return "Goal description is required.";
|
|
5391
6015
|
const category = input.category || "general";
|
|
5392
|
-
const agentState =
|
|
6016
|
+
const agentState = getProjectState(directory);
|
|
5393
6017
|
await agentState.load();
|
|
6018
|
+
const initialValue = await measureInitialGoalValue(desc, directory);
|
|
5394
6019
|
const goal = {
|
|
5395
6020
|
id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
5396
6021
|
description: desc,
|
|
5397
6022
|
type: "custom",
|
|
5398
6023
|
metric: "progress",
|
|
5399
6024
|
target: 100,
|
|
5400
|
-
currentValue:
|
|
5401
|
-
startValue:
|
|
6025
|
+
currentValue: initialValue,
|
|
6026
|
+
startValue: initialValue,
|
|
5402
6027
|
status: "active",
|
|
5403
6028
|
autoGenerated: false,
|
|
5404
6029
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5407,24 +6032,25 @@ async function executeTool(name, input, onProgress) {
|
|
|
5407
6032
|
category
|
|
5408
6033
|
};
|
|
5409
6034
|
await agentState.addGoal(goal);
|
|
5410
|
-
return `Goal created: "${desc}" [${category}]`;
|
|
6035
|
+
return `Goal created: "${desc}" [${category}]${initialValue > 0 ? ` (starting at ${initialValue} issues)` : ""}`;
|
|
5411
6036
|
}
|
|
5412
6037
|
case "trie_add_hypothesis": {
|
|
5413
6038
|
const stmt = String(input.statement || "").trim();
|
|
5414
6039
|
if (!stmt) return "Hypothesis statement is required.";
|
|
5415
6040
|
const category = input.category || "general";
|
|
5416
|
-
const agentState =
|
|
6041
|
+
const agentState = getProjectState(directory);
|
|
5417
6042
|
await agentState.load();
|
|
5418
6043
|
const hypothesis = {
|
|
5419
6044
|
id: `hyp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
5420
6045
|
statement: stmt,
|
|
5421
|
-
confidence: 0
|
|
6046
|
+
confidence: 0,
|
|
5422
6047
|
status: "proposed",
|
|
5423
6048
|
evidence: [],
|
|
5424
6049
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5425
6050
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5426
6051
|
testCriteria: String(input.test_criteria || "Collect evidence from scans"),
|
|
5427
|
-
category
|
|
6052
|
+
category,
|
|
6053
|
+
autoGenerated: false
|
|
5428
6054
|
};
|
|
5429
6055
|
await agentState.addHypothesis(hypothesis);
|
|
5430
6056
|
return `Hypothesis created: "${stmt}" [${category}]`;
|
|
@@ -5470,10 +6096,11 @@ async function executeTool(name, input, onProgress) {
|
|
|
5470
6096
|
};
|
|
5471
6097
|
const storage = new TieredStorage(directory);
|
|
5472
6098
|
await storage.storeSignal({
|
|
5473
|
-
|
|
6099
|
+
governance: [decisionObj],
|
|
5474
6100
|
facts: [],
|
|
5475
6101
|
blockers: [],
|
|
5476
6102
|
questions: [],
|
|
6103
|
+
gotchas: [],
|
|
5477
6104
|
metadata: {
|
|
5478
6105
|
extractedAt: now,
|
|
5479
6106
|
sourceType: "conversation"
|
|
@@ -5620,8 +6247,8 @@ ${truncated}`;
|
|
|
5620
6247
|
const goalId = input.goalId ? String(input.goalId).trim() : void 0;
|
|
5621
6248
|
try {
|
|
5622
6249
|
onProgress?.("Loading goals...");
|
|
5623
|
-
const { checkFilesForGoalViolations, getActiveGoals } = await import("./goal-validator-
|
|
5624
|
-
const agentState =
|
|
6250
|
+
const { checkFilesForGoalViolations, getActiveGoals } = await import("./goal-validator-GISXYANK.js");
|
|
6251
|
+
const agentState = getProjectState(directory);
|
|
5625
6252
|
await agentState.load();
|
|
5626
6253
|
const allGoals = await getActiveGoals(directory);
|
|
5627
6254
|
const goalsToCheck = goalId ? allGoals.filter((g) => g.id === goalId) : allGoals;
|
|
@@ -5633,6 +6260,20 @@ ${truncated}`;
|
|
|
5633
6260
|
if (violations.length === 0) {
|
|
5634
6261
|
return `\u2713 Scan complete! No violations found for ${goalsToCheck.length} goal(s).`;
|
|
5635
6262
|
}
|
|
6263
|
+
const { storeIssues } = await import("./issue-store-BO5OWLJW.js");
|
|
6264
|
+
const { basename } = await import("path");
|
|
6265
|
+
const issuesToStore = violations.map((v, i) => ({
|
|
6266
|
+
id: `goal-violation-${Date.now()}-${i}`,
|
|
6267
|
+
file: v.file,
|
|
6268
|
+
agent: "goal-violation",
|
|
6269
|
+
severity: v.severity === "critical" ? "critical" : v.severity === "warning" ? "serious" : "moderate",
|
|
6270
|
+
issue: v.message,
|
|
6271
|
+
fix: "Review and fix",
|
|
6272
|
+
category: "goal-violation",
|
|
6273
|
+
confidence: 80,
|
|
6274
|
+
autoFixable: false
|
|
6275
|
+
}));
|
|
6276
|
+
await storeIssues(issuesToStore, basename(directory), directory);
|
|
5636
6277
|
let result = `Found ${violations.length} violation(s):
|
|
5637
6278
|
|
|
5638
6279
|
`;
|
|
@@ -5643,12 +6284,66 @@ ${truncated}`;
|
|
|
5643
6284
|
|
|
5644
6285
|
`;
|
|
5645
6286
|
}
|
|
5646
|
-
result += "
|
|
6287
|
+
result += "Violations recorded to ledger (AI source). Check Ledger view.";
|
|
5647
6288
|
return result;
|
|
5648
6289
|
} catch (error) {
|
|
5649
6290
|
return `Scan failed: ${error.message}`;
|
|
5650
6291
|
}
|
|
5651
6292
|
}
|
|
6293
|
+
case "trie_test_hypothesis": {
|
|
6294
|
+
const hypothesisId = String(input.hypothesisId || "").trim();
|
|
6295
|
+
if (!hypothesisId) {
|
|
6296
|
+
try {
|
|
6297
|
+
const agentState = getProjectState(directory);
|
|
6298
|
+
await agentState.load();
|
|
6299
|
+
const hypotheses = agentState.getActiveHypotheses();
|
|
6300
|
+
if (hypotheses.length === 0) {
|
|
6301
|
+
return "No active hypotheses found. Use trie_add_hypothesis to create one first.";
|
|
6302
|
+
}
|
|
6303
|
+
let result = `Found ${hypotheses.length} active hypothesis/hypotheses. Please specify which one to test:
|
|
6304
|
+
|
|
6305
|
+
`;
|
|
6306
|
+
for (const h of hypotheses) {
|
|
6307
|
+
const evidenceCount = h.evidence?.length ?? 0;
|
|
6308
|
+
const confPercent = Math.round((h.confidence ?? 0) * 100);
|
|
6309
|
+
result += `\u2022 ID: ${h.id}
|
|
6310
|
+
Statement: ${h.statement}
|
|
6311
|
+
Evidence: ${evidenceCount} points | Confidence: ${confPercent}%
|
|
6312
|
+
|
|
6313
|
+
`;
|
|
6314
|
+
}
|
|
6315
|
+
result += `Call trie_test_hypothesis again with the hypothesisId you want to test.`;
|
|
6316
|
+
return result;
|
|
6317
|
+
} catch (error) {
|
|
6318
|
+
return `Failed to list hypotheses: ${error.message}`;
|
|
6319
|
+
}
|
|
6320
|
+
}
|
|
6321
|
+
try {
|
|
6322
|
+
onProgress?.("Gathering evidence for hypothesis...");
|
|
6323
|
+
const { gatherEvidenceForHypothesis } = await import("./hypothesis-K3KQJOXJ.js");
|
|
6324
|
+
const evidence = await gatherEvidenceForHypothesis(hypothesisId, directory);
|
|
6325
|
+
if (evidence.length === 0) {
|
|
6326
|
+
return `No evidence found for this hypothesis yet. The codebase may not have enough data to validate it \u2014 try running trie_scan_for_goal_violations first to populate issues, or add more context.`;
|
|
6327
|
+
}
|
|
6328
|
+
const supporting = evidence.filter((e) => e.supports).length;
|
|
6329
|
+
const against = evidence.length - supporting;
|
|
6330
|
+
let result = `Found ${evidence.length} evidence point(s): ${supporting} supporting, ${against} against.
|
|
6331
|
+
|
|
6332
|
+
`;
|
|
6333
|
+
for (const e of evidence.slice(0, 5)) {
|
|
6334
|
+
result += `${e.supports ? "\u2713" : "\u2717"} ${e.description}
|
|
6335
|
+
`;
|
|
6336
|
+
}
|
|
6337
|
+
if (evidence.length > 5) result += `
|
|
6338
|
+
... and ${evidence.length - 5} more.`;
|
|
6339
|
+
result += `
|
|
6340
|
+
|
|
6341
|
+
Hypothesis confidence has been updated. Check the Hypotheses view for the new confidence score.`;
|
|
6342
|
+
return result;
|
|
6343
|
+
} catch (error) {
|
|
6344
|
+
return `Hypothesis test failed: ${error.message}`;
|
|
6345
|
+
}
|
|
6346
|
+
}
|
|
5652
6347
|
default:
|
|
5653
6348
|
return `Unknown tool: ${name}`;
|
|
5654
6349
|
}
|
|
@@ -5659,50 +6354,73 @@ ${truncated}`;
|
|
|
5659
6354
|
}
|
|
5660
6355
|
|
|
5661
6356
|
// src/cli/dashboard/views/ChatView.tsx
|
|
5662
|
-
import { Fragment as
|
|
5663
|
-
var VISIBLE_MESSAGES = 8;
|
|
6357
|
+
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5664
6358
|
async function buildContext(workDir, dashboardState) {
|
|
5665
6359
|
const parts = [];
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
6360
|
+
let recentNudges = [];
|
|
6361
|
+
if (dashboardState?.agentInsights?.length) {
|
|
6362
|
+
recentNudges = dashboardState.agentInsights.filter((i) => i.type === "warning" && !i.dismissed).slice(0, 5).map((i) => {
|
|
6363
|
+
const file = i.suggestedAction?.replace(/^Review /, "");
|
|
6364
|
+
return { message: i.message, ...file ? { file } : {}, ...i.priority != null ? { priority: i.priority } : {} };
|
|
6365
|
+
});
|
|
6366
|
+
}
|
|
6367
|
+
if (recentNudges.length === 0) {
|
|
6368
|
+
try {
|
|
6369
|
+
const storage = new TieredStorage(workDir);
|
|
6370
|
+
await storage.initialize();
|
|
6371
|
+
const fromStorage = await storage.queryNudges({ resolved: false, limit: 5 });
|
|
6372
|
+
recentNudges = fromStorage.map((n) => ({ message: n.message, ...n.file ? { file: n.file } : {}, ...n.priority != null ? { priority: n.priority } : {} }));
|
|
6373
|
+
} catch {
|
|
6374
|
+
}
|
|
6375
|
+
}
|
|
6376
|
+
if (recentNudges.length > 0) {
|
|
6377
|
+
parts.push("Recent goal violations (nudges):\n" + recentNudges.map((n) => {
|
|
6378
|
+
const fileMatch = n.message.match(/in ([^:]+):/);
|
|
6379
|
+
const goalMatch = n.message.match(/Goal "([^"]+)"/);
|
|
6380
|
+
const violationMatch = n.message.match(/: (.+?) \[/);
|
|
6381
|
+
return `- File: ${n.file || fileMatch?.[1] || "unknown"}
|
|
5674
6382
|
Goal: ${goalMatch?.[1] || "unknown"}
|
|
5675
6383
|
Violation: ${violationMatch?.[1] || n.message}
|
|
5676
|
-
Priority: ${n.priority}`;
|
|
5677
|
-
|
|
5678
|
-
}
|
|
6384
|
+
Priority: ${n.priority ?? "\u2014"}`;
|
|
6385
|
+
}).join("\n"));
|
|
5679
6386
|
}
|
|
5680
6387
|
try {
|
|
5681
|
-
const
|
|
5682
|
-
await
|
|
5683
|
-
const activeGoals =
|
|
6388
|
+
const projectState = getProjectState(workDir);
|
|
6389
|
+
await projectState.load();
|
|
6390
|
+
const activeGoals = projectState.getAllGoals().filter((g) => g.status === "active");
|
|
5684
6391
|
if (activeGoals.length > 0) {
|
|
5685
6392
|
parts.push("Active goals:\n" + activeGoals.map((g) => {
|
|
5686
6393
|
const metadata = g.metadata || {};
|
|
5687
6394
|
const caughtCount = metadata.caughtCount || 0;
|
|
5688
6395
|
const lastCaught = metadata.lastCaught ? ` (last violation: ${metadata.lastCaughtFile || "unknown"})` : "";
|
|
5689
|
-
|
|
6396
|
+
const unchecked = recentNudges.length === 0;
|
|
6397
|
+
return `- "${g.description}" [${g.category || "general"}]${caughtCount > 0 ? ` - ${caughtCount} violation(s)${lastCaught}` : ""}${unchecked ? " (UNCHECKED - use trie_scan_for_goal_violations to verify)" : ""}`;
|
|
6398
|
+
}).join("\n"));
|
|
6399
|
+
}
|
|
6400
|
+
const hypotheses = projectState.getAllHypotheses().filter((h) => h.status === "testing" || h.status === "validated");
|
|
6401
|
+
if (hypotheses.length > 0) {
|
|
6402
|
+
parts.push("Hypotheses (testing/validated):\n" + hypotheses.map((h) => {
|
|
6403
|
+
const hasEvidence = (h.evidence?.length ?? 0) > 0;
|
|
6404
|
+
const confLabel = hasEvidence && h.confidence != null ? `${Math.round(h.confidence * 100)}%` : "untested";
|
|
6405
|
+
const evidenceCount = h.evidence?.length ?? 0;
|
|
6406
|
+
const untested = evidenceCount === 0;
|
|
6407
|
+
return `- ID: ${h.id} | "${h.statement}" [${h.status}] ${confLabel} \xB7 ${evidenceCount} evidence${untested ? " (UNTESTED - use trie_test_hypothesis to gather evidence)" : ""}`;
|
|
5690
6408
|
}).join("\n"));
|
|
5691
6409
|
}
|
|
5692
6410
|
} catch (error) {
|
|
5693
|
-
console.error("Failed to load
|
|
6411
|
+
console.error("Failed to load project state:", error);
|
|
5694
6412
|
}
|
|
5695
6413
|
try {
|
|
5696
6414
|
const storage = new TieredStorage(workDir);
|
|
5697
6415
|
try {
|
|
5698
|
-
const
|
|
5699
|
-
if (
|
|
5700
|
-
parts.push("Recent
|
|
6416
|
+
const governance = await storage.queryGovernance({ limit: 10 });
|
|
6417
|
+
if (governance.length > 0) {
|
|
6418
|
+
parts.push("Recent governance:\n" + governance.map(
|
|
5701
6419
|
(d) => `- ${d.decision} (${d.when}${d.hash ? `, hash: ${d.hash.slice(0, 8)}` : ""})`
|
|
5702
6420
|
).join("\n"));
|
|
5703
6421
|
}
|
|
5704
6422
|
} catch (error) {
|
|
5705
|
-
console.error("Failed to query
|
|
6423
|
+
console.error("Failed to query governance:", error);
|
|
5706
6424
|
}
|
|
5707
6425
|
try {
|
|
5708
6426
|
const blockers = await storage.queryBlockers({ limit: 5 });
|
|
@@ -5758,12 +6476,12 @@ function chatHistoryToMessages(history) {
|
|
|
5758
6476
|
content: m.content
|
|
5759
6477
|
}));
|
|
5760
6478
|
}
|
|
5761
|
-
var SYSTEM_PROMPT = `You are Trie, a code
|
|
6479
|
+
var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
|
|
5762
6480
|
|
|
5763
6481
|
**What you CAN do:**
|
|
5764
6482
|
- Check recent goal violations (nudges) in the provided project context
|
|
5765
6483
|
- Record incidents, decisions, and feedback about the codebase
|
|
5766
|
-
- Query stored
|
|
6484
|
+
- Query ALL stored context: goals, hypotheses, nudges, decisions, blockers via trie_query_context
|
|
5767
6485
|
- Create and manage goals and hypotheses
|
|
5768
6486
|
- Propose fixes for goal violations (requires user confirmation before spawning Claude Code)
|
|
5769
6487
|
- Run AI-powered scans to detect goal violations across the entire codebase
|
|
@@ -5775,12 +6493,32 @@ var SYSTEM_PROMPT = `You are Trie, a code guardian assistant embedded in a termi
|
|
|
5775
6493
|
- It uses AI analysis and is much more reliable than regex pattern matching
|
|
5776
6494
|
- You also have trie_search_files but it requires ripgrep (often not installed)
|
|
5777
6495
|
|
|
6496
|
+
**When user asks "what are my goals", "show hypotheses", "any nudges", "latest decisions", etc.:**
|
|
6497
|
+
- The project context block already includes goals, hypotheses, nudges, decisions, blockers
|
|
6498
|
+
- If the user wants more detail or the context seems stale: Call trie_query_context with the relevant query (e.g. query: "goals", type: "goals")
|
|
6499
|
+
- trie_query_context returns goals, hypotheses, nudges, decisions, and blockers \u2014 use it for any "what do I have" questions
|
|
6500
|
+
|
|
6501
|
+
**PROACTIVE - When you see goals marked UNCHECKED (no recent nudges):**
|
|
6502
|
+
- These haven't been scanned recently. Proactively offer: "I see your goals haven't been checked recently. Would you like me to run trie_scan_for_goal_violations to verify they're being met?"
|
|
6503
|
+
- If the user agrees, call trie_scan_for_goal_violations. It uses AI to check the codebase against all active goals.
|
|
6504
|
+
|
|
6505
|
+
**PROACTIVE - When you see hypotheses with 0 evidence (marked UNTESTED):**
|
|
6506
|
+
- These have no evidence yet. Proactively offer: "I see you have N hypotheses with no evidence yet. Would you like me to run a scan and gather evidence for them? I can use trie_scan_for_goal_violations (to populate issues) and trie_test_hypothesis (to validate each one)."
|
|
6507
|
+
- If the user agrees, call trie_scan_for_goal_violations first (populates issues for hypothesis analysis), then trie_test_hypothesis for each untested hypothesis.
|
|
6508
|
+
- CRITICAL: trie_test_hypothesis requires a hypothesisId parameter. The hypothesis IDs are shown in the project context (look for "ID: hyp-..."). Always use these exact IDs, never numeric IDs like 1, 2, 3.
|
|
6509
|
+
|
|
5778
6510
|
**When user asks about code content (emojis, TODOs, etc.):**
|
|
5779
6511
|
1. First check the "Recent goal violations (nudges)" section in project context
|
|
5780
6512
|
2. If found, report what you see
|
|
5781
6513
|
3. If not found or user wants a full scan: Call trie_scan_for_goal_violations
|
|
5782
6514
|
4. The scan will find all violations and update the Goals view automatically
|
|
5783
6515
|
|
|
6516
|
+
**When user asks to test hypotheses:**
|
|
6517
|
+
1. Look at the project context to find hypothesis IDs (format: "ID: hyp-..." at the start of each hypothesis line)
|
|
6518
|
+
2. For each hypothesis you want to test, call trie_test_hypothesis with the EXACT hypothesis ID from the context
|
|
6519
|
+
3. NEVER use numeric IDs like 1, 2, 3 - always use the full ID like "hyp-1771957097120-bogco0"
|
|
6520
|
+
4. If hypothesis IDs aren't in the context, first call trie_query_context with type="hypotheses" to fetch them
|
|
6521
|
+
|
|
5784
6522
|
**When user asks to fix violations:**
|
|
5785
6523
|
1. Look in "Recent goal violations (nudges)" section of project context
|
|
5786
6524
|
2. Extract: file path, goal description, and violation details for ALL files
|
|
@@ -5802,8 +6540,12 @@ function ChatView() {
|
|
|
5802
6540
|
const { chatState } = state;
|
|
5803
6541
|
const { messages, inputBuffer, loading, progress, messageQueue, currentSessionId, currentSessionTitle } = chatState;
|
|
5804
6542
|
const loadingRef = useRef(false);
|
|
6543
|
+
const { stdout } = useStdout9();
|
|
5805
6544
|
const [cursorVisible, setCursorVisible] = useState2(true);
|
|
5806
6545
|
const [scrollOffset, setScrollOffset] = useState2(0);
|
|
6546
|
+
const terminalHeight = stdout?.rows || 24;
|
|
6547
|
+
const availableLines = Math.max(8, terminalHeight - 7);
|
|
6548
|
+
const VISIBLE_MESSAGES = Math.min(availableLines, 20);
|
|
5807
6549
|
useEffect3(() => {
|
|
5808
6550
|
if (loading) {
|
|
5809
6551
|
setCursorVisible(true);
|
|
@@ -5822,7 +6564,7 @@ function ChatView() {
|
|
|
5822
6564
|
const saveChat = async () => {
|
|
5823
6565
|
try {
|
|
5824
6566
|
const workDir = getWorkingDirectory(void 0, true);
|
|
5825
|
-
const { getChatStore: getChatStore2 } = await import("./chat-store-
|
|
6567
|
+
const { getChatStore: getChatStore2 } = await import("./chat-store-OJLJCJFI.js");
|
|
5826
6568
|
const store = getChatStore2(workDir);
|
|
5827
6569
|
const sessionId = await store.saveSession(
|
|
5828
6570
|
messages,
|
|
@@ -5856,17 +6598,23 @@ function ChatView() {
|
|
|
5856
6598
|
const fixes = [];
|
|
5857
6599
|
const recentAssistantMessages = messages.filter((m) => m.role === "assistant").slice(-5);
|
|
5858
6600
|
for (const msg of recentAssistantMessages) {
|
|
5859
|
-
if (msg.pendingFixes
|
|
5860
|
-
|
|
6601
|
+
if (msg.pendingFixes?.length) {
|
|
6602
|
+
for (const pf of msg.pendingFixes) {
|
|
6603
|
+
if (pf.directory) fixes.push({ file: pf.file, goal: pf.goal, violation: pf.violation, directory: pf.directory, ...pf.suggestedFix ? { suggestedFix: pf.suggestedFix } : {} });
|
|
6604
|
+
}
|
|
5861
6605
|
} else if (msg.pendingFix) {
|
|
5862
|
-
|
|
6606
|
+
const pf = msg.pendingFix;
|
|
6607
|
+
if (pf.directory) {
|
|
6608
|
+
fixes.push({ file: pf.file, goal: pf.goal, violation: pf.violation, directory: pf.directory, ...pf.suggestedFix ? { suggestedFix: pf.suggestedFix } : {} });
|
|
6609
|
+
}
|
|
5863
6610
|
}
|
|
5864
6611
|
}
|
|
5865
6612
|
return fixes;
|
|
5866
6613
|
};
|
|
5867
6614
|
const allPendingFixes = collectPendingFixes();
|
|
5868
6615
|
const lastAssistantMessage = messages.filter((m) => m.role === "assistant").pop();
|
|
5869
|
-
const
|
|
6616
|
+
const lastFixesRaw = lastAssistantMessage?.pendingFixes?.length ? lastAssistantMessage.pendingFixes : lastAssistantMessage?.pendingFix ? [lastAssistantMessage.pendingFix] : [];
|
|
6617
|
+
const lastFixes = lastFixesRaw.filter((pf) => !!pf.directory).map((pf) => ({ file: pf.file, goal: pf.goal, violation: pf.violation, directory: pf.directory, ...pf.suggestedFix ? { suggestedFix: pf.suggestedFix } : {} }));
|
|
5870
6618
|
if (allPendingFixes.length > 0 && (isYes || isYesToAll || isNo)) {
|
|
5871
6619
|
if (isNo) {
|
|
5872
6620
|
dispatch({
|
|
@@ -5886,8 +6634,11 @@ function ChatView() {
|
|
|
5886
6634
|
for (const fix of fixesToApply) {
|
|
5887
6635
|
try {
|
|
5888
6636
|
await spawnClaudeCodeFix({
|
|
5889
|
-
|
|
5890
|
-
|
|
6637
|
+
file: fix.file,
|
|
6638
|
+
goal: fix.goal,
|
|
6639
|
+
violation: fix.violation,
|
|
6640
|
+
...fix.suggestedFix ? { suggestedFix: fix.suggestedFix } : {},
|
|
6641
|
+
cwd: fix.directory ?? workDir
|
|
5891
6642
|
});
|
|
5892
6643
|
results.push(`"${fix.file}"`);
|
|
5893
6644
|
} catch (error) {
|
|
@@ -5939,11 +6690,19 @@ ${contextBlock}`;
|
|
|
5939
6690
|
...messages,
|
|
5940
6691
|
{ role: "user", content: question, timestamp: Date.now() }
|
|
5941
6692
|
]);
|
|
6693
|
+
const LEDGER_WRITING_TOOLS = /* @__PURE__ */ new Set(["trie_scan_for_goal_violations", "trie_tell", "trie_add_goal"]);
|
|
6694
|
+
const executeToolWithRefresh = async (name, input, onProgress) => {
|
|
6695
|
+
const result2 = await executeTool(name, input, onProgress);
|
|
6696
|
+
if (LEDGER_WRITING_TOOLS.has(name)) {
|
|
6697
|
+
dispatch({ type: "INVALIDATE_MEMORY_TREE" });
|
|
6698
|
+
}
|
|
6699
|
+
return result2;
|
|
6700
|
+
};
|
|
5942
6701
|
const result = await runAIWithTools({
|
|
5943
6702
|
systemPrompt: fullSystem,
|
|
5944
6703
|
messages: history,
|
|
5945
6704
|
tools: CHAT_TOOLS,
|
|
5946
|
-
executeTool,
|
|
6705
|
+
executeTool: executeToolWithRefresh,
|
|
5947
6706
|
maxTokens: 4096,
|
|
5948
6707
|
maxToolRounds: 8,
|
|
5949
6708
|
onProgress: (msg) => dispatch({ type: "SET_CHAT_PROGRESS", message: msg })
|
|
@@ -5995,29 +6754,29 @@ ${contextBlock}`;
|
|
|
5995
6754
|
}
|
|
5996
6755
|
}
|
|
5997
6756
|
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
5998
|
-
action.toolCalls = result.toolCalls;
|
|
6757
|
+
action.toolCalls = result.toolCalls.map((tc, i) => ({ id: `tc-${Date.now()}-${i}`, name: tc.name, input: tc.input }));
|
|
5999
6758
|
const toolNames = new Set(result.toolCalls.map((tc) => tc.name));
|
|
6000
|
-
if (toolNames.has("trie_add_goal") || toolNames.has("trie_add_hypothesis")) {
|
|
6759
|
+
if (toolNames.has("trie_add_goal") || toolNames.has("trie_add_hypothesis") || toolNames.has("trie_test_hypothesis")) {
|
|
6001
6760
|
try {
|
|
6002
|
-
const agentState =
|
|
6761
|
+
const agentState = getProjectState(workDir);
|
|
6003
6762
|
await agentState.load();
|
|
6004
6763
|
if (toolNames.has("trie_add_goal")) {
|
|
6005
6764
|
const goals = agentState.getAllGoals();
|
|
6006
6765
|
dispatch({
|
|
6007
6766
|
type: "SET_GOALS",
|
|
6008
6767
|
goals: goals.map((g) => {
|
|
6009
|
-
const base = { id: g.id, description: g.description, type: g.type, target: g.target, currentValue: g.currentValue, status: g.status, autoGenerated: g.autoGenerated, updatedAt: g.updatedAt };
|
|
6010
|
-
return
|
|
6768
|
+
const base = { id: g.id, description: g.description, type: g.type, target: g.target, currentValue: g.currentValue, status: g.status, autoGenerated: g.autoGenerated, updatedAt: g.updatedAt, ...g.category != null ? { category: g.category } : {} };
|
|
6769
|
+
return base;
|
|
6011
6770
|
})
|
|
6012
6771
|
});
|
|
6013
6772
|
}
|
|
6014
|
-
if (toolNames.has("trie_add_hypothesis")) {
|
|
6773
|
+
if (toolNames.has("trie_add_hypothesis") || toolNames.has("trie_test_hypothesis")) {
|
|
6015
6774
|
const hypotheses = agentState.getAllHypotheses();
|
|
6016
6775
|
dispatch({
|
|
6017
6776
|
type: "SET_HYPOTHESES",
|
|
6018
6777
|
hypotheses: hypotheses.map((h) => {
|
|
6019
|
-
const base = { id: h.id, statement: h.statement, confidence: h.confidence, status: h.status, evidenceCount: h.evidence.length, updatedAt: h.updatedAt };
|
|
6020
|
-
return
|
|
6778
|
+
const base = { id: h.id, statement: h.statement, confidence: h.confidence, status: h.status, evidenceCount: h.evidence.length, updatedAt: h.updatedAt, ...h.category != null ? { category: h.category } : {} };
|
|
6779
|
+
return base;
|
|
6021
6780
|
})
|
|
6022
6781
|
});
|
|
6023
6782
|
}
|
|
@@ -6049,8 +6808,10 @@ ${contextBlock}`;
|
|
|
6049
6808
|
useEffect3(() => {
|
|
6050
6809
|
if (!loading && messageQueue.length > 0 && !loadingRef.current) {
|
|
6051
6810
|
const msg = messageQueue[0];
|
|
6052
|
-
|
|
6053
|
-
|
|
6811
|
+
if (msg) {
|
|
6812
|
+
dispatch({ type: "DEQUEUE_CHAT_MESSAGE" });
|
|
6813
|
+
void sendMessage(msg);
|
|
6814
|
+
}
|
|
6054
6815
|
}
|
|
6055
6816
|
}, [loading, messageQueue.length, dispatch, sendMessage]);
|
|
6056
6817
|
useInput8((input, key) => {
|
|
@@ -6104,7 +6865,7 @@ ${contextBlock}`;
|
|
|
6104
6865
|
const canScrollUp = scrollOffset < messages.length - VISIBLE_MESSAGES;
|
|
6105
6866
|
const canScrollDown = scrollOffset > 0;
|
|
6106
6867
|
const cursor = cursorVisible ? "|" : " ";
|
|
6107
|
-
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1,
|
|
6868
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, height: "100%", minHeight: 0, children: [
|
|
6108
6869
|
/* @__PURE__ */ jsx13(Box12, { flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { children: [
|
|
6109
6870
|
/* @__PURE__ */ jsx13(Text12, { bold: true, children: "Chat" }),
|
|
6110
6871
|
currentSessionTitle && /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
@@ -6124,10 +6885,10 @@ ${contextBlock}`;
|
|
|
6124
6885
|
"]"
|
|
6125
6886
|
] })
|
|
6126
6887
|
] }) }),
|
|
6127
|
-
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", flexGrow: 1, flexShrink: 1,
|
|
6888
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", flexGrow: 1, flexShrink: 1, height: "100%", minHeight: 0, marginTop: 1, marginBottom: 1, children: [
|
|
6128
6889
|
messages.length === 0 && !loading && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " Ask about your codebase, decisions, patterns, or risks." }),
|
|
6129
6890
|
canScrollUp && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " \u2191 more messages above" }),
|
|
6130
|
-
visibleMessages.map((msg, idx) => /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", marginTop: idx === 0 ? 0 : 1, children: msg.role === "user" ? /* @__PURE__ */ jsxs12(Text12, { children: [
|
|
6891
|
+
visibleMessages.map((msg, idx) => /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", marginTop: idx === 0 ? 0 : 1, children: msg.role === "user" ? /* @__PURE__ */ jsxs12(Text12, { wrap: "wrap", children: [
|
|
6131
6892
|
" ",
|
|
6132
6893
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: "green", children: "You:" }),
|
|
6133
6894
|
" ",
|
|
@@ -6143,7 +6904,7 @@ ${contextBlock}`;
|
|
|
6143
6904
|
" ",
|
|
6144
6905
|
formatToolInput(tc.input)
|
|
6145
6906
|
] }, ti)),
|
|
6146
|
-
msg.content.split("\n").map((line, li) => /* @__PURE__ */ jsxs12(Text12, { children: [
|
|
6907
|
+
msg.content.split("\n").map((line, li) => /* @__PURE__ */ jsxs12(Text12, { wrap: "wrap", children: [
|
|
6147
6908
|
li === 0 ? " Trie: " : " ",
|
|
6148
6909
|
line
|
|
6149
6910
|
] }, li))
|
|
@@ -6155,10 +6916,10 @@ ${contextBlock}`;
|
|
|
6155
6916
|
/* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " (Esc to cancel)" })
|
|
6156
6917
|
] })
|
|
6157
6918
|
] }),
|
|
6158
|
-
/* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: "green", paddingX: 1, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */ jsx13(Text12, { children: inputBuffer ? /* @__PURE__ */ jsxs12(
|
|
6919
|
+
/* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: "green", paddingX: 1, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */ jsx13(Text12, { children: inputBuffer ? /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
6159
6920
|
inputBuffer,
|
|
6160
6921
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: "green", children: cursor })
|
|
6161
|
-
] }) : /* @__PURE__ */ jsxs12(
|
|
6922
|
+
] }) : /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
6162
6923
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: "green", children: cursor }),
|
|
6163
6924
|
/* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Ask a question..." })
|
|
6164
6925
|
] }) }) })
|
|
@@ -6185,7 +6946,7 @@ function formatToolInput(input) {
|
|
|
6185
6946
|
|
|
6186
6947
|
// src/cli/dashboard/views/ChatArchiveView.tsx
|
|
6187
6948
|
import { useEffect as useEffect4, useCallback as useCallback6 } from "react";
|
|
6188
|
-
import { Box as Box13, Text as Text13, useInput as useInput9 } from "ink";
|
|
6949
|
+
import { Box as Box13, Text as Text13, useInput as useInput9, useStdout as useStdout10 } from "ink";
|
|
6189
6950
|
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
6190
6951
|
function formatTimeAgo2(timestamp) {
|
|
6191
6952
|
const seconds = Math.floor((Date.now() - timestamp) / 1e3);
|
|
@@ -6300,7 +7061,12 @@ function ChatArchiveView() {
|
|
|
6300
7061
|
dispatch({ type: "SHOW_NOTIFICATION", message: `Failed to export: ${error instanceof Error ? error.message : "unknown"}`, severity: "warning", autoHideMs: 3e3 });
|
|
6301
7062
|
}
|
|
6302
7063
|
}, [sessions, selectedIndex, dispatch]);
|
|
7064
|
+
const { stdout } = useStdout10();
|
|
7065
|
+
const cols = stdout?.columns || 80;
|
|
7066
|
+
const narrow = cols < 60;
|
|
7067
|
+
const contentWidth = Math.max(20, cols - 4);
|
|
6303
7068
|
useInput9((input, key) => {
|
|
7069
|
+
if (input === "q" || input === "Q") return;
|
|
6304
7070
|
if (inputMode === "rename") {
|
|
6305
7071
|
if (key.return) {
|
|
6306
7072
|
void renameSession(inputBuffer);
|
|
@@ -6379,11 +7145,12 @@ function ChatArchiveView() {
|
|
|
6379
7145
|
/* @__PURE__ */ jsx14(Box13, { flexDirection: "column", marginTop: 1, children: sessions.map((session, idx) => {
|
|
6380
7146
|
const isSelected = idx === selectedIndex;
|
|
6381
7147
|
const ago = formatTimeAgo2(session.updatedAt);
|
|
6382
|
-
const
|
|
6383
|
-
|
|
7148
|
+
const titleWidth = Math.max(30, contentWidth - 20);
|
|
7149
|
+
const titleDisplay = session.title.length > titleWidth ? session.title.slice(0, titleWidth) + "..." : session.title;
|
|
7150
|
+
return /* @__PURE__ */ jsx14(Box13, { flexDirection: "column", children: /* @__PURE__ */ jsxs13(Text13, { wrap: "truncate", children: [
|
|
6384
7151
|
isSelected ? /* @__PURE__ */ jsx14(Text13, { bold: true, color: "green", children: "> " }) : " ",
|
|
6385
7152
|
isSelected ? /* @__PURE__ */ jsx14(Text13, { bold: true, children: titleDisplay }) : /* @__PURE__ */ jsx14(Text13, { children: titleDisplay }),
|
|
6386
|
-
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
7153
|
+
narrow ? null : /* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
6387
7154
|
" ",
|
|
6388
7155
|
session.messageCount,
|
|
6389
7156
|
" msgs \xB7 ",
|
|
@@ -6399,7 +7166,7 @@ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
|
6399
7166
|
var MAIN_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
6400
7167
|
async function applyGoalFix(fix, dispatch) {
|
|
6401
7168
|
try {
|
|
6402
|
-
const { runAIAnalysis, isAIAvailable: isAIAvailable2 } = await import("./client-
|
|
7169
|
+
const { runAIAnalysis, isAIAvailable: isAIAvailable2 } = await import("./client-JTU5TRLB.js");
|
|
6403
7170
|
if (!isAIAvailable2()) {
|
|
6404
7171
|
dispatch({ type: "DISMISS_FIX", id: fix.id });
|
|
6405
7172
|
getOutputManager().nudge("AI not available for fix", "warning");
|
|
@@ -6434,7 +7201,7 @@ ${content}
|
|
|
6434
7201
|
fixedContent = fixedContent.replace(/^```\w*\n?/, "").replace(/\n?```$/, "");
|
|
6435
7202
|
}
|
|
6436
7203
|
await writeFile(fullPath, fixedContent, "utf-8");
|
|
6437
|
-
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-
|
|
7204
|
+
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-GISXYANK.js");
|
|
6438
7205
|
const goals = await getActiveGoals(projectPath);
|
|
6439
7206
|
const matchedGoal = goals.find((g) => g.description === fix.goalDescription);
|
|
6440
7207
|
if (matchedGoal) {
|
|
@@ -6450,6 +7217,7 @@ ${content}
|
|
|
6450
7217
|
function DashboardApp({ onReady }) {
|
|
6451
7218
|
const { state, dispatch } = useDashboard();
|
|
6452
7219
|
const { exit } = useApp();
|
|
7220
|
+
const { stdout } = useStdout11();
|
|
6453
7221
|
const [showConfig, setShowConfig] = useState3(false);
|
|
6454
7222
|
const [showHelp, setShowHelp] = useState3(false);
|
|
6455
7223
|
const dispatchRef = useRef2(dispatch);
|
|
@@ -6471,7 +7239,7 @@ function DashboardApp({ onReady }) {
|
|
|
6471
7239
|
const workDir = getWorkingDirectory(void 0, true);
|
|
6472
7240
|
await mkdir(getTrieDirectory(workDir), { recursive: true });
|
|
6473
7241
|
await writeFile(configPath, JSON.stringify(stateRef.current.agentConfig, null, 2), "utf-8");
|
|
6474
|
-
const { saveAutonomyConfig, loadAutonomyConfig } = await import("./autonomy-config-
|
|
7242
|
+
const { saveAutonomyConfig, loadAutonomyConfig } = await import("./autonomy-config-TZ6HF4FA.js");
|
|
6475
7243
|
const autonomy = await loadAutonomyConfig(workDir);
|
|
6476
7244
|
autonomy.aiWatcher = stateRef.current.agentConfig.aiWatcher;
|
|
6477
7245
|
await saveAutonomyConfig(workDir, autonomy);
|
|
@@ -6481,7 +7249,7 @@ function DashboardApp({ onReady }) {
|
|
|
6481
7249
|
const processInsights = useCallback7(async (issues) => {
|
|
6482
7250
|
try {
|
|
6483
7251
|
const workDir = getWorkingDirectory(void 0, true);
|
|
6484
|
-
const trieAgent =
|
|
7252
|
+
const trieAgent = getTrieAgent(workDir);
|
|
6485
7253
|
if (!stateRef.current.agentInitialized) {
|
|
6486
7254
|
await trieAgent.initialize();
|
|
6487
7255
|
dispatchRef.current({ type: "SET_AGENT_INITIALIZED", initialized: true });
|
|
@@ -6507,14 +7275,14 @@ function DashboardApp({ onReady }) {
|
|
|
6507
7275
|
const refreshGoals = useCallback7(async () => {
|
|
6508
7276
|
try {
|
|
6509
7277
|
const workDir = getWorkingDirectory(void 0, true);
|
|
6510
|
-
const agentState =
|
|
7278
|
+
const agentState = getProjectState(workDir);
|
|
6511
7279
|
await agentState.load();
|
|
6512
7280
|
const goals = agentState.getAllGoals();
|
|
6513
7281
|
dispatchRef.current({
|
|
6514
7282
|
type: "SET_GOALS",
|
|
6515
7283
|
goals: goals.map((g) => {
|
|
6516
|
-
const base = { id: g.id, description: g.description, type: g.type, target: g.target, currentValue: g.currentValue, status: g.status, autoGenerated: g.autoGenerated, updatedAt: g.updatedAt };
|
|
6517
|
-
return
|
|
7284
|
+
const base = { id: g.id, description: g.description, type: g.type, target: g.target, currentValue: g.currentValue, status: g.status, autoGenerated: g.autoGenerated, updatedAt: g.updatedAt, ...g.achievedAt != null ? { achievedAt: g.achievedAt } : {}, ...g.achievedBy != null ? { achievedBy: g.achievedBy } : {}, ...g.category != null ? { category: g.category } : {} };
|
|
7285
|
+
return base;
|
|
6518
7286
|
})
|
|
6519
7287
|
});
|
|
6520
7288
|
} catch {
|
|
@@ -6523,14 +7291,14 @@ function DashboardApp({ onReady }) {
|
|
|
6523
7291
|
const refreshHypotheses = useCallback7(async () => {
|
|
6524
7292
|
try {
|
|
6525
7293
|
const workDir = getWorkingDirectory(void 0, true);
|
|
6526
|
-
const agentState =
|
|
7294
|
+
const agentState = getProjectState(workDir);
|
|
6527
7295
|
await agentState.load();
|
|
6528
7296
|
const hypotheses = agentState.getAllHypotheses();
|
|
6529
7297
|
dispatchRef.current({
|
|
6530
7298
|
type: "SET_HYPOTHESES",
|
|
6531
7299
|
hypotheses: hypotheses.map((h) => {
|
|
6532
|
-
const base = { id: h.id, statement: h.statement, confidence: h.confidence, status: h.status, evidenceCount: h.evidence.length, updatedAt: h.updatedAt };
|
|
6533
|
-
return
|
|
7300
|
+
const base = { id: h.id, statement: h.statement, confidence: h.confidence, status: h.status, evidenceCount: h.evidence.length, updatedAt: h.updatedAt, ...h.autoGenerated != null ? { autoGenerated: h.autoGenerated } : {}, ...h.validatedBy != null ? { validatedBy: h.validatedBy } : {}, ...h.category != null ? { category: h.category } : {} };
|
|
7301
|
+
return base;
|
|
6534
7302
|
})
|
|
6535
7303
|
});
|
|
6536
7304
|
} catch {
|
|
@@ -6539,7 +7307,7 @@ function DashboardApp({ onReady }) {
|
|
|
6539
7307
|
const loadPersistedNudges = useCallback7(async () => {
|
|
6540
7308
|
try {
|
|
6541
7309
|
const workDir = getWorkingDirectory(void 0, true);
|
|
6542
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
7310
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-VZL7KK64.js");
|
|
6543
7311
|
const storage = getStorage2(workDir);
|
|
6544
7312
|
await storage.initialize();
|
|
6545
7313
|
const nudges = await storage.queryNudges({ resolved: false, limit: 50 });
|
|
@@ -6659,9 +7427,18 @@ function DashboardApp({ onReady }) {
|
|
|
6659
7427
|
}
|
|
6660
7428
|
}, [state.pendingFixes]);
|
|
6661
7429
|
useInput10((input, key) => {
|
|
7430
|
+
const inAddMode = state.view === "goals" && state.goalsPanel.inputMode === "add" || state.view === "hypotheses" && state.hypothesesPanel.inputMode === "add";
|
|
7431
|
+
const inChat = state.view === "chat";
|
|
7432
|
+
if (!inAddMode && !inChat && (input === "q" || input === "Q" || key.escape)) {
|
|
7433
|
+
exit();
|
|
7434
|
+
return;
|
|
7435
|
+
}
|
|
7436
|
+
if (inChat && !key.escape && (input === "q" || input === "Q")) {
|
|
7437
|
+
exit();
|
|
7438
|
+
return;
|
|
7439
|
+
}
|
|
6662
7440
|
if (showConfig) return;
|
|
6663
|
-
if (
|
|
6664
|
-
if (state.view === "hypotheses" && state.hypothesesPanel.inputMode === "add") return;
|
|
7441
|
+
if (inAddMode) return;
|
|
6665
7442
|
if ((input === "/" || input === "?") && state.view !== "chat") {
|
|
6666
7443
|
setShowHelp(!showHelp);
|
|
6667
7444
|
return;
|
|
@@ -6675,20 +7452,17 @@ function DashboardApp({ onReady }) {
|
|
|
6675
7452
|
const currentIndex = MAIN_VIEWS.indexOf(state.view);
|
|
6676
7453
|
const nextIndex = (currentIndex + 1) % MAIN_VIEWS.length;
|
|
6677
7454
|
dispatch({ type: "SET_VIEW", view: MAIN_VIEWS[nextIndex] || "overview" });
|
|
7455
|
+
return;
|
|
6678
7456
|
}
|
|
6679
7457
|
return;
|
|
6680
7458
|
}
|
|
6681
|
-
if (input === "q" || key.escape) {
|
|
6682
|
-
exit();
|
|
6683
|
-
return;
|
|
6684
|
-
}
|
|
6685
7459
|
if (key.tab) {
|
|
6686
7460
|
const currentIndex = MAIN_VIEWS.indexOf(state.view);
|
|
6687
7461
|
const nextIndex = currentIndex >= 0 ? (currentIndex + 1) % MAIN_VIEWS.length : 0;
|
|
6688
7462
|
dispatch({ type: "SET_VIEW", view: MAIN_VIEWS[nextIndex] || "overview" });
|
|
6689
7463
|
return;
|
|
6690
7464
|
}
|
|
6691
|
-
if (state.view === "goals" || state.view === "hypotheses" || state.view === "chat-archive") {
|
|
7465
|
+
if (state.view === "goals" || state.view === "hypotheses" || state.view === "chat-archive" || state.view === "memory" || state.view === "agent") {
|
|
6692
7466
|
return;
|
|
6693
7467
|
}
|
|
6694
7468
|
if (input === "s") {
|
|
@@ -6721,7 +7495,6 @@ function DashboardApp({ onReady }) {
|
|
|
6721
7495
|
dispatch({ type: "SET_VIEW", view: "chat" });
|
|
6722
7496
|
return;
|
|
6723
7497
|
}
|
|
6724
|
-
if (state.view === "agent" || state.view === "memory") return;
|
|
6725
7498
|
if (input === "b") dispatch({ type: "GO_BACK" });
|
|
6726
7499
|
if (input === "n") dispatch({ type: "NEXT_PAGE" });
|
|
6727
7500
|
if (input === "p") dispatch({ type: "PREV_PAGE" });
|
|
@@ -6755,10 +7528,11 @@ function DashboardApp({ onReady }) {
|
|
|
6755
7528
|
default:
|
|
6756
7529
|
viewComponent = /* @__PURE__ */ jsx15(OverviewView, {});
|
|
6757
7530
|
}
|
|
6758
|
-
|
|
7531
|
+
const terminalHeight = stdout?.rows || process.stdout.rows || 40;
|
|
7532
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", minHeight: terminalHeight, children: [
|
|
6759
7533
|
/* @__PURE__ */ jsx15(Header, {}),
|
|
6760
7534
|
!showConfig && !showHelp && /* @__PURE__ */ jsx15(Notification, {}),
|
|
6761
|
-
/* @__PURE__ */ jsx15(Box14, { flexGrow: 1, flexDirection: "column",
|
|
7535
|
+
/* @__PURE__ */ jsx15(Box14, { flexGrow: 1, flexDirection: "column", children: showConfig ? /* @__PURE__ */ jsx15(ConfigDialog, { onClose: () => {
|
|
6762
7536
|
setShowConfig(false);
|
|
6763
7537
|
void persistConfig();
|
|
6764
7538
|
} }) : showHelp ? /* @__PURE__ */ jsx15(HelpDialog, { view: state.view, onClose: () => setShowHelp(false) }) : viewComponent }),
|
|
@@ -6814,11 +7588,13 @@ export {
|
|
|
6814
7588
|
TrieTellTool,
|
|
6815
7589
|
TrieFeedbackTool,
|
|
6816
7590
|
TrieCheckTool,
|
|
7591
|
+
TrieGetGovernanceTool,
|
|
6817
7592
|
TrieGetDecisionsTool,
|
|
6818
7593
|
TrieGetBlockersTool,
|
|
7594
|
+
TrieGetRelatedGovernanceTool,
|
|
6819
7595
|
TrieGetRelatedDecisionsTool,
|
|
6820
7596
|
TrieQueryContextTool,
|
|
6821
7597
|
handleCheckpointTool,
|
|
6822
7598
|
InteractiveDashboard
|
|
6823
7599
|
};
|
|
6824
|
-
//# sourceMappingURL=chunk-
|
|
7600
|
+
//# sourceMappingURL=chunk-X3F5QDER.js.map
|