@triedotdev/mcp 1.0.115 → 1.0.117
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{autonomy-config-JXB7WCZ2.js → autonomy-config-QA6ATWLJ.js} +3 -3
- package/dist/{chunk-R4AAPFXC.js → chunk-45Y5TLQZ.js} +2 -2
- package/dist/{chunk-R4AAPFXC.js.map → chunk-45Y5TLQZ.js.map} +1 -1
- package/dist/{chunk-KRH642MT.js → chunk-4BGAVEO6.js} +2 -2
- package/dist/{chunk-NS2MSZMB.js → chunk-55CBWOEZ.js} +2 -2
- package/dist/{chunk-YR4BMGYO.js → chunk-7Q6I2CB4.js} +2 -2
- package/dist/{chunk-TKMV7JKN.js → chunk-DFHMB44X.js} +2 -2
- package/dist/{chunk-ZYKEILVK.js → chunk-EWVU7QUG.js} +464 -88
- package/dist/chunk-EWVU7QUG.js.map +1 -0
- package/dist/{chunk-D3EXBJE2.js → chunk-FNW7Z7ZS.js} +5 -5
- package/dist/{chunk-DZREHOGW.js → chunk-I7XKF5XD.js} +5 -5
- package/dist/{chunk-2SIFK7OW.js → chunk-IQBHPTV7.js} +4 -4
- package/dist/{chunk-AOFYU6T3.js → chunk-OMCEUJ5I.js} +12 -12
- package/dist/{chunk-MVNJPJBK.js → chunk-PPZYVTUO.js} +71 -5
- package/dist/{chunk-MVNJPJBK.js.map → chunk-PPZYVTUO.js.map} +1 -1
- package/dist/{chunk-55DOQNHJ.js → chunk-PRFHN2X6.js} +4 -4
- package/dist/{chunk-2GIAROBF.js → chunk-WHIQAGB7.js} +2 -2
- package/dist/{chunk-SWSK7ANT.js → chunk-WRGSH5RT.js} +2 -2
- package/dist/{chunk-6LXSA2OZ.js → chunk-Y52SNUW5.js} +3 -3
- package/dist/{chunk-I2GFI3AM.js → chunk-ZEXMMTIQ.js} +2 -2
- package/dist/cli/create-agent.js +1 -1
- package/dist/cli/main.js +66 -32
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +14 -14
- package/dist/{client-7XZHCMD3.js → client-PMKE26IV.js} +3 -3
- package/dist/{goal-manager-LMS6ZJB7.js → goal-manager-JKTNFJQE.js} +7 -7
- package/dist/goal-validator-YSNN23D4.js +62 -0
- package/dist/goal-validator-YSNN23D4.js.map +1 -0
- package/dist/{graph-U5JWSAB5.js → graph-PAUZ5EMP.js} +3 -3
- package/dist/guardian-agent-UY2G56FT.js +25 -0
- package/dist/{hypothesis-KGC3P54C.js → hypothesis-RUCJ74X7.js} +7 -7
- package/dist/{incident-index-PNIVT47T.js → incident-index-ZCDSJ42L.js} +3 -3
- package/dist/index.js +215 -128
- package/dist/index.js.map +1 -1
- package/dist/{ledger-SR6OEBLO.js → ledger-JMPGJGLB.js} +3 -3
- package/package.json +1 -1
- package/dist/auto-fix-apply-PCAHWLXF.js +0 -10
- package/dist/chunk-DJ2YAGHK.js +0 -50
- package/dist/chunk-DJ2YAGHK.js.map +0 -1
- package/dist/chunk-ZYKEILVK.js.map +0 -1
- package/dist/goal-validator-T5HEYBC5.js +0 -186
- package/dist/goal-validator-T5HEYBC5.js.map +0 -1
- package/dist/guardian-agent-EXP7APLC.js +0 -25
- package/dist/ledger-SR6OEBLO.js.map +0 -1
- /package/dist/{auto-fix-apply-PCAHWLXF.js.map → autonomy-config-QA6ATWLJ.js.map} +0 -0
- /package/dist/{chunk-KRH642MT.js.map → chunk-4BGAVEO6.js.map} +0 -0
- /package/dist/{chunk-NS2MSZMB.js.map → chunk-55CBWOEZ.js.map} +0 -0
- /package/dist/{chunk-YR4BMGYO.js.map → chunk-7Q6I2CB4.js.map} +0 -0
- /package/dist/{chunk-TKMV7JKN.js.map → chunk-DFHMB44X.js.map} +0 -0
- /package/dist/{chunk-D3EXBJE2.js.map → chunk-FNW7Z7ZS.js.map} +0 -0
- /package/dist/{chunk-DZREHOGW.js.map → chunk-I7XKF5XD.js.map} +0 -0
- /package/dist/{chunk-2SIFK7OW.js.map → chunk-IQBHPTV7.js.map} +0 -0
- /package/dist/{chunk-AOFYU6T3.js.map → chunk-OMCEUJ5I.js.map} +0 -0
- /package/dist/{chunk-55DOQNHJ.js.map → chunk-PRFHN2X6.js.map} +0 -0
- /package/dist/{chunk-2GIAROBF.js.map → chunk-WHIQAGB7.js.map} +0 -0
- /package/dist/{chunk-SWSK7ANT.js.map → chunk-WRGSH5RT.js.map} +0 -0
- /package/dist/{chunk-6LXSA2OZ.js.map → chunk-Y52SNUW5.js.map} +0 -0
- /package/dist/{chunk-I2GFI3AM.js.map → chunk-ZEXMMTIQ.js.map} +0 -0
- /package/dist/{autonomy-config-JXB7WCZ2.js.map → client-PMKE26IV.js.map} +0 -0
- /package/dist/{client-7XZHCMD3.js.map → goal-manager-JKTNFJQE.js.map} +0 -0
- /package/dist/{goal-manager-LMS6ZJB7.js.map → graph-PAUZ5EMP.js.map} +0 -0
- /package/dist/{graph-U5JWSAB5.js.map → guardian-agent-UY2G56FT.js.map} +0 -0
- /package/dist/{guardian-agent-EXP7APLC.js.map → hypothesis-RUCJ74X7.js.map} +0 -0
- /package/dist/{hypothesis-KGC3P54C.js.map → incident-index-ZCDSJ42L.js.map} +0 -0
- /package/dist/{incident-index-PNIVT47T.js.map → ledger-JMPGJGLB.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGuardian
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OMCEUJ5I.js";
|
|
4
4
|
import {
|
|
5
5
|
LearningEngine,
|
|
6
6
|
exportToJson,
|
|
@@ -10,34 +10,34 @@ import {
|
|
|
10
10
|
perceiveCurrentChanges,
|
|
11
11
|
reasonAboutChangesHumanReadable,
|
|
12
12
|
saveCheckpoint
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PPZYVTUO.js";
|
|
14
14
|
import {
|
|
15
15
|
TieredStorage,
|
|
16
16
|
findCrossProjectPatterns,
|
|
17
17
|
getStorage
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-FNW7Z7ZS.js";
|
|
19
19
|
import {
|
|
20
20
|
getKeyFromKeychain,
|
|
21
21
|
isAIAvailable,
|
|
22
22
|
runAIWithTools,
|
|
23
23
|
setAPIKey
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-WRGSH5RT.js";
|
|
25
25
|
import {
|
|
26
26
|
getGuardianState
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-4BGAVEO6.js";
|
|
28
28
|
import {
|
|
29
29
|
ContextGraph
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-55CBWOEZ.js";
|
|
31
31
|
import {
|
|
32
32
|
IncidentIndex
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-WHIQAGB7.js";
|
|
34
34
|
import {
|
|
35
35
|
getOutputManager
|
|
36
36
|
} from "./chunk-VRLMTOB6.js";
|
|
37
37
|
import {
|
|
38
38
|
getTrieDirectory,
|
|
39
39
|
getWorkingDirectory
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-45Y5TLQZ.js";
|
|
41
41
|
import {
|
|
42
42
|
isInteractiveMode
|
|
43
43
|
} from "./chunk-APMV77PU.js";
|
|
@@ -45,10 +45,14 @@ import {
|
|
|
45
45
|
// src/tools/scan.ts
|
|
46
46
|
var TrieScanTool = class {
|
|
47
47
|
async execute(_input) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
if (!isInteractiveMode()) {
|
|
49
|
+
console.error("Trie scan has been refocused on decision ledger");
|
|
50
|
+
console.error(" trie tell - report incidents");
|
|
51
|
+
console.error(" trie gotcha - predict risks");
|
|
52
|
+
console.error(" trie learn - learn from history");
|
|
53
|
+
} else {
|
|
54
|
+
getOutputManager().log("info", "Scan refocused on decision ledger");
|
|
55
|
+
}
|
|
52
56
|
return {
|
|
53
57
|
content: [{
|
|
54
58
|
type: "text",
|
|
@@ -217,6 +221,12 @@ var StreamingManager = class {
|
|
|
217
221
|
reportWatchChange(file) {
|
|
218
222
|
this.emit("watch_change", { file });
|
|
219
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Report a pending fix for user approval
|
|
226
|
+
*/
|
|
227
|
+
reportPendingFix(fix) {
|
|
228
|
+
this.emit("pending_fix", fix);
|
|
229
|
+
}
|
|
220
230
|
/**
|
|
221
231
|
* Report memory operations (saving context, learning patterns)
|
|
222
232
|
*/
|
|
@@ -282,7 +292,7 @@ import React9 from "react";
|
|
|
282
292
|
|
|
283
293
|
// src/cli/dashboard/App.tsx
|
|
284
294
|
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback6, useRef as useRef2 } from "react";
|
|
285
|
-
import { Box as Box12, useInput as
|
|
295
|
+
import { Box as Box12, useInput as useInput9, useApp } from "ink";
|
|
286
296
|
|
|
287
297
|
// src/cli/dashboard/state.tsx
|
|
288
298
|
import React, { createContext, useContext, useReducer } from "react";
|
|
@@ -402,7 +412,8 @@ function handleStreamUpdate(state, update) {
|
|
|
402
412
|
lastChange: entry.time,
|
|
403
413
|
filesScannedSession: s.watch.filesScannedSession + 1
|
|
404
414
|
};
|
|
405
|
-
|
|
415
|
+
const shortFile = update.data.file.split("/").slice(-2).join("/");
|
|
416
|
+
s = addActivity(s, `Change: ${shortFile}`);
|
|
406
417
|
break;
|
|
407
418
|
}
|
|
408
419
|
case "signal_extracted": {
|
|
@@ -430,6 +441,20 @@ function handleStreamUpdate(state, update) {
|
|
|
430
441
|
message: update.data.message
|
|
431
442
|
}, ...s.rawLog].slice(0, 500);
|
|
432
443
|
break;
|
|
444
|
+
case "pending_fix":
|
|
445
|
+
s.pendingFixes = [{
|
|
446
|
+
id: update.data.id,
|
|
447
|
+
file: update.data.file,
|
|
448
|
+
description: update.data.description,
|
|
449
|
+
goalDescription: update.data.goalDescription,
|
|
450
|
+
confidence: update.data.confidence,
|
|
451
|
+
severity: update.data.severity,
|
|
452
|
+
suggestedFix: update.data.suggestedFix,
|
|
453
|
+
timestamp: update.timestamp,
|
|
454
|
+
status: "pending"
|
|
455
|
+
}, ...s.pendingFixes].slice(0, 20);
|
|
456
|
+
s = addActivity(s, `Goal violation: ${update.data.description} [${update.data.confidence}%]`);
|
|
457
|
+
break;
|
|
433
458
|
}
|
|
434
459
|
return s;
|
|
435
460
|
}
|
|
@@ -687,6 +712,34 @@ function dashboardReducer(state, action) {
|
|
|
687
712
|
if (!changed) return state;
|
|
688
713
|
return { ...state, notificationHistory: history };
|
|
689
714
|
}
|
|
715
|
+
case "ADD_PENDING_FIX":
|
|
716
|
+
return {
|
|
717
|
+
...state,
|
|
718
|
+
pendingFixes: [action.fix, ...state.pendingFixes].slice(0, 20)
|
|
719
|
+
};
|
|
720
|
+
case "APPROVE_FIX":
|
|
721
|
+
return {
|
|
722
|
+
...state,
|
|
723
|
+
pendingFixes: state.pendingFixes.map(
|
|
724
|
+
(f) => f.id === action.id ? { ...f, status: "applying" } : f
|
|
725
|
+
)
|
|
726
|
+
};
|
|
727
|
+
case "DISMISS_FIX":
|
|
728
|
+
return {
|
|
729
|
+
...state,
|
|
730
|
+
pendingFixes: state.pendingFixes.map(
|
|
731
|
+
(f) => f.id === action.id ? { ...f, status: "dismissed" } : f
|
|
732
|
+
)
|
|
733
|
+
};
|
|
734
|
+
case "FIX_APPLIED":
|
|
735
|
+
return {
|
|
736
|
+
...state,
|
|
737
|
+
pendingFixes: state.pendingFixes.map(
|
|
738
|
+
(f) => f.id === action.id ? { ...f, status: "applied" } : f
|
|
739
|
+
)
|
|
740
|
+
};
|
|
741
|
+
case "SELECT_FIX":
|
|
742
|
+
return { ...state, selectedFixIndex: action.index };
|
|
690
743
|
default:
|
|
691
744
|
return state;
|
|
692
745
|
}
|
|
@@ -746,7 +799,9 @@ function createInitialState() {
|
|
|
746
799
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
747
800
|
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
748
801
|
agentBrain: { loaded: false, decisions: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
|
|
749
|
-
chatState: { messages: [], inputBuffer: "", loading: false }
|
|
802
|
+
chatState: { messages: [], inputBuffer: "", loading: false },
|
|
803
|
+
pendingFixes: [],
|
|
804
|
+
selectedFixIndex: 0
|
|
750
805
|
};
|
|
751
806
|
}
|
|
752
807
|
var DashboardContext = createContext(null);
|
|
@@ -767,45 +822,50 @@ import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
|
767
822
|
import { join as join2 } from "path";
|
|
768
823
|
|
|
769
824
|
// src/cli/dashboard/components/Header.tsx
|
|
770
|
-
import { Box, Text } from "ink";
|
|
825
|
+
import { Box, Text, useStdout } from "ink";
|
|
771
826
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
772
827
|
function Header() {
|
|
773
828
|
const { state } = useDashboard();
|
|
774
829
|
const { signalExtraction, watch, alerts } = state;
|
|
830
|
+
const { stdout } = useStdout();
|
|
831
|
+
const cols = stdout?.columns || 80;
|
|
832
|
+
const narrow = cols < 50;
|
|
775
833
|
const totalExtracted = signalExtraction.decisionsExtracted + signalExtraction.factsExtracted + signalExtraction.blockersExtracted + signalExtraction.questionsExtracted;
|
|
776
834
|
let status;
|
|
777
835
|
if (watch.watching) {
|
|
778
836
|
status = totalExtracted > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
779
837
|
/* @__PURE__ */ jsx2(Text, { color: "green", children: "\u25CF" }),
|
|
780
|
-
" ",
|
|
781
|
-
/* @__PURE__ */ jsx2(Text, { color: "green", children: "Learning" }),
|
|
782
|
-
|
|
783
|
-
|
|
838
|
+
narrow ? "" : " ",
|
|
839
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", children: narrow ? "" : "Learning" }),
|
|
840
|
+
!narrow && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
841
|
+
" ",
|
|
784
842
|
totalExtracted,
|
|
785
843
|
" signals"
|
|
786
844
|
] })
|
|
787
845
|
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
788
846
|
/* @__PURE__ */ jsx2(Text, { color: "green", children: "\u25CF" }),
|
|
789
|
-
" Watching"
|
|
847
|
+
!narrow && " Watching"
|
|
790
848
|
] });
|
|
791
849
|
} else {
|
|
792
850
|
status = /* @__PURE__ */ jsxs(Text, { children: [
|
|
793
851
|
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "\u25CB" }),
|
|
794
|
-
" "
|
|
795
|
-
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "Idle" })
|
|
852
|
+
!narrow && /* @__PURE__ */ jsx2(Text, { dimColor: true, children: " Idle" })
|
|
796
853
|
] });
|
|
797
854
|
}
|
|
798
855
|
return /* @__PURE__ */ jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [
|
|
799
|
-
/* @__PURE__ */ jsx2(Text, { bold: true, children: "Trie" }),
|
|
800
|
-
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
856
|
+
/* @__PURE__ */ jsx2(Text, { bold: true, color: "magenta", children: "Trie" }),
|
|
857
|
+
/* @__PURE__ */ jsxs(Box, { gap: narrow ? 1 : 2, children: [
|
|
801
858
|
status,
|
|
802
|
-
alerts.hasCritical && /* @__PURE__ */
|
|
859
|
+
alerts.hasCritical && /* @__PURE__ */ jsxs(Text, { color: "red", bold: true, children: [
|
|
860
|
+
"\u25CF",
|
|
861
|
+
!narrow && " Alert"
|
|
862
|
+
] })
|
|
803
863
|
] })
|
|
804
864
|
] });
|
|
805
865
|
}
|
|
806
866
|
|
|
807
867
|
// src/cli/dashboard/components/Footer.tsx
|
|
808
|
-
import { Box as Box2, Text as Text2 } from "ink";
|
|
868
|
+
import { Box as Box2, Text as Text2, useStdout as useStdout2 } from "ink";
|
|
809
869
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
810
870
|
var VIEW_LABELS = {
|
|
811
871
|
overview: "Overview",
|
|
@@ -816,6 +876,15 @@ var VIEW_LABELS = {
|
|
|
816
876
|
memory: "Ledger",
|
|
817
877
|
chat: "Chat"
|
|
818
878
|
};
|
|
879
|
+
var VIEW_SHORT = {
|
|
880
|
+
overview: "Ovr",
|
|
881
|
+
rawlog: "Log",
|
|
882
|
+
agent: "Ndg",
|
|
883
|
+
goals: "Gls",
|
|
884
|
+
hypotheses: "Hyp",
|
|
885
|
+
memory: "Ldg",
|
|
886
|
+
chat: "Cht"
|
|
887
|
+
};
|
|
819
888
|
var TAB_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
820
889
|
var CONTEXT_HINTS = {
|
|
821
890
|
goals: "j/k nav \xB7 a add \xB7 enter complete \xB7 d delete",
|
|
@@ -825,14 +894,42 @@ var CONTEXT_HINTS = {
|
|
|
825
894
|
chat: "type to ask \xB7 enter send \xB7 esc clear",
|
|
826
895
|
rawlog: "n/p pages \xB7 b back"
|
|
827
896
|
};
|
|
897
|
+
var CONTEXT_HINTS_SHORT = {
|
|
898
|
+
goals: "j/k a d",
|
|
899
|
+
hypotheses: "j/k a v x",
|
|
900
|
+
agent: "j/k enter d",
|
|
901
|
+
memory: "j/k enter",
|
|
902
|
+
chat: "enter esc",
|
|
903
|
+
rawlog: "n/p b"
|
|
904
|
+
};
|
|
828
905
|
function Footer() {
|
|
829
906
|
const { state } = useDashboard();
|
|
830
907
|
const { view, goalsPanel, hypothesesPanel } = state;
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
908
|
+
const { stdout } = useStdout2();
|
|
909
|
+
const cols = stdout?.columns || 80;
|
|
910
|
+
const narrow = cols < 60;
|
|
911
|
+
const veryNarrow = cols < 40;
|
|
912
|
+
const labels = narrow ? VIEW_SHORT : VIEW_LABELS;
|
|
913
|
+
let hints;
|
|
914
|
+
if (view === "goals" && goalsPanel.inputMode === "add") {
|
|
915
|
+
hints = narrow ? "enter esc" : "enter save \xB7 esc cancel";
|
|
916
|
+
} else if (view === "hypotheses" && hypothesesPanel.inputMode === "add") {
|
|
917
|
+
hints = narrow ? "enter esc" : "enter save \xB7 esc cancel";
|
|
918
|
+
} else {
|
|
919
|
+
const hintMap = narrow ? CONTEXT_HINTS_SHORT : CONTEXT_HINTS;
|
|
920
|
+
hints = hintMap[view] || (narrow ? "s n/p" : "n/p pages \xB7 s settings");
|
|
921
|
+
}
|
|
922
|
+
if (veryNarrow) {
|
|
923
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
|
|
924
|
+
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => v === view ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: labels[v] }, v) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: labels[v] }, v)) }),
|
|
925
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
926
|
+
hints,
|
|
927
|
+
" \xB7 q quit"
|
|
928
|
+
] })
|
|
929
|
+
] });
|
|
930
|
+
}
|
|
834
931
|
return /* @__PURE__ */ jsxs2(Box2, { paddingX: 1, justifyContent: "space-between", children: [
|
|
835
|
-
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => v === view ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children:
|
|
932
|
+
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => v === view ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: labels[v] }, v) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: labels[v] }, v)) }),
|
|
836
933
|
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
837
934
|
hints,
|
|
838
935
|
" \xB7 q quit"
|
|
@@ -841,21 +938,21 @@ function Footer() {
|
|
|
841
938
|
}
|
|
842
939
|
|
|
843
940
|
// src/cli/dashboard/components/Notification.tsx
|
|
844
|
-
import { Box as Box3, Text as Text3 } from "ink";
|
|
941
|
+
import { Box as Box3, Text as Text3, useStdout as useStdout3 } from "ink";
|
|
845
942
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
846
943
|
function Notification() {
|
|
847
944
|
const { state } = useDashboard();
|
|
848
945
|
const { notification } = state;
|
|
946
|
+
const { stdout } = useStdout3();
|
|
947
|
+
const cols = stdout?.columns || 80;
|
|
849
948
|
if (!notification || !notification.active) return null;
|
|
850
949
|
if (notification.autoHideAt && Date.now() > notification.autoHideAt) return null;
|
|
851
950
|
const color = notification.severity === "critical" ? "red" : notification.severity === "warning" ? "yellow" : "blue";
|
|
951
|
+
const maxMsgLen = Math.max(20, cols - 8);
|
|
952
|
+
const msg = notification.message.length > maxMsgLen ? notification.message.slice(0, maxMsgLen - 1) + "..." : notification.message;
|
|
852
953
|
return /* @__PURE__ */ jsxs3(Box3, { paddingX: 1, children: [
|
|
853
954
|
/* @__PURE__ */ jsx4(Text3, { color, bold: true, children: "\u25CF " }),
|
|
854
|
-
/* @__PURE__ */ jsx4(Text3, { children:
|
|
855
|
-
notification.file && /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
856
|
-
" ",
|
|
857
|
-
notification.file
|
|
858
|
-
] })
|
|
955
|
+
/* @__PURE__ */ jsx4(Text3, { wrap: "truncate", children: msg })
|
|
859
956
|
] });
|
|
860
957
|
}
|
|
861
958
|
|
|
@@ -1035,11 +1132,13 @@ function ConfigDialog({ onClose }) {
|
|
|
1035
1132
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1036
1133
|
const trieDir = getTrieDirectory(workDir);
|
|
1037
1134
|
const filesToDelete = [
|
|
1038
|
-
join(trieDir, "context
|
|
1135
|
+
join(trieDir, "context.db"),
|
|
1136
|
+
join(trieDir, "context.json"),
|
|
1039
1137
|
join(trieDir, "incident-trie.json"),
|
|
1040
1138
|
join(trieDir, "memory", "ledger.json"),
|
|
1041
1139
|
join(trieDir, "memory", "issue-store.db"),
|
|
1042
|
-
join(trieDir, "memory", "insights.json")
|
|
1140
|
+
join(trieDir, "memory", "insights.json"),
|
|
1141
|
+
join(trieDir, "memory", "issues.json")
|
|
1043
1142
|
];
|
|
1044
1143
|
for (const file of filesToDelete) {
|
|
1045
1144
|
if (existsSync(file)) {
|
|
@@ -1105,18 +1204,41 @@ function ConfigDialog({ onClose }) {
|
|
|
1105
1204
|
}
|
|
1106
1205
|
|
|
1107
1206
|
// src/cli/dashboard/views/OverviewView.tsx
|
|
1108
|
-
import { Box as Box5, Text as Text5 } from "ink";
|
|
1109
|
-
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1207
|
+
import { Box as Box5, Text as Text5, useInput as useInput2, useStdout as useStdout4 } from "ink";
|
|
1208
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1209
|
+
function truncate(str, max) {
|
|
1210
|
+
return str.length > max ? str.slice(0, max - 1) + "..." : str;
|
|
1211
|
+
}
|
|
1110
1212
|
function OverviewView() {
|
|
1111
|
-
const { state } = useDashboard();
|
|
1112
|
-
const { progress, signalExtraction, watch, issues, activityLog, activityPage } = state;
|
|
1213
|
+
const { state, dispatch } = useDashboard();
|
|
1214
|
+
const { progress, signalExtraction, watch, issues, activityLog, activityPage, pendingFixes, selectedFixIndex } = state;
|
|
1113
1215
|
const { totalIssues } = progress;
|
|
1216
|
+
const { stdout } = useStdout4();
|
|
1217
|
+
const cols = stdout?.columns || 80;
|
|
1218
|
+
const narrow = cols < 60;
|
|
1219
|
+
const contentWidth = Math.max(20, cols - 4);
|
|
1114
1220
|
const endTime = state.scanComplete && state.scanEndTime ? state.scanEndTime : Date.now();
|
|
1115
1221
|
const elapsed = ((endTime - state.scanStartTime) / 1e3).toFixed(1);
|
|
1116
1222
|
const criticalIssues = issues.filter((i) => i.severity === "critical").slice(0, 3);
|
|
1117
|
-
const
|
|
1223
|
+
const activeFixes = pendingFixes.filter((f) => f.status === "pending" || f.status === "applying");
|
|
1224
|
+
const activityRows = activeFixes.length > 0 ? 5 : 8;
|
|
1118
1225
|
const startIdx = activityPage * activityRows;
|
|
1119
1226
|
const pageActivities = activityLog.slice(startIdx, startIdx + activityRows);
|
|
1227
|
+
useInput2((input, key) => {
|
|
1228
|
+
if (state.view !== "overview" || activeFixes.length === 0) return;
|
|
1229
|
+
if (key.upArrow && activeFixes.length > 0) {
|
|
1230
|
+
dispatch({ type: "SELECT_FIX", index: Math.max(0, selectedFixIndex - 1) });
|
|
1231
|
+
}
|
|
1232
|
+
if (key.downArrow && activeFixes.length > 0) {
|
|
1233
|
+
dispatch({ type: "SELECT_FIX", index: Math.min(activeFixes.length - 1, selectedFixIndex + 1) });
|
|
1234
|
+
}
|
|
1235
|
+
if (input === "f" && activeFixes[selectedFixIndex]) {
|
|
1236
|
+
dispatch({ type: "APPROVE_FIX", id: activeFixes[selectedFixIndex].id });
|
|
1237
|
+
}
|
|
1238
|
+
if (input === "x" && activeFixes[selectedFixIndex]) {
|
|
1239
|
+
dispatch({ type: "DISMISS_FIX", id: activeFixes[selectedFixIndex].id });
|
|
1240
|
+
}
|
|
1241
|
+
});
|
|
1120
1242
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, children: [
|
|
1121
1243
|
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1122
1244
|
"Scanned ",
|
|
@@ -1125,26 +1247,27 @@ function OverviewView() {
|
|
|
1125
1247
|
elapsed,
|
|
1126
1248
|
"s"
|
|
1127
1249
|
] }),
|
|
1128
|
-
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1250
|
+
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
|
|
1129
1251
|
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CF" }),
|
|
1130
1252
|
" Signal extraction",
|
|
1131
|
-
(signalExtraction.decisionsExtracted > 0 || signalExtraction.factsExtracted > 0 || signalExtraction.blockersExtracted > 0) && /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1253
|
+
!narrow && (signalExtraction.decisionsExtracted > 0 || signalExtraction.factsExtracted > 0 || signalExtraction.blockersExtracted > 0) && /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1132
1254
|
" ",
|
|
1133
1255
|
signalExtraction.decisionsExtracted,
|
|
1134
|
-
"
|
|
1256
|
+
"d \xB7 ",
|
|
1135
1257
|
signalExtraction.factsExtracted,
|
|
1136
|
-
"
|
|
1258
|
+
"f \xB7 ",
|
|
1137
1259
|
signalExtraction.blockersExtracted,
|
|
1138
|
-
"
|
|
1260
|
+
"b"
|
|
1139
1261
|
] })
|
|
1140
1262
|
] }),
|
|
1141
1263
|
criticalIssues.length > 0 && criticalIssues.map((issue, i) => {
|
|
1142
1264
|
const filename = issue.file.split("/").pop() || issue.file;
|
|
1143
1265
|
const lineNum = issue.line ? `:${issue.line}` : "";
|
|
1144
|
-
|
|
1266
|
+
const issueLen = Math.max(15, contentWidth - filename.length - 6);
|
|
1267
|
+
return /* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
|
|
1145
1268
|
/* @__PURE__ */ jsx6(Text5, { color: "red", children: "\u25CF" }),
|
|
1146
1269
|
" ",
|
|
1147
|
-
/* @__PURE__ */ jsx6(Text5, { color: "red", children: issue.issue
|
|
1270
|
+
/* @__PURE__ */ jsx6(Text5, { color: "red", children: truncate(issue.issue, issueLen) }),
|
|
1148
1271
|
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1149
1272
|
" ",
|
|
1150
1273
|
filename,
|
|
@@ -1152,25 +1275,62 @@ function OverviewView() {
|
|
|
1152
1275
|
] })
|
|
1153
1276
|
] }, i);
|
|
1154
1277
|
}),
|
|
1155
|
-
totalIssues === 0 && criticalIssues.length === 0 && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1278
|
+
totalIssues === 0 && criticalIssues.length === 0 && activeFixes.length === 0 && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1156
1279
|
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CF" }),
|
|
1157
1280
|
" No issues"
|
|
1158
1281
|
] }),
|
|
1159
|
-
/* @__PURE__ */
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1282
|
+
activeFixes.length > 0 && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
1283
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: "Goal Violations" }),
|
|
1284
|
+
activeFixes.map((fix, i) => {
|
|
1285
|
+
const isSelected = i === selectedFixIndex;
|
|
1286
|
+
const confidenceColor = fix.confidence >= 90 ? "green" : fix.confidence >= 70 ? "yellow" : "red";
|
|
1287
|
+
const shortFile = fix.file.split("/").pop() || fix.file;
|
|
1288
|
+
const descLen = Math.max(15, contentWidth - shortFile.length - 10);
|
|
1289
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
1290
|
+
/* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
|
|
1291
|
+
isSelected ? /* @__PURE__ */ jsx6(Text5, { bold: true, color: "yellow", children: "> " }) : " ",
|
|
1292
|
+
/* @__PURE__ */ jsx6(Text5, { color: "yellow", children: "\u25CF" }),
|
|
1293
|
+
" ",
|
|
1294
|
+
/* @__PURE__ */ jsx6(Text5, { children: truncate(fix.description, descLen) }),
|
|
1295
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1296
|
+
" ",
|
|
1297
|
+
shortFile
|
|
1298
|
+
] })
|
|
1299
|
+
] }),
|
|
1300
|
+
/* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
|
|
1301
|
+
" ",
|
|
1302
|
+
/* @__PURE__ */ jsxs5(Text5, { color: confidenceColor, bold: true, children: [
|
|
1303
|
+
fix.confidence,
|
|
1304
|
+
"%"
|
|
1305
|
+
] }),
|
|
1306
|
+
narrow ? fix.status === "applying" && /* @__PURE__ */ jsx6(Text5, { color: "cyan", children: " applying..." }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1307
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1308
|
+
" confidence fix: ",
|
|
1309
|
+
truncate(fix.suggestedFix, contentWidth - 25)
|
|
1310
|
+
] }),
|
|
1311
|
+
fix.status === "applying" && /* @__PURE__ */ jsx6(Text5, { color: "cyan", children: " applying..." })
|
|
1312
|
+
] })
|
|
1313
|
+
] })
|
|
1314
|
+
] }, fix.id);
|
|
1315
|
+
}),
|
|
1316
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " f fix \xB7 x dismiss" })
|
|
1317
|
+
] }),
|
|
1318
|
+
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
1319
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: "Activity" }),
|
|
1320
|
+
pageActivities.map((entry, i) => /* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
|
|
1321
|
+
" ",
|
|
1322
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: entry.time }),
|
|
1323
|
+
" ",
|
|
1324
|
+
truncate(entry.message, contentWidth - 14)
|
|
1325
|
+
] }, i)),
|
|
1326
|
+
pageActivities.length === 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " No activity yet" })
|
|
1327
|
+
] })
|
|
1168
1328
|
] });
|
|
1169
1329
|
}
|
|
1170
1330
|
|
|
1171
1331
|
// src/cli/dashboard/views/AgentView.tsx
|
|
1172
1332
|
import { useEffect, useCallback } from "react";
|
|
1173
|
-
import { Box as Box6, Text as Text6, useInput as
|
|
1333
|
+
import { Box as Box6, Text as Text6, useInput as useInput3, useStdout as useStdout5 } from "ink";
|
|
1174
1334
|
|
|
1175
1335
|
// src/cli/dashboard/theme.ts
|
|
1176
1336
|
import pc from "picocolors";
|
|
@@ -1221,6 +1381,9 @@ function timeAgo(iso) {
|
|
|
1221
1381
|
function AgentView() {
|
|
1222
1382
|
const { state, dispatch } = useDashboard();
|
|
1223
1383
|
const { agentInsights, agentBrain, selectedInsight, expandedInsight } = state;
|
|
1384
|
+
const { stdout } = useStdout5();
|
|
1385
|
+
const cols = stdout?.columns || 80;
|
|
1386
|
+
const msgLen = Math.max(20, cols - 25);
|
|
1224
1387
|
const visibleInsights = getVisibleInsights(state);
|
|
1225
1388
|
const alerts = visibleInsights.filter((i) => i.type === "warning");
|
|
1226
1389
|
const { decisions, patterns, loaded } = agentBrain;
|
|
@@ -1244,7 +1407,7 @@ function AgentView() {
|
|
|
1244
1407
|
void loadBrain();
|
|
1245
1408
|
}
|
|
1246
1409
|
}, [loaded, loadBrain]);
|
|
1247
|
-
|
|
1410
|
+
useInput3((input, key) => {
|
|
1248
1411
|
if (key.upArrow || input === "k") dispatch({ type: "NAVIGATE_UP" });
|
|
1249
1412
|
else if (key.downArrow || input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
1250
1413
|
else if (key.return) dispatch({ type: "TOGGLE_INSIGHT", index: selectedInsight });
|
|
@@ -1282,10 +1445,10 @@ function AgentView() {
|
|
|
1282
1445
|
const isSelected = idx === selectedInsight;
|
|
1283
1446
|
const isExpanded = idx === expandedInsight;
|
|
1284
1447
|
const ago = formatTimeAgo(insight.timestamp);
|
|
1285
|
-
const msg = insight.message.slice(0,
|
|
1448
|
+
const msg = insight.message.slice(0, msgLen) + (insight.message.length > msgLen ? "..." : "");
|
|
1286
1449
|
const riskColor = insight.priority >= 8 ? "red" : insight.priority >= 5 ? "yellow" : void 0;
|
|
1287
1450
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1288
|
-
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1451
|
+
/* @__PURE__ */ jsxs6(Text6, { wrap: "truncate", children: [
|
|
1289
1452
|
isSelected ? /* @__PURE__ */ jsx7(Text6, { bold: true, color: "green", children: "> " }) : " ",
|
|
1290
1453
|
riskColor ? /* @__PURE__ */ jsx7(Text6, { color: riskColor, children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1291
1454
|
" ",
|
|
@@ -1316,8 +1479,8 @@ function AgentView() {
|
|
|
1316
1479
|
" ",
|
|
1317
1480
|
active ? /* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1318
1481
|
" ",
|
|
1319
|
-
dec.decision.slice(0,
|
|
1320
|
-
dec.decision.length >
|
|
1482
|
+
dec.decision.slice(0, msgLen),
|
|
1483
|
+
dec.decision.length > msgLen ? "..." : "",
|
|
1321
1484
|
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1322
1485
|
" ",
|
|
1323
1486
|
ago
|
|
@@ -1334,8 +1497,8 @@ function AgentView() {
|
|
|
1334
1497
|
" ",
|
|
1335
1498
|
pat.isAntiPattern ? /* @__PURE__ */ jsx7(Text6, { color: "red", children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1336
1499
|
" ",
|
|
1337
|
-
pat.description.slice(0,
|
|
1338
|
-
pat.description.length >
|
|
1500
|
+
pat.description.slice(0, msgLen),
|
|
1501
|
+
pat.description.length > msgLen ? "..." : "",
|
|
1339
1502
|
" ",
|
|
1340
1503
|
confColor ? /* @__PURE__ */ jsxs6(Text6, { color: confColor, children: [
|
|
1341
1504
|
conf,
|
|
@@ -1367,8 +1530,8 @@ function AgentView() {
|
|
|
1367
1530
|
|
|
1368
1531
|
// src/cli/dashboard/views/GoalsView.tsx
|
|
1369
1532
|
import { useCallback as useCallback2 } from "react";
|
|
1370
|
-
import { Box as Box7, Text as Text7, useInput as
|
|
1371
|
-
import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1533
|
+
import { Box as Box7, Text as Text7, useInput as useInput4 } from "ink";
|
|
1534
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1372
1535
|
function calculateGoalProgress(goal) {
|
|
1373
1536
|
if (goal.target <= 0) return 0;
|
|
1374
1537
|
const startValue = goal.startValue ?? goal.currentValue;
|
|
@@ -1464,7 +1627,7 @@ function GoalsView() {
|
|
|
1464
1627
|
} catch {
|
|
1465
1628
|
}
|
|
1466
1629
|
}, [dispatch, refreshGoals]);
|
|
1467
|
-
|
|
1630
|
+
useInput4((_input, key) => {
|
|
1468
1631
|
if (goalsPanel.inputMode === "add") {
|
|
1469
1632
|
if (key.escape) {
|
|
1470
1633
|
dispatch({ type: "SET_GOALS_INPUT_MODE", mode: "browse" });
|
|
@@ -1503,7 +1666,7 @@ function GoalsView() {
|
|
|
1503
1666
|
/* @__PURE__ */ jsx8(Text7, { bold: true, color: "green", children: "|" })
|
|
1504
1667
|
] }) }),
|
|
1505
1668
|
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
1506
|
-
] }) : /* @__PURE__ */ jsx8(
|
|
1669
|
+
] }) : /* @__PURE__ */ jsx8(Fragment2, { children: goalsPanel.goals.length === 0 ? /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " No goals yet. Press a to add one." }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1507
1670
|
activeGoals.map((goal, idx) => {
|
|
1508
1671
|
const isSelected = goalsPanel.selectedIndex === idx;
|
|
1509
1672
|
const progress = calculateGoalProgress(goal);
|
|
@@ -1555,8 +1718,8 @@ function GoalsView() {
|
|
|
1555
1718
|
|
|
1556
1719
|
// src/cli/dashboard/views/HypothesesView.tsx
|
|
1557
1720
|
import { useCallback as useCallback3 } from "react";
|
|
1558
|
-
import { Box as Box8, Text as Text8, useInput as
|
|
1559
|
-
import { Fragment as
|
|
1721
|
+
import { Box as Box8, Text as Text8, useInput as useInput5 } from "ink";
|
|
1722
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1560
1723
|
function HypothesesView() {
|
|
1561
1724
|
const { state, dispatch } = useDashboard();
|
|
1562
1725
|
const { hypothesesPanel } = state;
|
|
@@ -1625,7 +1788,7 @@ function HypothesesView() {
|
|
|
1625
1788
|
} catch {
|
|
1626
1789
|
}
|
|
1627
1790
|
}, [dispatch, refreshHypotheses]);
|
|
1628
|
-
|
|
1791
|
+
useInput5((_input, key) => {
|
|
1629
1792
|
if (hypothesesPanel.inputMode === "add") {
|
|
1630
1793
|
if (key.escape) {
|
|
1631
1794
|
dispatch({ type: "SET_HYPOTHESES_INPUT_MODE", mode: "browse" });
|
|
@@ -1667,7 +1830,7 @@ function HypothesesView() {
|
|
|
1667
1830
|
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "|" })
|
|
1668
1831
|
] }) }),
|
|
1669
1832
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
1670
|
-
] }) : /* @__PURE__ */ jsx9(
|
|
1833
|
+
] }) : /* @__PURE__ */ jsx9(Fragment3, { children: hypothesesPanel.hypotheses.length === 0 ? /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " No hypotheses yet. Press a to add one." }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1671
1834
|
testing.map((hypo, idx) => {
|
|
1672
1835
|
const isSelected = hypothesesPanel.selectedIndex === idx;
|
|
1673
1836
|
const conf = Math.round(hypo.confidence * 100);
|
|
@@ -1719,8 +1882,8 @@ function HypothesesView() {
|
|
|
1719
1882
|
|
|
1720
1883
|
// src/cli/dashboard/views/MemoryTreeView.tsx
|
|
1721
1884
|
import { useEffect as useEffect2, useCallback as useCallback4 } from "react";
|
|
1722
|
-
import { Box as Box9, Text as Text9, useInput as
|
|
1723
|
-
import { Fragment as
|
|
1885
|
+
import { Box as Box9, Text as Text9, useInput as useInput6 } from "ink";
|
|
1886
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1724
1887
|
function timeAgo2(iso) {
|
|
1725
1888
|
const ms = Date.now() - new Date(iso).getTime();
|
|
1726
1889
|
const mins = Math.floor(ms / 6e4);
|
|
@@ -1751,7 +1914,7 @@ function MemoryTreeView() {
|
|
|
1751
1914
|
void loadData();
|
|
1752
1915
|
}
|
|
1753
1916
|
}, [loaded, loadData]);
|
|
1754
|
-
|
|
1917
|
+
useInput6((_input, key) => {
|
|
1755
1918
|
if (key.upArrow || _input === "k") dispatch({ type: "NAVIGATE_UP" });
|
|
1756
1919
|
else if (key.downArrow || _input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
1757
1920
|
else if (key.return) dispatch({ type: "TOGGLE_MEMORY_NODE", nodeId: selectedNode });
|
|
@@ -1888,7 +2051,7 @@ function MemoryTreeView() {
|
|
|
1888
2051
|
] })
|
|
1889
2052
|
] }, pattern.id);
|
|
1890
2053
|
}),
|
|
1891
|
-
hotspots.length > 0 && /* @__PURE__ */ jsxs9(
|
|
2054
|
+
hotspots.length > 0 && /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
1892
2055
|
renderHeader("hotspots", "Risk Hotspots", hotspots.length),
|
|
1893
2056
|
expandedNodes.has("hotspots") && hotspots.slice(0, 10).map((n) => {
|
|
1894
2057
|
const nodeId = `file-${n.id}`;
|
|
@@ -1914,14 +2077,14 @@ function MemoryTreeView() {
|
|
|
1914
2077
|
}
|
|
1915
2078
|
|
|
1916
2079
|
// src/cli/dashboard/views/RawLogView.tsx
|
|
1917
|
-
import { Box as Box10, Text as Text10, useInput as
|
|
2080
|
+
import { Box as Box10, Text as Text10, useInput as useInput7 } from "ink";
|
|
1918
2081
|
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1919
2082
|
function RawLogView() {
|
|
1920
2083
|
const { state, dispatch } = useDashboard();
|
|
1921
2084
|
const { rawLog, rawLogPage } = state;
|
|
1922
2085
|
const pageSize = Math.max(10, (process.stdout.rows || 40) - 10);
|
|
1923
2086
|
const totalPages = Math.max(1, Math.ceil(rawLog.length / pageSize));
|
|
1924
|
-
|
|
2087
|
+
useInput7((input, _key) => {
|
|
1925
2088
|
if (input === "n") dispatch({ type: "SET_RAW_LOG_PAGE", page: Math.min(totalPages - 1, rawLogPage + 1) });
|
|
1926
2089
|
else if (input === "p") dispatch({ type: "SET_RAW_LOG_PAGE", page: Math.max(0, rawLogPage - 1) });
|
|
1927
2090
|
});
|
|
@@ -1955,7 +2118,7 @@ function RawLogView() {
|
|
|
1955
2118
|
|
|
1956
2119
|
// src/cli/dashboard/views/ChatView.tsx
|
|
1957
2120
|
import { useCallback as useCallback5, useRef } from "react";
|
|
1958
|
-
import { Box as Box11, Text as Text11, useInput as
|
|
2121
|
+
import { Box as Box11, Text as Text11, useInput as useInput8 } from "ink";
|
|
1959
2122
|
|
|
1960
2123
|
// src/tools/tell.ts
|
|
1961
2124
|
import path from "path";
|
|
@@ -4319,6 +4482,98 @@ ${checkpoint.files.length > 0 ? `**Files:** ${checkpoint.files.join(", ")}` : ""
|
|
|
4319
4482
|
|
|
4320
4483
|
// src/cli/dashboard/chat-tools.ts
|
|
4321
4484
|
import { createHash } from "crypto";
|
|
4485
|
+
|
|
4486
|
+
// src/utils/terminal-spawn.ts
|
|
4487
|
+
import { exec } from "child_process";
|
|
4488
|
+
import { promisify } from "util";
|
|
4489
|
+
import { platform } from "os";
|
|
4490
|
+
var execAsync = promisify(exec);
|
|
4491
|
+
async function spawnTerminal(options) {
|
|
4492
|
+
const { command, cwd, title, keepOpen = true } = options;
|
|
4493
|
+
const os = platform();
|
|
4494
|
+
if (os === "darwin") {
|
|
4495
|
+
await spawnMacOSTerminal(command, cwd, title, keepOpen);
|
|
4496
|
+
} else if (os === "linux") {
|
|
4497
|
+
await spawnLinuxTerminal(command, cwd, title, keepOpen);
|
|
4498
|
+
} else {
|
|
4499
|
+
throw new Error(`Terminal spawning not supported on ${os}`);
|
|
4500
|
+
}
|
|
4501
|
+
}
|
|
4502
|
+
async function spawnMacOSTerminal(command, cwd, title, keepOpen) {
|
|
4503
|
+
const escapedCommand = command.replace(/'/g, `'"'"'`);
|
|
4504
|
+
const escapedCwd = cwd?.replace(/'/g, `'"'"'`) || process.cwd();
|
|
4505
|
+
const escapedTitle = title?.replace(/'/g, `'"'"'`) || "Trie Agent";
|
|
4506
|
+
const fullCommand = cwd ? `cd '${escapedCwd}' && ${command}` : command;
|
|
4507
|
+
const escapedFullCommand = fullCommand.replace(/'/g, `'"'"'`);
|
|
4508
|
+
const script = `
|
|
4509
|
+
tell application "Terminal"
|
|
4510
|
+
activate
|
|
4511
|
+
set newTab to do script "${escapedFullCommand}"
|
|
4512
|
+
set custom title of newTab to "${escapedTitle}"
|
|
4513
|
+
end tell
|
|
4514
|
+
`.trim();
|
|
4515
|
+
try {
|
|
4516
|
+
await execAsync(`osascript -e '${script.replace(/'/g, `'"'"'`)}'`);
|
|
4517
|
+
} catch (error) {
|
|
4518
|
+
console.error("Terminal.app spawn failed, trying fallback...");
|
|
4519
|
+
const shellCmd = keepOpen ? `${fullCommand}; exec bash` : fullCommand;
|
|
4520
|
+
await execAsync(`open -a Terminal "${escapedCwd}" --args -e "${shellCmd}"`);
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
4523
|
+
async function spawnLinuxTerminal(command, cwd, title, keepOpen) {
|
|
4524
|
+
const workDir = cwd || process.cwd();
|
|
4525
|
+
const termTitle = title || "Trie Agent";
|
|
4526
|
+
const shellCmd = keepOpen ? `${command}; exec bash` : command;
|
|
4527
|
+
const terminals = [
|
|
4528
|
+
// GNOME Terminal
|
|
4529
|
+
{
|
|
4530
|
+
command: "gnome-terminal",
|
|
4531
|
+
args: `--working-directory="${workDir}" --title="${termTitle}" -- bash -c "${shellCmd}"`
|
|
4532
|
+
},
|
|
4533
|
+
// Konsole (KDE)
|
|
4534
|
+
{
|
|
4535
|
+
command: "konsole",
|
|
4536
|
+
args: `--workdir "${workDir}" --title "${termTitle}" -e bash -c "${shellCmd}"`
|
|
4537
|
+
},
|
|
4538
|
+
// xterm (fallback)
|
|
4539
|
+
{
|
|
4540
|
+
command: "xterm",
|
|
4541
|
+
args: `-T "${termTitle}" -e "cd '${workDir}' && ${shellCmd}"`
|
|
4542
|
+
}
|
|
4543
|
+
];
|
|
4544
|
+
for (const term of terminals) {
|
|
4545
|
+
try {
|
|
4546
|
+
await execAsync(`which ${term.command}`);
|
|
4547
|
+
await execAsync(`${term.command} ${term.args} &`);
|
|
4548
|
+
return;
|
|
4549
|
+
} catch {
|
|
4550
|
+
continue;
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
throw new Error("No supported terminal emulator found (tried: gnome-terminal, konsole, xterm)");
|
|
4554
|
+
}
|
|
4555
|
+
async function spawnClaudeCodeFix(options) {
|
|
4556
|
+
const { file, goal, violation, suggestedFix, cwd } = options;
|
|
4557
|
+
const prompt = `Fix this goal violation:
|
|
4558
|
+
|
|
4559
|
+
Goal: ${goal}
|
|
4560
|
+
File: ${file}
|
|
4561
|
+
Violation: ${violation}
|
|
4562
|
+
${suggestedFix ? `Suggested fix: ${suggestedFix}` : ""}
|
|
4563
|
+
|
|
4564
|
+
Please review the file and fix the violation while preserving functionality.`;
|
|
4565
|
+
const escapedPrompt = prompt.replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
4566
|
+
const escapedFile = file.replace(/"/g, '\\"');
|
|
4567
|
+
const command = `echo "${escapedPrompt}" | claude --file="${escapedFile}"`;
|
|
4568
|
+
await spawnTerminal({
|
|
4569
|
+
command,
|
|
4570
|
+
cwd,
|
|
4571
|
+
title: `Fixing: ${file}`,
|
|
4572
|
+
keepOpen: true
|
|
4573
|
+
});
|
|
4574
|
+
}
|
|
4575
|
+
|
|
4576
|
+
// src/cli/dashboard/chat-tools.ts
|
|
4322
4577
|
function textFromResult(result) {
|
|
4323
4578
|
return result.content.map((c) => c.text).join("\n");
|
|
4324
4579
|
}
|
|
@@ -4468,6 +4723,20 @@ var CHAT_TOOLS = [
|
|
|
4468
4723
|
},
|
|
4469
4724
|
required: ["decision", "context"]
|
|
4470
4725
|
}
|
|
4726
|
+
},
|
|
4727
|
+
{
|
|
4728
|
+
name: "trie_fix_goal_violation",
|
|
4729
|
+
description: "Spawn Claude Code in a new terminal to fix a goal violation. Use when the user wants to auto-fix a goal violation detected by the watcher.",
|
|
4730
|
+
input_schema: {
|
|
4731
|
+
type: "object",
|
|
4732
|
+
properties: {
|
|
4733
|
+
file: { type: "string", description: "File path with the goal violation" },
|
|
4734
|
+
goal: { type: "string", description: "The goal that was violated" },
|
|
4735
|
+
violation: { type: "string", description: "Description of the violation" },
|
|
4736
|
+
suggestedFix: { type: "string", description: "Suggested fix for the violation (optional)" }
|
|
4737
|
+
},
|
|
4738
|
+
required: ["file", "goal", "violation"]
|
|
4739
|
+
}
|
|
4471
4740
|
}
|
|
4472
4741
|
];
|
|
4473
4742
|
async function executeTool(name, input) {
|
|
@@ -4617,6 +4886,35 @@ async function executeTool(name, input) {
|
|
|
4617
4886
|
});
|
|
4618
4887
|
return `Decision recorded [${hash}]: "${dec}"`;
|
|
4619
4888
|
}
|
|
4889
|
+
case "trie_fix_goal_violation": {
|
|
4890
|
+
const file = String(input.file || "").trim();
|
|
4891
|
+
const goal = String(input.goal || "").trim();
|
|
4892
|
+
const violation = String(input.violation || "").trim();
|
|
4893
|
+
const suggestedFix = input.suggestedFix ? String(input.suggestedFix) : void 0;
|
|
4894
|
+
if (!file) return "File path is required.";
|
|
4895
|
+
if (!goal) return "Goal description is required.";
|
|
4896
|
+
if (!violation) return "Violation description is required.";
|
|
4897
|
+
try {
|
|
4898
|
+
await spawnClaudeCodeFix({
|
|
4899
|
+
file,
|
|
4900
|
+
goal,
|
|
4901
|
+
violation,
|
|
4902
|
+
suggestedFix,
|
|
4903
|
+
cwd: directory
|
|
4904
|
+
});
|
|
4905
|
+
return `\u2713 Spawned Claude Code in a new terminal to fix "${file}".
|
|
4906
|
+
|
|
4907
|
+
Claude Code will:
|
|
4908
|
+
1. Review the file
|
|
4909
|
+
2. Understand the goal: "${goal}"
|
|
4910
|
+
3. Fix the violation: "${violation}"
|
|
4911
|
+
4. Preserve all functionality
|
|
4912
|
+
|
|
4913
|
+
Check the new terminal window to see the fix in progress.`;
|
|
4914
|
+
} catch (error) {
|
|
4915
|
+
return `Failed to spawn Claude Code: ${error instanceof Error ? error.message : "unknown error"}`;
|
|
4916
|
+
}
|
|
4917
|
+
}
|
|
4620
4918
|
default:
|
|
4621
4919
|
return `Unknown tool: ${name}`;
|
|
4622
4920
|
}
|
|
@@ -4626,6 +4924,20 @@ async function executeTool(name, input) {
|
|
|
4626
4924
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4627
4925
|
async function buildContext(workDir) {
|
|
4628
4926
|
const parts = [];
|
|
4927
|
+
try {
|
|
4928
|
+
const guardianState = getGuardianState(workDir);
|
|
4929
|
+
await guardianState.load();
|
|
4930
|
+
const activeGoals = guardianState.getAllGoals().filter((g) => g.status === "active");
|
|
4931
|
+
if (activeGoals.length > 0) {
|
|
4932
|
+
parts.push("Active goals:\n" + activeGoals.map((g) => {
|
|
4933
|
+
const metadata = g.metadata || {};
|
|
4934
|
+
const caughtCount = metadata.caughtCount || 0;
|
|
4935
|
+
const lastCaught = metadata.lastCaught ? ` (last violation: ${metadata.lastCaughtFile || "unknown"})` : "";
|
|
4936
|
+
return `- "${g.description}" [${g.category || "general"}]${caughtCount > 0 ? ` - ${caughtCount} violation(s)${lastCaught}` : ""}`;
|
|
4937
|
+
}).join("\n"));
|
|
4938
|
+
}
|
|
4939
|
+
} catch {
|
|
4940
|
+
}
|
|
4629
4941
|
try {
|
|
4630
4942
|
const storage = new TieredStorage(workDir);
|
|
4631
4943
|
try {
|
|
@@ -4690,6 +5002,12 @@ function chatHistoryToMessages(history) {
|
|
|
4690
5002
|
}
|
|
4691
5003
|
var SYSTEM_PROMPT = `You are Trie, a code guardian assistant embedded in a terminal TUI.
|
|
4692
5004
|
You have tools to take actions on the user's codebase \u2014 use them when the user asks you to check files, record incidents, give feedback, query decisions, or save checkpoints.
|
|
5005
|
+
|
|
5006
|
+
When the user mentions a goal violation or asks you to fix something detected by the watcher:
|
|
5007
|
+
1. Extract the file path, goal description, and violation details from context
|
|
5008
|
+
2. Use trie_fix_goal_violation to spawn Claude Code in a new terminal
|
|
5009
|
+
3. Claude Code will automatically fix the violation
|
|
5010
|
+
|
|
4693
5011
|
Answer concisely. Reference specific files, decisions, and patterns when relevant.
|
|
4694
5012
|
When you use a tool, briefly summarize what you did and what the result was.`;
|
|
4695
5013
|
function ChatView() {
|
|
@@ -4778,7 +5096,7 @@ ${contextBlock}`;
|
|
|
4778
5096
|
loadingRef.current = false;
|
|
4779
5097
|
}
|
|
4780
5098
|
}, [dispatch, messages]);
|
|
4781
|
-
|
|
5099
|
+
useInput8((input, key) => {
|
|
4782
5100
|
if (loading) return;
|
|
4783
5101
|
if (key.return && inputBuffer.trim().length > 0) {
|
|
4784
5102
|
void sendMessage(inputBuffer.trim());
|
|
@@ -4841,6 +5159,56 @@ function formatToolInput(input) {
|
|
|
4841
5159
|
// src/cli/dashboard/App.tsx
|
|
4842
5160
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4843
5161
|
var MAIN_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
5162
|
+
async function applyGoalFix(fix, dispatch) {
|
|
5163
|
+
try {
|
|
5164
|
+
const { runAIAnalysis, isAIAvailable: isAIAvailable2 } = await import("./client-PMKE26IV.js");
|
|
5165
|
+
if (!isAIAvailable2()) {
|
|
5166
|
+
dispatch({ type: "DISMISS_FIX", id: fix.id });
|
|
5167
|
+
getOutputManager().nudge("AI not available for fix", "warning");
|
|
5168
|
+
return;
|
|
5169
|
+
}
|
|
5170
|
+
const projectPath = getWorkingDirectory(void 0, true);
|
|
5171
|
+
const fullPath = join2(projectPath, fix.file);
|
|
5172
|
+
const content = await readFile2(fullPath, "utf-8");
|
|
5173
|
+
const result = await runAIAnalysis({
|
|
5174
|
+
systemPrompt: `You are a precise code fixer. The user has a quality goal: "${fix.goalDescription}".
|
|
5175
|
+
A violation was detected: "${fix.description}"
|
|
5176
|
+
Suggested fix: "${fix.suggestedFix}"
|
|
5177
|
+
|
|
5178
|
+
Return the COMPLETE fixed file content. Make the minimal change needed to resolve the violation.
|
|
5179
|
+
Do NOT add comments explaining the fix. Do NOT change anything else.
|
|
5180
|
+
Output ONLY the file content, no markdown fences, no explanation.`,
|
|
5181
|
+
userPrompt: `Fix this file:
|
|
5182
|
+
|
|
5183
|
+
\`\`\`
|
|
5184
|
+
${content}
|
|
5185
|
+
\`\`\``,
|
|
5186
|
+
maxTokens: 4096,
|
|
5187
|
+
temperature: 0
|
|
5188
|
+
});
|
|
5189
|
+
if (!result.success || !result.content.trim()) {
|
|
5190
|
+
dispatch({ type: "DISMISS_FIX", id: fix.id });
|
|
5191
|
+
getOutputManager().nudge("Fix generation failed", "warning");
|
|
5192
|
+
return;
|
|
5193
|
+
}
|
|
5194
|
+
let fixedContent = result.content.trim();
|
|
5195
|
+
if (fixedContent.startsWith("```")) {
|
|
5196
|
+
fixedContent = fixedContent.replace(/^```\w*\n?/, "").replace(/\n?```$/, "");
|
|
5197
|
+
}
|
|
5198
|
+
await writeFile(fullPath, fixedContent, "utf-8");
|
|
5199
|
+
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-YSNN23D4.js");
|
|
5200
|
+
const goals = await getActiveGoals(projectPath);
|
|
5201
|
+
const matchedGoal = goals.find((g) => g.description === fix.goalDescription);
|
|
5202
|
+
if (matchedGoal) {
|
|
5203
|
+
await recordGoalViolationFixed(matchedGoal, fix.file, projectPath);
|
|
5204
|
+
}
|
|
5205
|
+
dispatch({ type: "FIX_APPLIED", id: fix.id });
|
|
5206
|
+
getOutputManager().nudge(`Fixed: ${fix.description} in ${fix.file.split("/").pop()}`, "info", fix.file, 8e3);
|
|
5207
|
+
} catch (error) {
|
|
5208
|
+
dispatch({ type: "DISMISS_FIX", id: fix.id });
|
|
5209
|
+
getOutputManager().nudge(`Fix failed: ${error}`, "warning");
|
|
5210
|
+
}
|
|
5211
|
+
}
|
|
4844
5212
|
function DashboardApp({ onReady }) {
|
|
4845
5213
|
const { state, dispatch } = useDashboard();
|
|
4846
5214
|
const { exit } = useApp();
|
|
@@ -4864,7 +5232,7 @@ function DashboardApp({ onReady }) {
|
|
|
4864
5232
|
const workDir = getWorkingDirectory(void 0, true);
|
|
4865
5233
|
await mkdir(getTrieDirectory(workDir), { recursive: true });
|
|
4866
5234
|
await writeFile(configPath, JSON.stringify(stateRef.current.agentConfig, null, 2), "utf-8");
|
|
4867
|
-
const { saveAutonomyConfig, loadAutonomyConfig } = await import("./autonomy-config-
|
|
5235
|
+
const { saveAutonomyConfig, loadAutonomyConfig } = await import("./autonomy-config-QA6ATWLJ.js");
|
|
4868
5236
|
const autonomy = await loadAutonomyConfig(workDir);
|
|
4869
5237
|
autonomy.aiWatcher = stateRef.current.agentConfig.aiWatcher;
|
|
4870
5238
|
await saveAutonomyConfig(workDir, autonomy);
|
|
@@ -4990,7 +5358,15 @@ function DashboardApp({ onReady }) {
|
|
|
4990
5358
|
}, 5e3);
|
|
4991
5359
|
return () => clearInterval(interval);
|
|
4992
5360
|
}, []);
|
|
4993
|
-
|
|
5361
|
+
const applyingFixIds = useRef2(/* @__PURE__ */ new Set());
|
|
5362
|
+
useEffect3(() => {
|
|
5363
|
+
const toApply = state.pendingFixes.filter((f) => f.status === "applying" && !applyingFixIds.current.has(f.id));
|
|
5364
|
+
for (const fix of toApply) {
|
|
5365
|
+
applyingFixIds.current.add(fix.id);
|
|
5366
|
+
void applyGoalFix(fix, dispatchRef.current);
|
|
5367
|
+
}
|
|
5368
|
+
}, [state.pendingFixes]);
|
|
5369
|
+
useInput9((input, key) => {
|
|
4994
5370
|
if (showConfig) return;
|
|
4995
5371
|
if (state.view === "goals" && state.goalsPanel.inputMode === "add") return;
|
|
4996
5372
|
if (state.view === "hypotheses" && state.hypothesesPanel.inputMode === "add") return;
|
|
@@ -5139,4 +5515,4 @@ export {
|
|
|
5139
5515
|
handleCheckpointTool,
|
|
5140
5516
|
InteractiveDashboard
|
|
5141
5517
|
};
|
|
5142
|
-
//# sourceMappingURL=chunk-
|
|
5518
|
+
//# sourceMappingURL=chunk-EWVU7QUG.js.map
|