@triedotdev/mcp 1.0.121 → 1.0.123
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/chat-store-HFOOWZYN.js +15 -0
- package/dist/{chunk-Y52SNUW5.js → chunk-4YJ6KLGI.js} +19 -4
- package/dist/{chunk-Y52SNUW5.js.map → chunk-4YJ6KLGI.js.map} +1 -1
- package/dist/{chunk-PPZYVTUO.js → chunk-6LD7OPJL.js} +5 -5
- package/dist/{chunk-5TQ7J7UI.js → chunk-B46FDUKR.js} +8 -8
- package/dist/{chunk-GPLRFTMB.js → chunk-CKT2A33R.js} +5 -6
- package/dist/chunk-CKT2A33R.js.map +1 -0
- package/dist/chunk-DFPVUMVE.js +347 -0
- package/dist/chunk-DFPVUMVE.js.map +1 -0
- package/dist/{chunk-FNW7Z7ZS.js → chunk-F4ZIAHTZ.js} +3 -3
- package/dist/{chunk-PRFHN2X6.js → chunk-K5EXATBF.js} +2 -2
- package/dist/{chunk-7BY2KVIN.js → chunk-QIS2VDJL.js} +680 -319
- package/dist/chunk-QIS2VDJL.js.map +1 -0
- package/dist/{chunk-IQBHPTV7.js → chunk-TRIJC5MW.js} +4 -4
- package/dist/{chunk-4BGAVEO6.js → chunk-UHMMANC2.js} +77 -338
- package/dist/chunk-UHMMANC2.js.map +1 -0
- package/dist/chunk-WS6OA7H6.js +266 -0
- package/dist/chunk-WS6OA7H6.js.map +1 -0
- package/dist/cli/main.js +6 -5
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +12 -10
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{goal-manager-JKTNFJQE.js → goal-manager-RREOIX6U.js} +6 -5
- package/dist/{goal-validator-RD6QBQJB.js → goal-validator-XYA364W3.js} +3 -2
- package/dist/{goal-validator-RD6QBQJB.js.map → goal-validator-XYA364W3.js.map} +1 -1
- package/dist/{guardian-agent-ITZIDNQD.js → guardian-agent-PTC6G37Q.js} +9 -8
- package/dist/{hypothesis-PEVD2IJR.js → hypothesis-WWDONGPU.js} +6 -5
- package/dist/hypothesis-WWDONGPU.js.map +1 -0
- package/dist/index.js +16 -14
- package/dist/index.js.map +1 -1
- package/dist/insight-store-F5KDBY5Y.js +22 -0
- package/dist/insight-store-F5KDBY5Y.js.map +1 -0
- package/dist/{terminal-spawn-2GU5KLPS.js → terminal-spawn-P5M5PHAV.js} +28 -6
- package/dist/terminal-spawn-P5M5PHAV.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-4BGAVEO6.js.map +0 -1
- package/dist/chunk-7BY2KVIN.js.map +0 -1
- package/dist/chunk-GPLRFTMB.js.map +0 -1
- package/dist/terminal-spawn-2GU5KLPS.js.map +0 -1
- /package/dist/{goal-manager-JKTNFJQE.js.map → chat-store-HFOOWZYN.js.map} +0 -0
- /package/dist/{chunk-PPZYVTUO.js.map → chunk-6LD7OPJL.js.map} +0 -0
- /package/dist/{chunk-5TQ7J7UI.js.map → chunk-B46FDUKR.js.map} +0 -0
- /package/dist/{chunk-FNW7Z7ZS.js.map → chunk-F4ZIAHTZ.js.map} +0 -0
- /package/dist/{chunk-PRFHN2X6.js.map → chunk-K5EXATBF.js.map} +0 -0
- /package/dist/{chunk-IQBHPTV7.js.map → chunk-TRIJC5MW.js.map} +0 -0
- /package/dist/{guardian-agent-ITZIDNQD.js.map → goal-manager-RREOIX6U.js.map} +0 -0
- /package/dist/{hypothesis-PEVD2IJR.js.map → guardian-agent-PTC6G37Q.js.map} +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGuardian
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-B46FDUKR.js";
|
|
4
|
+
import {
|
|
5
|
+
getChatStore
|
|
6
|
+
} from "./chunk-DFPVUMVE.js";
|
|
4
7
|
import {
|
|
5
8
|
LearningEngine,
|
|
6
9
|
exportToJson,
|
|
@@ -10,12 +13,12 @@ import {
|
|
|
10
13
|
perceiveCurrentChanges,
|
|
11
14
|
reasonAboutChangesHumanReadable,
|
|
12
15
|
saveCheckpoint
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-6LD7OPJL.js";
|
|
14
17
|
import {
|
|
15
18
|
TieredStorage,
|
|
16
19
|
findCrossProjectPatterns,
|
|
17
20
|
getStorage
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-F4ZIAHTZ.js";
|
|
19
22
|
import {
|
|
20
23
|
getKeyFromKeychain,
|
|
21
24
|
isAIAvailable,
|
|
@@ -24,7 +27,7 @@ import {
|
|
|
24
27
|
} from "./chunk-WRGSH5RT.js";
|
|
25
28
|
import {
|
|
26
29
|
getGuardianState
|
|
27
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-UHMMANC2.js";
|
|
28
31
|
import {
|
|
29
32
|
ContextGraph
|
|
30
33
|
} from "./chunk-55CBWOEZ.js";
|
|
@@ -288,11 +291,11 @@ var StreamingManager = class {
|
|
|
288
291
|
|
|
289
292
|
// src/cli/dashboard/index.ts
|
|
290
293
|
import { render } from "ink";
|
|
291
|
-
import
|
|
294
|
+
import React11 from "react";
|
|
292
295
|
|
|
293
296
|
// src/cli/dashboard/App.tsx
|
|
294
|
-
import { useState as useState2, useEffect as
|
|
295
|
-
import { Box as
|
|
297
|
+
import { useState as useState2, useEffect as useEffect5, useCallback as useCallback7, useRef as useRef2 } from "react";
|
|
298
|
+
import { Box as Box14, useInput as useInput10, useApp } from "ink";
|
|
296
299
|
|
|
297
300
|
// src/cli/dashboard/state.tsx
|
|
298
301
|
import React, { createContext, useContext, useReducer } from "react";
|
|
@@ -526,7 +529,7 @@ function dashboardReducer(state, action) {
|
|
|
526
529
|
(ni) => !existing.some((ei) => ei.message === ni.message && !ei.dismissed)
|
|
527
530
|
);
|
|
528
531
|
const merged = [...newOnes, ...existing].slice(0, 50);
|
|
529
|
-
console.
|
|
532
|
+
console.debug("[State] ADD_INSIGHTS:", {
|
|
530
533
|
newCount: newOnes.length,
|
|
531
534
|
existingCount: existing.length,
|
|
532
535
|
mergedCount: merged.length,
|
|
@@ -661,6 +664,27 @@ function dashboardReducer(state, action) {
|
|
|
661
664
|
}
|
|
662
665
|
case "SET_CHAT_LOADING":
|
|
663
666
|
return { ...state, chatState: { ...state.chatState, loading: action.loading } };
|
|
667
|
+
case "SET_CHAT_SESSION":
|
|
668
|
+
return { ...state, chatState: { ...state.chatState, currentSessionId: action.sessionId, currentSessionTitle: action.title } };
|
|
669
|
+
case "LOAD_CHAT_MESSAGES":
|
|
670
|
+
return { ...state, chatState: { ...state.chatState, messages: action.messages } };
|
|
671
|
+
case "CLEAR_CHAT":
|
|
672
|
+
return { ...state, chatState: { messages: [], inputBuffer: "", loading: false, currentSessionId: null, currentSessionTitle: null } };
|
|
673
|
+
case "SET_CHAT_ARCHIVE_SESSIONS":
|
|
674
|
+
return { ...state, chatArchivePanel: { ...state.chatArchivePanel, sessions: action.sessions } };
|
|
675
|
+
case "SELECT_CHAT_SESSION": {
|
|
676
|
+
const sessions = state.chatArchivePanel.sessions;
|
|
677
|
+
const newIndex = Math.max(0, Math.min(action.index, sessions.length - 1));
|
|
678
|
+
return { ...state, chatArchivePanel: { ...state.chatArchivePanel, selectedIndex: newIndex } };
|
|
679
|
+
}
|
|
680
|
+
case "SET_CHAT_ARCHIVE_INPUT_MODE":
|
|
681
|
+
return { ...state, chatArchivePanel: { ...state.chatArchivePanel, inputMode: action.mode, inputBuffer: action.mode === "rename" ? state.chatArchivePanel.sessions[state.chatArchivePanel.selectedIndex]?.title || "" : "" } };
|
|
682
|
+
case "SET_CHAT_ARCHIVE_INPUT_BUFFER":
|
|
683
|
+
return { ...state, chatArchivePanel: { ...state.chatArchivePanel, inputBuffer: action.buffer } };
|
|
684
|
+
case "SET_CHAT_ARCHIVE_LOADING":
|
|
685
|
+
return { ...state, chatArchivePanel: { ...state.chatArchivePanel, loading: action.loading } };
|
|
686
|
+
case "TOGGLE_ARCHIVED_CHATS":
|
|
687
|
+
return { ...state, chatArchivePanel: { ...state.chatArchivePanel, showArchived: !state.chatArchivePanel.showArchived } };
|
|
664
688
|
case "SET_AGENT_CONFIG":
|
|
665
689
|
return { ...state, agentConfig: applyAgentConfigPatch(state.agentConfig, action.config) };
|
|
666
690
|
case "NAVIGATE_UP": {
|
|
@@ -789,7 +813,7 @@ function createInitialState() {
|
|
|
789
813
|
watch: { watching: false, directories: 0, recentChanges: [], filesScannedSession: 0 },
|
|
790
814
|
rawLog: [],
|
|
791
815
|
rawLogPage: 0,
|
|
792
|
-
scrollPositions: { overview: 0, rawlog: 0, agent: 0, goals: 0, hypotheses: 0, memory: 0, chat: 0 },
|
|
816
|
+
scrollPositions: { overview: 0, rawlog: 0, agent: 0, goals: 0, hypotheses: 0, memory: 0, chat: 0, "chat-archive": 0 },
|
|
793
817
|
notification: null,
|
|
794
818
|
notificationHistory: [],
|
|
795
819
|
agentInsights: [],
|
|
@@ -813,7 +837,8 @@ function createInitialState() {
|
|
|
813
837
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
814
838
|
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
815
839
|
agentBrain: { loaded: false, decisions: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
|
|
816
|
-
chatState: { messages: [], inputBuffer: "", loading: false },
|
|
840
|
+
chatState: { messages: [], inputBuffer: "", loading: false, currentSessionId: null, currentSessionTitle: null },
|
|
841
|
+
chatArchivePanel: { sessions: [], selectedIndex: 0, showArchived: false, loading: false, inputMode: "browse", inputBuffer: "" },
|
|
817
842
|
pendingFixes: [],
|
|
818
843
|
selectedFixIndex: 0
|
|
819
844
|
};
|
|
@@ -889,7 +914,8 @@ var VIEW_LABELS = {
|
|
|
889
914
|
goals: "Goals",
|
|
890
915
|
hypotheses: "Hypotheses",
|
|
891
916
|
memory: "Ledger",
|
|
892
|
-
chat: "Chat"
|
|
917
|
+
chat: "Chat",
|
|
918
|
+
"chat-archive": "History"
|
|
893
919
|
};
|
|
894
920
|
var VIEW_SHORT = {
|
|
895
921
|
overview: "Ovr",
|
|
@@ -898,24 +924,27 @@ var VIEW_SHORT = {
|
|
|
898
924
|
goals: "Gls",
|
|
899
925
|
hypotheses: "Hyp",
|
|
900
926
|
memory: "Ldg",
|
|
901
|
-
chat: "Cht"
|
|
927
|
+
chat: "Cht",
|
|
928
|
+
"chat-archive": "Hst"
|
|
902
929
|
};
|
|
903
930
|
var TAB_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
904
931
|
var CONTEXT_HINTS = {
|
|
905
|
-
goals: "
|
|
906
|
-
hypotheses: "
|
|
907
|
-
agent: "
|
|
908
|
-
memory: "
|
|
909
|
-
chat: "
|
|
910
|
-
|
|
932
|
+
goals: "/ help",
|
|
933
|
+
hypotheses: "/ help",
|
|
934
|
+
agent: "/ help",
|
|
935
|
+
memory: "/ help",
|
|
936
|
+
chat: "/ help",
|
|
937
|
+
"chat-archive": "/ help",
|
|
938
|
+
rawlog: "/ help"
|
|
911
939
|
};
|
|
912
940
|
var CONTEXT_HINTS_SHORT = {
|
|
913
|
-
goals: "
|
|
914
|
-
hypotheses: "
|
|
915
|
-
agent: "
|
|
916
|
-
memory: "
|
|
917
|
-
chat: "
|
|
918
|
-
|
|
941
|
+
goals: "/",
|
|
942
|
+
hypotheses: "/",
|
|
943
|
+
agent: "/",
|
|
944
|
+
memory: "/",
|
|
945
|
+
chat: "/",
|
|
946
|
+
"chat-archive": "/",
|
|
947
|
+
rawlog: "/"
|
|
919
948
|
};
|
|
920
949
|
function Footer() {
|
|
921
950
|
const { state } = useDashboard();
|
|
@@ -933,7 +962,7 @@ function Footer() {
|
|
|
933
962
|
hints = narrow ? "enter esc" : "enter save \xB7 esc cancel";
|
|
934
963
|
} else {
|
|
935
964
|
const hintMap = narrow ? CONTEXT_HINTS_SHORT : CONTEXT_HINTS;
|
|
936
|
-
hints = hintMap[view] || (narrow ? "
|
|
965
|
+
hints = hintMap[view] || (narrow ? "/" : "/ help");
|
|
937
966
|
}
|
|
938
967
|
if (veryNarrow) {
|
|
939
968
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
|
|
@@ -947,7 +976,7 @@ function Footer() {
|
|
|
947
976
|
" (",
|
|
948
977
|
unreadNudgesCount,
|
|
949
978
|
")"
|
|
950
|
-
] }) : /* @__PURE__ */ jsx3(Text2, {
|
|
979
|
+
] }) : /* @__PURE__ */ jsx3(Text2, { color: "green", children: labels[v] }),
|
|
951
980
|
!isLast && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: " \xB7 " })
|
|
952
981
|
] }, v);
|
|
953
982
|
}) }),
|
|
@@ -968,7 +997,7 @@ function Footer() {
|
|
|
968
997
|
" (",
|
|
969
998
|
unreadNudgesCount,
|
|
970
999
|
")"
|
|
971
|
-
] }) : /* @__PURE__ */ jsx3(Text2, {
|
|
1000
|
+
] }) : /* @__PURE__ */ jsx3(Text2, { color: "green", children: labels[v] }),
|
|
972
1001
|
!isLast && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: " \xB7 " })
|
|
973
1002
|
] }, v);
|
|
974
1003
|
}) }),
|
|
@@ -1304,9 +1333,24 @@ var VIEW_HELP = {
|
|
|
1304
1333
|
{ key: "type", description: "Enter message" },
|
|
1305
1334
|
{ key: "enter", description: "Send message" },
|
|
1306
1335
|
{ key: "esc", description: "Clear input" },
|
|
1336
|
+
{ key: "h", description: "Open chat history" },
|
|
1307
1337
|
{ key: "tab", description: "Navigate between views" },
|
|
1308
1338
|
{ key: "q", description: "Quit (press twice if input active)" }
|
|
1309
1339
|
],
|
|
1340
|
+
"chat-archive": [
|
|
1341
|
+
{ key: "j / \u2193", description: "Move down" },
|
|
1342
|
+
{ key: "k / \u2191", description: "Move up" },
|
|
1343
|
+
{ key: "enter", description: "Load selected chat" },
|
|
1344
|
+
{ key: "n", description: "Start new chat" },
|
|
1345
|
+
{ key: "d", description: "Delete selected chat" },
|
|
1346
|
+
{ key: "a", description: "Archive selected chat" },
|
|
1347
|
+
{ key: "r", description: "Rename selected chat" },
|
|
1348
|
+
{ key: "e", description: "Export selected chat" },
|
|
1349
|
+
{ key: "t", description: "Toggle archived chats" },
|
|
1350
|
+
{ key: "tab", description: "Navigate between views" },
|
|
1351
|
+
{ key: "s", description: "Open Settings" },
|
|
1352
|
+
{ key: "q / esc", description: "Quit" }
|
|
1353
|
+
],
|
|
1310
1354
|
rawlog: [
|
|
1311
1355
|
{ key: "n", description: "Next page" },
|
|
1312
1356
|
{ key: "p", description: "Previous page" },
|
|
@@ -1316,7 +1360,7 @@ var VIEW_HELP = {
|
|
|
1316
1360
|
{ key: "q / esc", description: "Quit" }
|
|
1317
1361
|
]
|
|
1318
1362
|
};
|
|
1319
|
-
function HelpDialog({ view
|
|
1363
|
+
function HelpDialog({ view }) {
|
|
1320
1364
|
const shortcuts = VIEW_HELP[view] || VIEW_HELP.overview;
|
|
1321
1365
|
const viewName = view.charAt(0).toUpperCase() + view.slice(1);
|
|
1322
1366
|
return /* @__PURE__ */ jsxs5(
|
|
@@ -1531,7 +1575,7 @@ function AgentView() {
|
|
|
1531
1575
|
const { decisions, patterns, loaded } = agentBrain;
|
|
1532
1576
|
useEffect(() => {
|
|
1533
1577
|
if (agentInsights.length > 0 || visibleInsights.length > 0) {
|
|
1534
|
-
console.
|
|
1578
|
+
console.debug("[AgentView Debug]", {
|
|
1535
1579
|
totalInsights: agentInsights.length,
|
|
1536
1580
|
visibleInsights: visibleInsights.length,
|
|
1537
1581
|
alerts: alerts.length,
|
|
@@ -1565,11 +1609,25 @@ function AgentView() {
|
|
|
1565
1609
|
dispatch({ type: "MARK_NUDGES_READ" });
|
|
1566
1610
|
}
|
|
1567
1611
|
}, [dispatch, state.unreadNudgesCount]);
|
|
1612
|
+
const dismissInsight = useCallback(async () => {
|
|
1613
|
+
const visible = getVisibleInsights(state);
|
|
1614
|
+
const insight = visible[selectedInsight];
|
|
1615
|
+
if (!insight) return;
|
|
1616
|
+
try {
|
|
1617
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1618
|
+
const { getInsightStore } = await import("./insight-store-F5KDBY5Y.js");
|
|
1619
|
+
const store = getInsightStore(workDir);
|
|
1620
|
+
await store.dismissInsight(insight.id);
|
|
1621
|
+
} catch (error) {
|
|
1622
|
+
console.error("Failed to persist insight dismissal:", error);
|
|
1623
|
+
}
|
|
1624
|
+
dispatch({ type: "DISMISS_INSIGHT", index: selectedInsight });
|
|
1625
|
+
}, [selectedInsight, state, dispatch]);
|
|
1568
1626
|
useInput3((input, key) => {
|
|
1569
1627
|
if (key.upArrow || input === "k") dispatch({ type: "NAVIGATE_UP" });
|
|
1570
1628
|
else if (key.downArrow || input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
1571
1629
|
else if (key.return) dispatch({ type: "TOGGLE_INSIGHT", index: selectedInsight });
|
|
1572
|
-
else if (input === "d")
|
|
1630
|
+
else if (input === "d") void dismissInsight();
|
|
1573
1631
|
});
|
|
1574
1632
|
const alertCount = alerts.length;
|
|
1575
1633
|
const decCount = decisions.length;
|
|
@@ -1797,7 +1855,7 @@ function GoalsView() {
|
|
|
1797
1855
|
return;
|
|
1798
1856
|
}
|
|
1799
1857
|
for (const goal of achieved) {
|
|
1800
|
-
await agentState.
|
|
1858
|
+
await agentState.updateGoal(goal.id, { status: "rejected" });
|
|
1801
1859
|
}
|
|
1802
1860
|
dispatch({ type: "SHOW_NOTIFICATION", message: `Cleared ${achieved.length} achieved goal${achieved.length > 1 ? "s" : ""}`, severity: "info", autoHideMs: 3e3 });
|
|
1803
1861
|
dispatch({ type: "ADD_ACTIVITY", message: `Cleared ${achieved.length} achieved goal${achieved.length > 1 ? "s" : ""}` });
|
|
@@ -1814,7 +1872,7 @@ function GoalsView() {
|
|
|
1814
1872
|
if (!goal) return;
|
|
1815
1873
|
dispatch({ type: "ADD_ACTIVITY", message: `Checking goal: ${goal.description.slice(0, 30)}...` });
|
|
1816
1874
|
dispatch({ type: "SHOW_NOTIFICATION", message: `Scanning files for violations...`, severity: "info", autoHideMs: 3e3 });
|
|
1817
|
-
const { checkFilesForGoalViolations } = await import("./goal-validator-
|
|
1875
|
+
const { checkFilesForGoalViolations } = await import("./goal-validator-XYA364W3.js");
|
|
1818
1876
|
const violations = await checkFilesForGoalViolations([goal], workDir);
|
|
1819
1877
|
if (violations.length === 0) {
|
|
1820
1878
|
dispatch({ type: "SHOW_NOTIFICATION", message: `\u2713 No violations found for: ${goal.description.slice(0, 40)}`, severity: "info", autoHideMs: 5e3 });
|
|
@@ -1826,13 +1884,11 @@ function GoalsView() {
|
|
|
1826
1884
|
dispatch({ type: "ADD_INSIGHTS", insights: [{
|
|
1827
1885
|
id: `scan-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
1828
1886
|
message: violation.message,
|
|
1829
|
-
severity: violation.severity,
|
|
1830
1887
|
timestamp: Date.now(),
|
|
1831
|
-
category: "
|
|
1888
|
+
category: "quality",
|
|
1832
1889
|
type: "warning",
|
|
1833
1890
|
dismissed: false,
|
|
1834
1891
|
priority: violation.severity === "critical" ? 9 : 6,
|
|
1835
|
-
file: violation.file,
|
|
1836
1892
|
relatedIssues: []
|
|
1837
1893
|
}] });
|
|
1838
1894
|
}
|
|
@@ -2013,7 +2069,7 @@ function HypothesesView() {
|
|
|
2013
2069
|
if (!hypo) return;
|
|
2014
2070
|
dispatch({ type: "ADD_ACTIVITY", message: `Testing hypothesis: ${hypo.statement.slice(0, 30)}...` });
|
|
2015
2071
|
dispatch({ type: "SHOW_NOTIFICATION", message: `Gathering evidence for hypothesis...`, severity: "info", autoHideMs: 3e3 });
|
|
2016
|
-
const { gatherEvidenceForHypothesis } = await import("./hypothesis-
|
|
2072
|
+
const { gatherEvidenceForHypothesis } = await import("./hypothesis-WWDONGPU.js");
|
|
2017
2073
|
const evidence = await gatherEvidenceForHypothesis(hypoId, workDir);
|
|
2018
2074
|
if (evidence.length === 0) {
|
|
2019
2075
|
dispatch({ type: "SHOW_NOTIFICATION", message: `No evidence found for: ${hypo.statement.slice(0, 40)}`, severity: "info", autoHideMs: 5e3 });
|
|
@@ -2361,7 +2417,7 @@ function RawLogView() {
|
|
|
2361
2417
|
}
|
|
2362
2418
|
|
|
2363
2419
|
// src/cli/dashboard/views/ChatView.tsx
|
|
2364
|
-
import { useCallback as useCallback5, useRef } from "react";
|
|
2420
|
+
import { useCallback as useCallback5, useRef, useEffect as useEffect3 } from "react";
|
|
2365
2421
|
import { Box as Box12, Text as Text12, useInput as useInput8 } from "ink";
|
|
2366
2422
|
|
|
2367
2423
|
// src/tools/tell.ts
|
|
@@ -2833,34 +2889,35 @@ var ExtractionPipeline = class {
|
|
|
2833
2889
|
* Process raw content through the entire pipeline
|
|
2834
2890
|
*/
|
|
2835
2891
|
async process(content, context) {
|
|
2836
|
-
|
|
2892
|
+
const outputManager = getOutputManager();
|
|
2893
|
+
outputManager.debug("Extracting signals from content...");
|
|
2837
2894
|
let extractedSignal = await this.extractor.extract(content, context.sourceType, context.sourceId);
|
|
2838
2895
|
extractedSignal = this.addIds(extractedSignal, context);
|
|
2839
|
-
|
|
2840
|
-
|
|
2896
|
+
outputManager.debug(`Extracted ${extractedSignal.decisions.length} decisions, ${extractedSignal.facts.length} facts, ${extractedSignal.blockers.length} blockers, ${extractedSignal.questions.length} questions`);
|
|
2897
|
+
outputManager.debug("Enriching with metadata...");
|
|
2841
2898
|
const { metadata: enrichedMeta } = await this.enricher.enrichSignal(extractedSignal, {
|
|
2842
2899
|
workingDirectory: this.workDir
|
|
2843
2900
|
});
|
|
2844
2901
|
if (enrichedMeta.expandedTags.length > 0) {
|
|
2845
|
-
|
|
2902
|
+
outputManager.debug(`Expanded tags: ${enrichedMeta.expandedTags.slice(0, 5).join(", ")}${enrichedMeta.expandedTags.length > 5 ? "..." : ""}`);
|
|
2846
2903
|
}
|
|
2847
2904
|
if (enrichedMeta.dependencies.length > 0) {
|
|
2848
|
-
|
|
2905
|
+
outputManager.debug(`Dependencies: ${enrichedMeta.dependencies.join(", ")}`);
|
|
2849
2906
|
}
|
|
2850
2907
|
if (enrichedMeta.codebaseArea.length > 0) {
|
|
2851
|
-
|
|
2908
|
+
outputManager.debug(`Codebase areas: ${enrichedMeta.codebaseArea.join(", ")}`);
|
|
2852
2909
|
}
|
|
2853
2910
|
if (enrichedMeta.domain.length > 0) {
|
|
2854
|
-
|
|
2911
|
+
outputManager.debug(`Domains: ${enrichedMeta.domain.join(", ")}`);
|
|
2855
2912
|
}
|
|
2856
|
-
|
|
2913
|
+
outputManager.debug("Storing in decision ledger...");
|
|
2857
2914
|
await this.storage.storeSignal(extractedSignal, {
|
|
2858
2915
|
expandedTags: enrichedMeta.expandedTags,
|
|
2859
2916
|
dependencies: enrichedMeta.dependencies,
|
|
2860
2917
|
codebaseArea: enrichedMeta.codebaseArea,
|
|
2861
2918
|
domain: enrichedMeta.domain
|
|
2862
2919
|
});
|
|
2863
|
-
|
|
2920
|
+
outputManager.debug("Successfully stored in decision ledger");
|
|
2864
2921
|
return extractedSignal;
|
|
2865
2922
|
}
|
|
2866
2923
|
/**
|
|
@@ -4892,7 +4949,7 @@ var CHAT_TOOLS = [
|
|
|
4892
4949
|
},
|
|
4893
4950
|
{
|
|
4894
4951
|
name: "trie_search_files",
|
|
4895
|
-
description: "Search source code files for text patterns
|
|
4952
|
+
description: "Search source code files for text patterns using ripgrep. Note: Requires ripgrep to be installed. For emoji detection, use trie_scan_for_goal_violations instead.",
|
|
4896
4953
|
input_schema: {
|
|
4897
4954
|
type: "object",
|
|
4898
4955
|
properties: {
|
|
@@ -4911,171 +4968,185 @@ var CHAT_TOOLS = [
|
|
|
4911
4968
|
},
|
|
4912
4969
|
required: ["pattern"]
|
|
4913
4970
|
}
|
|
4971
|
+
},
|
|
4972
|
+
{
|
|
4973
|
+
name: "trie_scan_for_goal_violations",
|
|
4974
|
+
description: "Run an AI-powered scan to check for goal violations across the codebase. This is the most reliable way to detect issues like emojis, as it uses AI analysis rather than pattern matching.",
|
|
4975
|
+
input_schema: {
|
|
4976
|
+
type: "object",
|
|
4977
|
+
properties: {
|
|
4978
|
+
goalId: {
|
|
4979
|
+
type: "string",
|
|
4980
|
+
description: "Optional: Specific goal ID to check. If omitted, checks all active goals."
|
|
4981
|
+
}
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4914
4984
|
}
|
|
4915
4985
|
];
|
|
4916
4986
|
async function executeTool(name, input) {
|
|
4917
4987
|
const directory = getWorkingDirectory(void 0, true);
|
|
4918
4988
|
const withDir = { ...input, directory };
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
case "trie_feedback": {
|
|
4926
|
-
const tool = new TrieFeedbackTool();
|
|
4927
|
-
const result = await tool.execute(withDir);
|
|
4928
|
-
return textFromResult(result);
|
|
4929
|
-
}
|
|
4930
|
-
case "trie_check": {
|
|
4931
|
-
const tool = new TrieCheckTool();
|
|
4932
|
-
const result = await tool.execute(withDir);
|
|
4933
|
-
return textFromResult(result);
|
|
4934
|
-
}
|
|
4935
|
-
case "trie_explain": {
|
|
4936
|
-
const tool = new TrieExplainTool();
|
|
4937
|
-
const result = await tool.execute(input);
|
|
4938
|
-
return textFromResult(result);
|
|
4939
|
-
}
|
|
4940
|
-
case "trie_get_decisions": {
|
|
4941
|
-
const tool = new TrieGetDecisionsTool();
|
|
4942
|
-
const result = await tool.execute(withDir);
|
|
4943
|
-
return textFromResult(result);
|
|
4944
|
-
}
|
|
4945
|
-
case "trie_get_blockers": {
|
|
4946
|
-
const tool = new TrieGetBlockersTool();
|
|
4947
|
-
const result = await tool.execute(withDir);
|
|
4948
|
-
return textFromResult(result);
|
|
4949
|
-
}
|
|
4950
|
-
case "trie_query_context": {
|
|
4951
|
-
const tool = new TrieQueryContextTool();
|
|
4952
|
-
const result = await tool.execute(withDir);
|
|
4953
|
-
return textFromResult(result);
|
|
4954
|
-
}
|
|
4955
|
-
case "trie_checkpoint": {
|
|
4956
|
-
const result = await handleCheckpointTool(input);
|
|
4957
|
-
return result;
|
|
4958
|
-
}
|
|
4959
|
-
case "trie_add_goal": {
|
|
4960
|
-
const desc = String(input.description || "").trim();
|
|
4961
|
-
if (!desc) return "Goal description is required.";
|
|
4962
|
-
const category = input.category || "general";
|
|
4963
|
-
const agentState = getGuardianState(directory);
|
|
4964
|
-
await agentState.load();
|
|
4965
|
-
const goal = {
|
|
4966
|
-
id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
4967
|
-
description: desc,
|
|
4968
|
-
type: "custom",
|
|
4969
|
-
metric: "progress",
|
|
4970
|
-
target: 100,
|
|
4971
|
-
currentValue: 0,
|
|
4972
|
-
startValue: 0,
|
|
4973
|
-
status: "active",
|
|
4974
|
-
autoGenerated: false,
|
|
4975
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4976
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4977
|
-
deadline: new Date(Date.now() + 14 * 864e5).toISOString(),
|
|
4978
|
-
category
|
|
4979
|
-
};
|
|
4980
|
-
await agentState.addGoal(goal);
|
|
4981
|
-
return `Goal created: "${desc}" [${category}]`;
|
|
4982
|
-
}
|
|
4983
|
-
case "trie_add_hypothesis": {
|
|
4984
|
-
const stmt = String(input.statement || "").trim();
|
|
4985
|
-
if (!stmt) return "Hypothesis statement is required.";
|
|
4986
|
-
const category = input.category || "general";
|
|
4987
|
-
const agentState = getGuardianState(directory);
|
|
4988
|
-
await agentState.load();
|
|
4989
|
-
const hypothesis = {
|
|
4990
|
-
id: `hyp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
4991
|
-
statement: stmt,
|
|
4992
|
-
confidence: 0.5,
|
|
4993
|
-
status: "proposed",
|
|
4994
|
-
evidence: [],
|
|
4995
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4996
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4997
|
-
testCriteria: String(input.test_criteria || "Collect evidence from scans"),
|
|
4998
|
-
category
|
|
4999
|
-
};
|
|
5000
|
-
await agentState.addHypothesis(hypothesis);
|
|
5001
|
-
return `Hypothesis created: "${stmt}" [${category}]`;
|
|
5002
|
-
}
|
|
5003
|
-
case "trie_delete_incident": {
|
|
5004
|
-
const search = String(input.search || "").trim().toLowerCase();
|
|
5005
|
-
if (!search) return "Search text is required to find the incident.";
|
|
5006
|
-
const graph = new ContextGraph(directory);
|
|
5007
|
-
const nodes = await graph.listNodes();
|
|
5008
|
-
const incidents = nodes.filter(
|
|
5009
|
-
(n) => n.type === "incident" && n.data.description?.toLowerCase().includes(search)
|
|
5010
|
-
);
|
|
5011
|
-
if (incidents.length === 0) return `No incidents found matching "${search}".`;
|
|
5012
|
-
for (const inc of incidents) {
|
|
5013
|
-
await graph.deleteNode("incident", inc.id);
|
|
4989
|
+
try {
|
|
4990
|
+
switch (name) {
|
|
4991
|
+
case "trie_tell": {
|
|
4992
|
+
const tool = new TrieTellTool();
|
|
4993
|
+
const result = await tool.execute(withDir);
|
|
4994
|
+
return textFromResult(result);
|
|
5014
4995
|
}
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
4996
|
+
case "trie_feedback": {
|
|
4997
|
+
const tool = new TrieFeedbackTool();
|
|
4998
|
+
const result = await tool.execute(withDir);
|
|
4999
|
+
return textFromResult(result);
|
|
5000
|
+
}
|
|
5001
|
+
case "trie_check": {
|
|
5002
|
+
const tool = new TrieCheckTool();
|
|
5003
|
+
const result = await tool.execute(withDir);
|
|
5004
|
+
return textFromResult(result);
|
|
5005
|
+
}
|
|
5006
|
+
case "trie_explain": {
|
|
5007
|
+
const tool = new TrieExplainTool();
|
|
5008
|
+
const result = await tool.execute(withDir);
|
|
5009
|
+
return textFromResult(result);
|
|
5010
|
+
}
|
|
5011
|
+
case "trie_get_decisions": {
|
|
5012
|
+
const tool = new TrieGetDecisionsTool();
|
|
5013
|
+
const result = await tool.execute(withDir);
|
|
5014
|
+
return textFromResult(result);
|
|
5015
|
+
}
|
|
5016
|
+
case "trie_get_blockers": {
|
|
5017
|
+
const tool = new TrieGetBlockersTool();
|
|
5018
|
+
const result = await tool.execute(withDir);
|
|
5019
|
+
return textFromResult(result);
|
|
5020
|
+
}
|
|
5021
|
+
case "trie_query_context": {
|
|
5022
|
+
const tool = new TrieQueryContextTool();
|
|
5023
|
+
const result = await tool.execute(withDir);
|
|
5024
|
+
return textFromResult(result);
|
|
5025
|
+
}
|
|
5026
|
+
case "trie_checkpoint": {
|
|
5027
|
+
const result = await handleCheckpointTool(input);
|
|
5028
|
+
return result;
|
|
5029
|
+
}
|
|
5030
|
+
case "trie_add_goal": {
|
|
5031
|
+
const desc = String(input.description || "").trim();
|
|
5032
|
+
if (!desc) return "Goal description is required.";
|
|
5033
|
+
const category = input.category || "general";
|
|
5034
|
+
const agentState = getGuardianState(directory);
|
|
5035
|
+
await agentState.load();
|
|
5036
|
+
const goal = {
|
|
5037
|
+
id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
5038
|
+
description: desc,
|
|
5039
|
+
type: "custom",
|
|
5040
|
+
metric: "progress",
|
|
5041
|
+
target: 100,
|
|
5042
|
+
currentValue: 0,
|
|
5043
|
+
startValue: 0,
|
|
5044
|
+
status: "active",
|
|
5045
|
+
autoGenerated: false,
|
|
5046
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5047
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5048
|
+
deadline: new Date(Date.now() + 14 * 864e5).toISOString(),
|
|
5049
|
+
category
|
|
5050
|
+
};
|
|
5051
|
+
await agentState.addGoal(goal);
|
|
5052
|
+
return `Goal created: "${desc}" [${category}]`;
|
|
5053
|
+
}
|
|
5054
|
+
case "trie_add_hypothesis": {
|
|
5055
|
+
const stmt = String(input.statement || "").trim();
|
|
5056
|
+
if (!stmt) return "Hypothesis statement is required.";
|
|
5057
|
+
const category = input.category || "general";
|
|
5058
|
+
const agentState = getGuardianState(directory);
|
|
5059
|
+
await agentState.load();
|
|
5060
|
+
const hypothesis = {
|
|
5061
|
+
id: `hyp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
5062
|
+
statement: stmt,
|
|
5063
|
+
confidence: 0.5,
|
|
5064
|
+
status: "proposed",
|
|
5065
|
+
evidence: [],
|
|
5066
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5067
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5068
|
+
testCriteria: String(input.test_criteria || "Collect evidence from scans"),
|
|
5069
|
+
category
|
|
5070
|
+
};
|
|
5071
|
+
await agentState.addHypothesis(hypothesis);
|
|
5072
|
+
return `Hypothesis created: "${stmt}" [${category}]`;
|
|
5073
|
+
}
|
|
5074
|
+
case "trie_delete_incident": {
|
|
5075
|
+
const search = String(input.search || "").trim().toLowerCase();
|
|
5076
|
+
if (!search) return "Search text is required to find the incident.";
|
|
5077
|
+
const graph = new ContextGraph(directory);
|
|
5078
|
+
const nodes = await graph.listNodes();
|
|
5079
|
+
const incidents = nodes.filter(
|
|
5080
|
+
(n) => n.type === "incident" && n.data.description?.toLowerCase().includes(search)
|
|
5081
|
+
);
|
|
5082
|
+
if (incidents.length === 0) return `No incidents found matching "${search}".`;
|
|
5083
|
+
for (const inc of incidents) {
|
|
5084
|
+
await graph.deleteNode("incident", inc.id);
|
|
5051
5085
|
}
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5086
|
+
await exportToJson(graph);
|
|
5087
|
+
const descs = incidents.map((i) => `"${i.data.description.slice(0, 60)}"`);
|
|
5088
|
+
return `Deleted ${incidents.length} incident(s): ${descs.join(", ")}`;
|
|
5089
|
+
}
|
|
5090
|
+
case "trie_add_decision": {
|
|
5091
|
+
const dec = String(input.decision || "").trim();
|
|
5092
|
+
const ctx = String(input.context || "").trim();
|
|
5093
|
+
if (!dec) return "Decision text is required.";
|
|
5094
|
+
if (!ctx) return "Decision context is required.";
|
|
5095
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5096
|
+
const id = `dec-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
5097
|
+
const hash = createHash("sha256").update(`${dec}|${ctx}|${now}`).digest("hex").slice(0, 16);
|
|
5098
|
+
const files = Array.isArray(input.files) ? input.files.map(String) : [];
|
|
5099
|
+
const tags = Array.isArray(input.tags) ? input.tags.map(String) : [];
|
|
5100
|
+
const reasoningStr = input.reasoning ? String(input.reasoning) : null;
|
|
5101
|
+
const decisionObj = {
|
|
5102
|
+
id,
|
|
5103
|
+
decision: dec,
|
|
5104
|
+
context: ctx,
|
|
5105
|
+
when: now,
|
|
5106
|
+
who: "user",
|
|
5107
|
+
files,
|
|
5108
|
+
tags,
|
|
5109
|
+
status: "active",
|
|
5110
|
+
hash,
|
|
5111
|
+
...reasoningStr ? { reasoning: reasoningStr } : {}
|
|
5112
|
+
};
|
|
5113
|
+
const storage = new TieredStorage(directory);
|
|
5114
|
+
await storage.storeSignal({
|
|
5115
|
+
decisions: [decisionObj],
|
|
5116
|
+
facts: [],
|
|
5117
|
+
blockers: [],
|
|
5118
|
+
questions: [],
|
|
5119
|
+
metadata: {
|
|
5120
|
+
extractedAt: now,
|
|
5121
|
+
sourceType: "conversation"
|
|
5122
|
+
}
|
|
5123
|
+
});
|
|
5124
|
+
const graph = new ContextGraph(directory);
|
|
5125
|
+
await graph.addNode("decision", {
|
|
5126
|
+
context: ctx,
|
|
5127
|
+
decision: dec,
|
|
5128
|
+
reasoning: reasoningStr,
|
|
5129
|
+
outcome: "unknown",
|
|
5130
|
+
timestamp: now
|
|
5131
|
+
});
|
|
5132
|
+
return `Decision recorded [${hash}]: "${dec}"`;
|
|
5133
|
+
}
|
|
5134
|
+
case "trie_propose_fix": {
|
|
5135
|
+
const file = String(input.file || "").trim();
|
|
5136
|
+
const goal = String(input.goal || "").trim();
|
|
5137
|
+
const violation = String(input.violation || "").trim();
|
|
5138
|
+
const suggestedFix = input.suggestedFix ? String(input.suggestedFix) : void 0;
|
|
5139
|
+
if (!file) return "File path is required.";
|
|
5140
|
+
if (!goal) return "Goal description is required.";
|
|
5141
|
+
if (!violation) return "Violation description is required.";
|
|
5142
|
+
const fixProposal = {
|
|
5143
|
+
file,
|
|
5144
|
+
goal,
|
|
5145
|
+
violation,
|
|
5146
|
+
suggestedFix,
|
|
5147
|
+
directory
|
|
5148
|
+
};
|
|
5149
|
+
return `I found a violation to fix:
|
|
5079
5150
|
|
|
5080
5151
|
\u{1F4C1} File: ${file}
|
|
5081
5152
|
\u{1F3AF} Goal: ${goal}
|
|
@@ -5087,76 +5158,111 @@ Would you like me to spawn Claude Code to fix this?
|
|
|
5087
5158
|
Type "yes" to proceed, or "no" to cancel.
|
|
5088
5159
|
|
|
5089
5160
|
[PENDING_FIX:${JSON.stringify(fixProposal)}]`;
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5161
|
+
}
|
|
5162
|
+
case "trie_search_files": {
|
|
5163
|
+
const pattern = String(input.pattern || "").trim();
|
|
5164
|
+
const filePattern = input.filePattern ? String(input.filePattern).trim() : void 0;
|
|
5165
|
+
const contextLines = typeof input.contextLines === "number" ? input.contextLines : 2;
|
|
5166
|
+
if (!pattern) return "Search pattern is required.";
|
|
5167
|
+
const { spawnSync } = await import("child_process");
|
|
5168
|
+
try {
|
|
5169
|
+
const rgArgs = [
|
|
5170
|
+
"--context",
|
|
5171
|
+
String(contextLines),
|
|
5172
|
+
"--heading",
|
|
5173
|
+
"--line-number",
|
|
5174
|
+
"--color=never",
|
|
5175
|
+
"--max-count",
|
|
5176
|
+
"50"
|
|
5177
|
+
// Limit matches per file
|
|
5178
|
+
];
|
|
5179
|
+
if (filePattern) {
|
|
5180
|
+
rgArgs.push("--glob", filePattern);
|
|
5181
|
+
}
|
|
5182
|
+
rgArgs.push(
|
|
5183
|
+
"--glob",
|
|
5184
|
+
"!node_modules/**",
|
|
5185
|
+
"--glob",
|
|
5186
|
+
"!.git/**",
|
|
5187
|
+
"--glob",
|
|
5188
|
+
"!dist/**",
|
|
5189
|
+
"--glob",
|
|
5190
|
+
"!build/**",
|
|
5191
|
+
"--glob",
|
|
5192
|
+
"!coverage/**"
|
|
5193
|
+
);
|
|
5194
|
+
rgArgs.push(pattern, directory);
|
|
5195
|
+
const result = spawnSync("rg", rgArgs, {
|
|
5196
|
+
encoding: "utf-8",
|
|
5197
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
5198
|
+
// 10MB
|
|
5199
|
+
cwd: directory
|
|
5200
|
+
});
|
|
5201
|
+
if (result.error) {
|
|
5202
|
+
if (result.error.code === "ENOENT") {
|
|
5203
|
+
return `Error: ripgrep (rg) not found. Please install it:
|
|
5133
5204
|
brew install ripgrep (macOS)
|
|
5134
5205
|
apt install ripgrep (Ubuntu)
|
|
5135
|
-
Or
|
|
5206
|
+
Or use trie_scan_for_goal_violations for AI-powered analysis instead.`;
|
|
5207
|
+
}
|
|
5208
|
+
return `Search failed: ${result.error.message}`;
|
|
5136
5209
|
}
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
const output = result.stdout;
|
|
5147
|
-
const truncated = output.length > maxLength ? output.slice(0, maxLength) + `
|
|
5210
|
+
if (result.status === 1 || !result.stdout || !result.stdout.trim()) {
|
|
5211
|
+
return `No matches found for pattern: ${pattern}`;
|
|
5212
|
+
}
|
|
5213
|
+
if (result.status === 2) {
|
|
5214
|
+
return `Search error: ${result.stderr || "Unknown error"}`;
|
|
5215
|
+
}
|
|
5216
|
+
const maxLength = 5e3;
|
|
5217
|
+
const output = result.stdout;
|
|
5218
|
+
const truncated = output.length > maxLength ? output.slice(0, maxLength) + `
|
|
5148
5219
|
|
|
5149
5220
|
... (truncated, ${output.length - maxLength} more characters)` : output;
|
|
5150
|
-
|
|
5151
|
-
|
|
5221
|
+
const matchCount = (output.match(/^\d+:/gm) || []).length;
|
|
5222
|
+
return `Found ${matchCount} match(es) for "${pattern}":
|
|
5152
5223
|
|
|
5153
5224
|
${truncated}`;
|
|
5154
|
-
|
|
5155
|
-
|
|
5225
|
+
} catch (error) {
|
|
5226
|
+
return `Search failed: ${error.message}`;
|
|
5227
|
+
}
|
|
5156
5228
|
}
|
|
5229
|
+
case "trie_scan_for_goal_violations": {
|
|
5230
|
+
const goalId = input.goalId ? String(input.goalId).trim() : void 0;
|
|
5231
|
+
try {
|
|
5232
|
+
const { checkFilesForGoalViolations, getActiveGoals } = await import("./goal-validator-XYA364W3.js");
|
|
5233
|
+
const agentState = getGuardianState(directory);
|
|
5234
|
+
await agentState.load();
|
|
5235
|
+
const allGoals = await getActiveGoals(directory);
|
|
5236
|
+
const goalsToCheck = goalId ? allGoals.filter((g) => g.id === goalId) : allGoals;
|
|
5237
|
+
if (goalsToCheck.length === 0) {
|
|
5238
|
+
return goalId ? `No active goal found with ID: ${goalId}` : "No active goals to check. Add goals in the Goals view first.";
|
|
5239
|
+
}
|
|
5240
|
+
const violations = await checkFilesForGoalViolations(goalsToCheck, directory);
|
|
5241
|
+
if (violations.length === 0) {
|
|
5242
|
+
return `\u2713 Scan complete! No violations found for ${goalsToCheck.length} goal(s).`;
|
|
5243
|
+
}
|
|
5244
|
+
let result = `Found ${violations.length} violation(s):
|
|
5245
|
+
|
|
5246
|
+
`;
|
|
5247
|
+
for (const v of violations) {
|
|
5248
|
+
result += `\u26A0\uFE0F ${v.file}
|
|
5249
|
+
`;
|
|
5250
|
+
result += ` ${v.message}
|
|
5251
|
+
|
|
5252
|
+
`;
|
|
5253
|
+
}
|
|
5254
|
+
result += "These violations have been recorded and will appear in the Goals view.";
|
|
5255
|
+
return result;
|
|
5256
|
+
} catch (error) {
|
|
5257
|
+
return `Scan failed: ${error.message}`;
|
|
5258
|
+
}
|
|
5259
|
+
}
|
|
5260
|
+
default:
|
|
5261
|
+
return `Unknown tool: ${name}`;
|
|
5157
5262
|
}
|
|
5158
|
-
|
|
5159
|
-
|
|
5263
|
+
} catch (error) {
|
|
5264
|
+
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
5265
|
+
return `Tool execution failed: ${errorMsg}`;
|
|
5160
5266
|
}
|
|
5161
5267
|
}
|
|
5162
5268
|
|
|
@@ -5190,7 +5296,8 @@ async function buildContext(workDir, dashboardState) {
|
|
|
5190
5296
|
return `- "${g.description}" [${g.category || "general"}]${caughtCount > 0 ? ` - ${caughtCount} violation(s)${lastCaught}` : ""}`;
|
|
5191
5297
|
}).join("\n"));
|
|
5192
5298
|
}
|
|
5193
|
-
} catch {
|
|
5299
|
+
} catch (error) {
|
|
5300
|
+
console.error("Failed to load guardian state:", error);
|
|
5194
5301
|
}
|
|
5195
5302
|
try {
|
|
5196
5303
|
const storage = new TieredStorage(workDir);
|
|
@@ -5201,7 +5308,8 @@ async function buildContext(workDir, dashboardState) {
|
|
|
5201
5308
|
(d) => `- ${d.decision} (${d.when}${d.hash ? `, hash: ${d.hash.slice(0, 8)}` : ""})`
|
|
5202
5309
|
).join("\n"));
|
|
5203
5310
|
}
|
|
5204
|
-
} catch {
|
|
5311
|
+
} catch (error) {
|
|
5312
|
+
console.error("Failed to query decisions:", error);
|
|
5205
5313
|
}
|
|
5206
5314
|
try {
|
|
5207
5315
|
const blockers = await storage.queryBlockers({ limit: 5 });
|
|
@@ -5210,9 +5318,11 @@ async function buildContext(workDir, dashboardState) {
|
|
|
5210
5318
|
(b) => `- ${b.blocker} [${b.impact}]`
|
|
5211
5319
|
).join("\n"));
|
|
5212
5320
|
}
|
|
5213
|
-
} catch {
|
|
5321
|
+
} catch (error) {
|
|
5322
|
+
console.error("Failed to query blockers:", error);
|
|
5214
5323
|
}
|
|
5215
|
-
} catch {
|
|
5324
|
+
} catch (error) {
|
|
5325
|
+
console.error("Storage unavailable:", error);
|
|
5216
5326
|
}
|
|
5217
5327
|
try {
|
|
5218
5328
|
const graph = new ContextGraph(workDir);
|
|
@@ -5244,7 +5354,8 @@ async function buildContext(workDir, dashboardState) {
|
|
|
5244
5354
|
return `- ${d.description} (${Math.round(d.confidence * 100)}%${d.isAntiPattern ? ", anti-pattern" : ""})`;
|
|
5245
5355
|
}).join("\n"));
|
|
5246
5356
|
}
|
|
5247
|
-
} catch {
|
|
5357
|
+
} catch (error) {
|
|
5358
|
+
console.error("Context graph unavailable:", error);
|
|
5248
5359
|
}
|
|
5249
5360
|
return parts.length > 0 ? parts.join("\n\n") : "No context data available yet.";
|
|
5250
5361
|
}
|
|
@@ -5262,20 +5373,20 @@ var SYSTEM_PROMPT = `You are Trie, a code guardian assistant embedded in a termi
|
|
|
5262
5373
|
- Query stored decisions, blockers, facts, and questions from the decision ledger
|
|
5263
5374
|
- Create and manage goals and hypotheses
|
|
5264
5375
|
- Propose fixes for goal violations (requires user confirmation before spawning Claude Code)
|
|
5376
|
+
- Run AI-powered scans to detect goal violations across the entire codebase
|
|
5265
5377
|
- Save work checkpoints
|
|
5266
5378
|
|
|
5267
|
-
**IMPORTANT -
|
|
5268
|
-
- You have a
|
|
5269
|
-
-
|
|
5270
|
-
-
|
|
5271
|
-
-
|
|
5272
|
-
- Instead, suggest the user press 'r' in Goals view to run an AI-powered scan
|
|
5379
|
+
**IMPORTANT - Finding Code Issues:**
|
|
5380
|
+
- You have a trie_scan_for_goal_violations tool - use this to scan the codebase for goal violations
|
|
5381
|
+
- This is the BEST way to find emojis, TODOs, or other patterns that violate goals
|
|
5382
|
+
- It uses AI analysis and is much more reliable than regex pattern matching
|
|
5383
|
+
- You also have trie_search_files but it requires ripgrep (often not installed)
|
|
5273
5384
|
|
|
5274
|
-
**When user asks about code content:**
|
|
5385
|
+
**When user asks about code content (emojis, TODOs, etc.):**
|
|
5275
5386
|
1. First check the "Recent goal violations (nudges)" section in project context
|
|
5276
5387
|
2. If found, report what you see
|
|
5277
|
-
3. If not found
|
|
5278
|
-
4.
|
|
5388
|
+
3. If not found or user wants a full scan: Call trie_scan_for_goal_violations
|
|
5389
|
+
4. The scan will find all violations and update the Goals view automatically
|
|
5279
5390
|
|
|
5280
5391
|
**When user asks to fix violations:**
|
|
5281
5392
|
1. Look in "Recent goal violations (nudges)" section of project context
|
|
@@ -5284,16 +5395,39 @@ var SYSTEM_PROMPT = `You are Trie, a code guardian assistant embedded in a termi
|
|
|
5284
5395
|
4. Do NOT assume the user wants to proceed - always get confirmation first
|
|
5285
5396
|
|
|
5286
5397
|
Examples:
|
|
5287
|
-
- User: "do we have emojis?" \u2192 Check nudges first. If none
|
|
5398
|
+
- User: "do we have emojis?" \u2192 Check nudges first. If none or unclear: Call trie_scan_for_goal_violations to scan the codebase.
|
|
5399
|
+
- User: "run a full scan for emojis" \u2192 Call trie_scan_for_goal_violations directly.
|
|
5288
5400
|
- User: "fix the emoji violation" \u2192 Find emoji violation in nudges, call trie_propose_fix (will ask user to confirm)
|
|
5289
|
-
- User: "search for TODO comments" \u2192
|
|
5401
|
+
- User: "search for TODO comments" \u2192 If there's a goal about TODOs, use trie_scan_for_goal_violations. Otherwise explain no such goal exists.
|
|
5290
5402
|
|
|
5291
5403
|
Answer concisely. Reference specific files, decisions, and patterns when relevant.`;
|
|
5292
5404
|
function ChatView() {
|
|
5293
5405
|
const { state, dispatch } = useDashboard();
|
|
5294
5406
|
const { chatState } = state;
|
|
5295
|
-
const { messages, inputBuffer, loading } = chatState;
|
|
5407
|
+
const { messages, inputBuffer, loading, currentSessionId, currentSessionTitle } = chatState;
|
|
5296
5408
|
const loadingRef = useRef(false);
|
|
5409
|
+
useEffect3(() => {
|
|
5410
|
+
if (messages.length === 0) return;
|
|
5411
|
+
const saveChat = async () => {
|
|
5412
|
+
try {
|
|
5413
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5414
|
+
const { getChatStore: getChatStore2 } = await import("./chat-store-HFOOWZYN.js");
|
|
5415
|
+
const store = getChatStore2(workDir);
|
|
5416
|
+
const sessionId = await store.saveSession(
|
|
5417
|
+
messages,
|
|
5418
|
+
currentSessionId || void 0,
|
|
5419
|
+
currentSessionTitle || void 0
|
|
5420
|
+
);
|
|
5421
|
+
if (!currentSessionId) {
|
|
5422
|
+
dispatch({ type: "SET_CHAT_SESSION", sessionId, title: null });
|
|
5423
|
+
}
|
|
5424
|
+
} catch (error) {
|
|
5425
|
+
console.error("Failed to auto-save chat:", error);
|
|
5426
|
+
}
|
|
5427
|
+
};
|
|
5428
|
+
const timeout = setTimeout(() => void saveChat(), 2e3);
|
|
5429
|
+
return () => clearTimeout(timeout);
|
|
5430
|
+
}, [messages, currentSessionId, currentSessionTitle, dispatch]);
|
|
5297
5431
|
const sendMessage = useCallback5(async (question) => {
|
|
5298
5432
|
if (loadingRef.current) return;
|
|
5299
5433
|
loadingRef.current = true;
|
|
@@ -5306,9 +5440,12 @@ function ChatView() {
|
|
|
5306
5440
|
if (lastAssistantMessage?.pendingFix) {
|
|
5307
5441
|
const response = question.trim().toLowerCase();
|
|
5308
5442
|
if (response === "yes" || response === "y") {
|
|
5309
|
-
const { spawnClaudeCodeFix } = await import("./terminal-spawn-
|
|
5443
|
+
const { spawnClaudeCodeFix } = await import("./terminal-spawn-P5M5PHAV.js");
|
|
5310
5444
|
try {
|
|
5311
|
-
await spawnClaudeCodeFix(
|
|
5445
|
+
await spawnClaudeCodeFix({
|
|
5446
|
+
...lastAssistantMessage.pendingFix,
|
|
5447
|
+
cwd: lastAssistantMessage.pendingFix.directory
|
|
5448
|
+
});
|
|
5312
5449
|
dispatch({
|
|
5313
5450
|
type: "ADD_CHAT_MESSAGE",
|
|
5314
5451
|
role: "assistant",
|
|
@@ -5405,7 +5542,8 @@ ${contextBlock}`;
|
|
|
5405
5542
|
})
|
|
5406
5543
|
});
|
|
5407
5544
|
}
|
|
5408
|
-
} catch {
|
|
5545
|
+
} catch (error) {
|
|
5546
|
+
console.error("Failed to update state after tool calls:", error);
|
|
5409
5547
|
}
|
|
5410
5548
|
}
|
|
5411
5549
|
}
|
|
@@ -5447,7 +5585,14 @@ ${contextBlock}`;
|
|
|
5447
5585
|
] });
|
|
5448
5586
|
}
|
|
5449
5587
|
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
5450
|
-
/* @__PURE__ */
|
|
5588
|
+
/* @__PURE__ */ jsxs12(Text12, { children: [
|
|
5589
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, children: "Chat" }),
|
|
5590
|
+
currentSessionTitle && /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
5591
|
+
" ",
|
|
5592
|
+
currentSessionTitle
|
|
5593
|
+
] }),
|
|
5594
|
+
/* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " (h for history)" })
|
|
5595
|
+
] }),
|
|
5451
5596
|
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", flexGrow: 1, overflow: "hidden", marginTop: 1, children: [
|
|
5452
5597
|
messages.length === 0 && !loading && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " Ask about your codebase, decisions, patterns, or risks." }),
|
|
5453
5598
|
messages.map((msg, idx) => /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", marginTop: idx === 0 ? 0 : 1, marginBottom: 1, children: msg.role === "user" ? /* @__PURE__ */ jsxs12(Text12, { children: [
|
|
@@ -5489,8 +5634,219 @@ function formatToolInput(input) {
|
|
|
5489
5634
|
return parts.length > 0 ? parts.join(", ") : "";
|
|
5490
5635
|
}
|
|
5491
5636
|
|
|
5492
|
-
// src/cli/dashboard/
|
|
5637
|
+
// src/cli/dashboard/views/ChatArchiveView.tsx
|
|
5638
|
+
import { useEffect as useEffect4, useCallback as useCallback6 } from "react";
|
|
5639
|
+
import { Box as Box13, Text as Text13, useInput as useInput9 } from "ink";
|
|
5493
5640
|
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5641
|
+
function formatTimeAgo2(timestamp) {
|
|
5642
|
+
const seconds = Math.floor((Date.now() - timestamp) / 1e3);
|
|
5643
|
+
if (seconds < 60) return `${seconds}s ago`;
|
|
5644
|
+
const minutes = Math.floor(seconds / 60);
|
|
5645
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
5646
|
+
const hours = Math.floor(minutes / 60);
|
|
5647
|
+
if (hours < 24) return `${hours}h ago`;
|
|
5648
|
+
const days = Math.floor(hours / 24);
|
|
5649
|
+
if (days < 30) return `${days}d ago`;
|
|
5650
|
+
const months = Math.floor(days / 30);
|
|
5651
|
+
if (months < 12) return `${months}mo ago`;
|
|
5652
|
+
return `${Math.floor(months / 12)}y ago`;
|
|
5653
|
+
}
|
|
5654
|
+
function ChatArchiveView() {
|
|
5655
|
+
const { state, dispatch } = useDashboard();
|
|
5656
|
+
const { chatArchivePanel } = state;
|
|
5657
|
+
const { sessions, selectedIndex, showArchived, loading, inputMode, inputBuffer } = chatArchivePanel;
|
|
5658
|
+
const loadSessions = useCallback6(async () => {
|
|
5659
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_LOADING", loading: true });
|
|
5660
|
+
try {
|
|
5661
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5662
|
+
const store = getChatStore(workDir);
|
|
5663
|
+
const sessionsList = await store.listSessions(showArchived);
|
|
5664
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_SESSIONS", sessions: sessionsList });
|
|
5665
|
+
} catch (error) {
|
|
5666
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Failed to load chat sessions: ${error instanceof Error ? error.message : "unknown"}` });
|
|
5667
|
+
}
|
|
5668
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_LOADING", loading: false });
|
|
5669
|
+
}, [showArchived, dispatch]);
|
|
5670
|
+
useEffect4(() => {
|
|
5671
|
+
void loadSessions();
|
|
5672
|
+
}, [loadSessions]);
|
|
5673
|
+
const loadChatSession = useCallback6(async (sessionId) => {
|
|
5674
|
+
try {
|
|
5675
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5676
|
+
const store = getChatStore(workDir);
|
|
5677
|
+
const session = await store.loadSession(sessionId);
|
|
5678
|
+
if (session) {
|
|
5679
|
+
dispatch({ type: "LOAD_CHAT_MESSAGES", messages: session.messages });
|
|
5680
|
+
dispatch({ type: "SET_CHAT_SESSION", sessionId: session.id, title: session.title });
|
|
5681
|
+
dispatch({ type: "SET_VIEW", view: "chat" });
|
|
5682
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Loaded chat: ${session.title}` });
|
|
5683
|
+
} else {
|
|
5684
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "Chat session not found", severity: "warning", autoHideMs: 3e3 });
|
|
5685
|
+
}
|
|
5686
|
+
} catch (error) {
|
|
5687
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Failed to load chat: ${error instanceof Error ? error.message : "unknown"}`, severity: "warning", autoHideMs: 3e3 });
|
|
5688
|
+
}
|
|
5689
|
+
}, [dispatch]);
|
|
5690
|
+
const deleteSession = useCallback6(async () => {
|
|
5691
|
+
if (sessions.length === 0) return;
|
|
5692
|
+
const session = sessions[selectedIndex];
|
|
5693
|
+
if (!session) return;
|
|
5694
|
+
try {
|
|
5695
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5696
|
+
const store = getChatStore(workDir);
|
|
5697
|
+
await store.deleteSession(session.id);
|
|
5698
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Deleted chat: ${session.title}` });
|
|
5699
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "Chat deleted", severity: "info", autoHideMs: 2e3 });
|
|
5700
|
+
await loadSessions();
|
|
5701
|
+
} catch (error) {
|
|
5702
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Failed to delete: ${error instanceof Error ? error.message : "unknown"}`, severity: "warning", autoHideMs: 3e3 });
|
|
5703
|
+
}
|
|
5704
|
+
}, [sessions, selectedIndex, dispatch, loadSessions]);
|
|
5705
|
+
const archiveSession = useCallback6(async () => {
|
|
5706
|
+
if (sessions.length === 0) return;
|
|
5707
|
+
const session = sessions[selectedIndex];
|
|
5708
|
+
if (!session) return;
|
|
5709
|
+
try {
|
|
5710
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5711
|
+
const store = getChatStore(workDir);
|
|
5712
|
+
await store.archiveSession(session.id);
|
|
5713
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Archived chat: ${session.title}` });
|
|
5714
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "Chat archived", severity: "info", autoHideMs: 2e3 });
|
|
5715
|
+
await loadSessions();
|
|
5716
|
+
} catch (error) {
|
|
5717
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Failed to archive: ${error instanceof Error ? error.message : "unknown"}`, severity: "warning", autoHideMs: 3e3 });
|
|
5718
|
+
}
|
|
5719
|
+
}, [sessions, selectedIndex, dispatch, loadSessions]);
|
|
5720
|
+
const renameSession = useCallback6(async (newTitle) => {
|
|
5721
|
+
if (sessions.length === 0 || !newTitle.trim()) return;
|
|
5722
|
+
const session = sessions[selectedIndex];
|
|
5723
|
+
if (!session) return;
|
|
5724
|
+
try {
|
|
5725
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5726
|
+
const store = getChatStore(workDir);
|
|
5727
|
+
await store.renameSession(session.id, newTitle.trim());
|
|
5728
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Renamed chat to: ${newTitle}` });
|
|
5729
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "Chat renamed", severity: "info", autoHideMs: 2e3 });
|
|
5730
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_INPUT_MODE", mode: "browse" });
|
|
5731
|
+
await loadSessions();
|
|
5732
|
+
} catch (error) {
|
|
5733
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Failed to rename: ${error instanceof Error ? error.message : "unknown"}`, severity: "warning", autoHideMs: 3e3 });
|
|
5734
|
+
}
|
|
5735
|
+
}, [sessions, selectedIndex, dispatch, loadSessions]);
|
|
5736
|
+
const exportSession = useCallback6(async () => {
|
|
5737
|
+
if (sessions.length === 0) return;
|
|
5738
|
+
const session = sessions[selectedIndex];
|
|
5739
|
+
if (!session) return;
|
|
5740
|
+
try {
|
|
5741
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
5742
|
+
const store = getChatStore(workDir);
|
|
5743
|
+
const exported = await store.exportSession(session.id);
|
|
5744
|
+
if (exported) {
|
|
5745
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: "Chat exported (check logs for JSON)", severity: "info", autoHideMs: 3e3 });
|
|
5746
|
+
console.log("=== EXPORTED CHAT ===");
|
|
5747
|
+
console.log(exported);
|
|
5748
|
+
console.log("=== END EXPORT ===");
|
|
5749
|
+
}
|
|
5750
|
+
} catch (error) {
|
|
5751
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Failed to export: ${error instanceof Error ? error.message : "unknown"}`, severity: "warning", autoHideMs: 3e3 });
|
|
5752
|
+
}
|
|
5753
|
+
}, [sessions, selectedIndex, dispatch]);
|
|
5754
|
+
useInput9((input, key) => {
|
|
5755
|
+
if (inputMode === "rename") {
|
|
5756
|
+
if (key.return) {
|
|
5757
|
+
void renameSession(inputBuffer);
|
|
5758
|
+
} else if (key.escape) {
|
|
5759
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_INPUT_MODE", mode: "browse" });
|
|
5760
|
+
} else if (key.backspace || key.delete) {
|
|
5761
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_INPUT_BUFFER", buffer: inputBuffer.slice(0, -1) });
|
|
5762
|
+
} else if (input && !key.ctrl && !key.meta) {
|
|
5763
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_INPUT_BUFFER", buffer: inputBuffer + input });
|
|
5764
|
+
}
|
|
5765
|
+
return;
|
|
5766
|
+
}
|
|
5767
|
+
if (key.upArrow || input === "k") {
|
|
5768
|
+
const newIndex = Math.max(0, selectedIndex - 1);
|
|
5769
|
+
dispatch({ type: "SELECT_CHAT_SESSION", index: newIndex });
|
|
5770
|
+
} else if (key.downArrow || input === "j") {
|
|
5771
|
+
const newIndex = Math.min(sessions.length - 1, selectedIndex + 1);
|
|
5772
|
+
dispatch({ type: "SELECT_CHAT_SESSION", index: newIndex });
|
|
5773
|
+
} else if (key.return) {
|
|
5774
|
+
if (sessions[selectedIndex]) {
|
|
5775
|
+
void loadChatSession(sessions[selectedIndex].id);
|
|
5776
|
+
}
|
|
5777
|
+
} else if (input === "d") {
|
|
5778
|
+
void deleteSession();
|
|
5779
|
+
} else if (input === "a") {
|
|
5780
|
+
void archiveSession();
|
|
5781
|
+
} else if (input === "r") {
|
|
5782
|
+
dispatch({ type: "SET_CHAT_ARCHIVE_INPUT_MODE", mode: "rename" });
|
|
5783
|
+
} else if (input === "e") {
|
|
5784
|
+
void exportSession();
|
|
5785
|
+
} else if (input === "t") {
|
|
5786
|
+
dispatch({ type: "TOGGLE_ARCHIVED_CHATS" });
|
|
5787
|
+
} else if (input === "n") {
|
|
5788
|
+
dispatch({ type: "CLEAR_CHAT" });
|
|
5789
|
+
dispatch({ type: "SET_VIEW", view: "chat" });
|
|
5790
|
+
}
|
|
5791
|
+
});
|
|
5792
|
+
if (loading) {
|
|
5793
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
|
|
5794
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, children: "Chat Archive" }),
|
|
5795
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: " Loading..." })
|
|
5796
|
+
] });
|
|
5797
|
+
}
|
|
5798
|
+
if (sessions.length === 0) {
|
|
5799
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
|
|
5800
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, children: "Chat Archive" }),
|
|
5801
|
+
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
5802
|
+
" ",
|
|
5803
|
+
showArchived ? "No archived chats" : "No chat history yet"
|
|
5804
|
+
] }),
|
|
5805
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: " Press n to start a new chat" })
|
|
5806
|
+
] });
|
|
5807
|
+
}
|
|
5808
|
+
if (inputMode === "rename") {
|
|
5809
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
|
|
5810
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, children: "Rename Chat" }),
|
|
5811
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
|
|
5812
|
+
/* @__PURE__ */ jsx14(Text13, { children: "Title: " }),
|
|
5813
|
+
/* @__PURE__ */ jsx14(Text13, { children: inputBuffer }),
|
|
5814
|
+
/* @__PURE__ */ jsx14(Text13, { children: "\u2502" })
|
|
5815
|
+
] }),
|
|
5816
|
+
/* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "enter save \xB7 esc cancel" }) })
|
|
5817
|
+
] });
|
|
5818
|
+
}
|
|
5819
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
|
|
5820
|
+
/* @__PURE__ */ jsxs13(Text13, { children: [
|
|
5821
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, children: "Chat Archive" }),
|
|
5822
|
+
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
5823
|
+
" ",
|
|
5824
|
+
sessions.length,
|
|
5825
|
+
" chat",
|
|
5826
|
+
sessions.length !== 1 ? "s" : ""
|
|
5827
|
+
] }),
|
|
5828
|
+
showArchived && /* @__PURE__ */ jsx14(Text13, { color: "yellow", children: " (showing archived)" })
|
|
5829
|
+
] }),
|
|
5830
|
+
/* @__PURE__ */ jsx14(Box13, { flexDirection: "column", marginTop: 1, children: sessions.map((session, idx) => {
|
|
5831
|
+
const isSelected = idx === selectedIndex;
|
|
5832
|
+
const ago = formatTimeAgo2(session.updatedAt);
|
|
5833
|
+
const titleDisplay = session.title.length > 60 ? session.title.slice(0, 60) + "..." : session.title;
|
|
5834
|
+
return /* @__PURE__ */ jsx14(Box13, { flexDirection: "column", children: /* @__PURE__ */ jsxs13(Text13, { children: [
|
|
5835
|
+
isSelected ? /* @__PURE__ */ jsx14(Text13, { bold: true, color: "green", children: "> " }) : " ",
|
|
5836
|
+
isSelected ? /* @__PURE__ */ jsx14(Text13, { bold: true, children: titleDisplay }) : /* @__PURE__ */ jsx14(Text13, { children: titleDisplay }),
|
|
5837
|
+
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
5838
|
+
" ",
|
|
5839
|
+
session.messageCount,
|
|
5840
|
+
" msgs \xB7 ",
|
|
5841
|
+
ago
|
|
5842
|
+
] })
|
|
5843
|
+
] }) }, session.id);
|
|
5844
|
+
}) })
|
|
5845
|
+
] });
|
|
5846
|
+
}
|
|
5847
|
+
|
|
5848
|
+
// src/cli/dashboard/App.tsx
|
|
5849
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5494
5850
|
var MAIN_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
5495
5851
|
async function applyGoalFix(fix, dispatch) {
|
|
5496
5852
|
try {
|
|
@@ -5529,7 +5885,7 @@ ${content}
|
|
|
5529
5885
|
fixedContent = fixedContent.replace(/^```\w*\n?/, "").replace(/\n?```$/, "");
|
|
5530
5886
|
}
|
|
5531
5887
|
await writeFile(fullPath, fixedContent, "utf-8");
|
|
5532
|
-
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-
|
|
5888
|
+
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-XYA364W3.js");
|
|
5533
5889
|
const goals = await getActiveGoals(projectPath);
|
|
5534
5890
|
const matchedGoal = goals.find((g) => g.description === fix.goalDescription);
|
|
5535
5891
|
if (matchedGoal) {
|
|
@@ -5552,7 +5908,7 @@ function DashboardApp({ onReady }) {
|
|
|
5552
5908
|
const stateRef = useRef2(state);
|
|
5553
5909
|
stateRef.current = state;
|
|
5554
5910
|
const configPath = join2(getTrieDirectory(getWorkingDirectory(void 0, true)), "agent.json");
|
|
5555
|
-
const loadConfig =
|
|
5911
|
+
const loadConfig = useCallback7(async () => {
|
|
5556
5912
|
if (!existsSync3(configPath)) return;
|
|
5557
5913
|
try {
|
|
5558
5914
|
const raw = await readFile2(configPath, "utf-8");
|
|
@@ -5561,7 +5917,7 @@ function DashboardApp({ onReady }) {
|
|
|
5561
5917
|
} catch {
|
|
5562
5918
|
}
|
|
5563
5919
|
}, [configPath]);
|
|
5564
|
-
const persistConfig =
|
|
5920
|
+
const persistConfig = useCallback7(async () => {
|
|
5565
5921
|
try {
|
|
5566
5922
|
const workDir = getWorkingDirectory(void 0, true);
|
|
5567
5923
|
await mkdir(getTrieDirectory(workDir), { recursive: true });
|
|
@@ -5573,7 +5929,7 @@ function DashboardApp({ onReady }) {
|
|
|
5573
5929
|
} catch {
|
|
5574
5930
|
}
|
|
5575
5931
|
}, [configPath]);
|
|
5576
|
-
const processInsights =
|
|
5932
|
+
const processInsights = useCallback7(async (issues) => {
|
|
5577
5933
|
try {
|
|
5578
5934
|
const workDir = getWorkingDirectory(void 0, true);
|
|
5579
5935
|
const trieAgent = getGuardian(workDir);
|
|
@@ -5599,7 +5955,7 @@ function DashboardApp({ onReady }) {
|
|
|
5599
5955
|
dispatchRef.current({ type: "ADD_ACTIVITY", message: `Trie Agent error: ${error instanceof Error ? error.message : "unknown"}` });
|
|
5600
5956
|
}
|
|
5601
5957
|
}, []);
|
|
5602
|
-
const refreshGoals =
|
|
5958
|
+
const refreshGoals = useCallback7(async () => {
|
|
5603
5959
|
try {
|
|
5604
5960
|
const workDir = getWorkingDirectory(void 0, true);
|
|
5605
5961
|
const agentState = getGuardianState(workDir);
|
|
@@ -5615,7 +5971,7 @@ function DashboardApp({ onReady }) {
|
|
|
5615
5971
|
} catch {
|
|
5616
5972
|
}
|
|
5617
5973
|
}, []);
|
|
5618
|
-
const refreshHypotheses =
|
|
5974
|
+
const refreshHypotheses = useCallback7(async () => {
|
|
5619
5975
|
try {
|
|
5620
5976
|
const workDir = getWorkingDirectory(void 0, true);
|
|
5621
5977
|
const agentState = getGuardianState(workDir);
|
|
@@ -5631,7 +5987,7 @@ function DashboardApp({ onReady }) {
|
|
|
5631
5987
|
} catch {
|
|
5632
5988
|
}
|
|
5633
5989
|
}, []);
|
|
5634
|
-
|
|
5990
|
+
useEffect5(() => {
|
|
5635
5991
|
void loadConfig();
|
|
5636
5992
|
void refreshGoals();
|
|
5637
5993
|
void refreshHypotheses();
|
|
@@ -5646,7 +6002,6 @@ function DashboardApp({ onReady }) {
|
|
|
5646
6002
|
dispatchRef.current({ type: "STREAM_UPDATE", update: { type: "raw_log", data: { time, level, message }, timestamp: Date.now() } });
|
|
5647
6003
|
},
|
|
5648
6004
|
onNudge: (nudge) => {
|
|
5649
|
-
console.error("[Dashboard] onNudge called:", { message: nudge.message, severity: nudge.severity, file: nudge.file });
|
|
5650
6005
|
const action = { type: "SHOW_NOTIFICATION", message: nudge.message, severity: nudge.severity };
|
|
5651
6006
|
if (nudge.file !== void 0) action.file = nudge.file;
|
|
5652
6007
|
if (nudge.autoHideMs !== void 0) action.autoHideMs = nudge.autoHideMs;
|
|
@@ -5663,7 +6018,6 @@ function DashboardApp({ onReady }) {
|
|
|
5663
6018
|
relatedIssues: [],
|
|
5664
6019
|
dismissed: false
|
|
5665
6020
|
};
|
|
5666
|
-
console.error("[Dashboard] Adding insight:", { id: insight.id, type: insight.type, category: insight.category, priority: insight.priority });
|
|
5667
6021
|
dispatchRef.current({ type: "ADD_INSIGHTS", insights: [insight] });
|
|
5668
6022
|
}
|
|
5669
6023
|
}
|
|
@@ -5688,21 +6042,21 @@ function DashboardApp({ onReady }) {
|
|
|
5688
6042
|
outputManager.setMode("console");
|
|
5689
6043
|
};
|
|
5690
6044
|
}, [loadConfig, onReady, processInsights, refreshGoals, refreshHypotheses]);
|
|
5691
|
-
|
|
6045
|
+
useEffect5(() => {
|
|
5692
6046
|
const interval = setInterval(() => {
|
|
5693
6047
|
dispatchRef.current({ type: "AUTO_DISMISS_NOTIFICATIONS" });
|
|
5694
6048
|
}, 5e3);
|
|
5695
6049
|
return () => clearInterval(interval);
|
|
5696
6050
|
}, []);
|
|
5697
6051
|
const applyingFixIds = useRef2(/* @__PURE__ */ new Set());
|
|
5698
|
-
|
|
6052
|
+
useEffect5(() => {
|
|
5699
6053
|
const toApply = state.pendingFixes.filter((f) => f.status === "applying" && !applyingFixIds.current.has(f.id));
|
|
5700
6054
|
for (const fix of toApply) {
|
|
5701
6055
|
applyingFixIds.current.add(fix.id);
|
|
5702
6056
|
void applyGoalFix(fix, dispatchRef.current);
|
|
5703
6057
|
}
|
|
5704
6058
|
}, [state.pendingFixes]);
|
|
5705
|
-
|
|
6059
|
+
useInput10((input, key) => {
|
|
5706
6060
|
if (showConfig) return;
|
|
5707
6061
|
if (state.view === "goals" && state.goalsPanel.inputMode === "add") return;
|
|
5708
6062
|
if (state.view === "hypotheses" && state.hypothesesPanel.inputMode === "add") return;
|
|
@@ -5724,7 +6078,7 @@ function DashboardApp({ onReady }) {
|
|
|
5724
6078
|
}
|
|
5725
6079
|
if (input === "q" || key.escape) {
|
|
5726
6080
|
exit();
|
|
5727
|
-
|
|
6081
|
+
return;
|
|
5728
6082
|
}
|
|
5729
6083
|
if (key.tab) {
|
|
5730
6084
|
const currentIndex = MAIN_VIEWS.indexOf(state.view);
|
|
@@ -5732,7 +6086,7 @@ function DashboardApp({ onReady }) {
|
|
|
5732
6086
|
dispatch({ type: "SET_VIEW", view: MAIN_VIEWS[nextIndex] || "overview" });
|
|
5733
6087
|
return;
|
|
5734
6088
|
}
|
|
5735
|
-
if (state.view === "goals" || state.view === "hypotheses") {
|
|
6089
|
+
if (state.view === "goals" || state.view === "hypotheses" || state.view === "chat-archive") {
|
|
5736
6090
|
return;
|
|
5737
6091
|
}
|
|
5738
6092
|
if (input === "s") {
|
|
@@ -5765,6 +6119,10 @@ function DashboardApp({ onReady }) {
|
|
|
5765
6119
|
dispatch({ type: "SET_VIEW", view: "chat" });
|
|
5766
6120
|
return;
|
|
5767
6121
|
}
|
|
6122
|
+
if (input === "h") {
|
|
6123
|
+
dispatch({ type: "SET_VIEW", view: "chat-archive" });
|
|
6124
|
+
return;
|
|
6125
|
+
}
|
|
5768
6126
|
if (state.view === "agent" || state.view === "memory") return;
|
|
5769
6127
|
if (input === "b") dispatch({ type: "GO_BACK" });
|
|
5770
6128
|
if (input === "n") dispatch({ type: "NEXT_PAGE" });
|
|
@@ -5773,41 +6131,44 @@ function DashboardApp({ onReady }) {
|
|
|
5773
6131
|
let viewComponent;
|
|
5774
6132
|
switch (state.view) {
|
|
5775
6133
|
case "overview":
|
|
5776
|
-
viewComponent = /* @__PURE__ */
|
|
6134
|
+
viewComponent = /* @__PURE__ */ jsx15(OverviewView, {});
|
|
5777
6135
|
break;
|
|
5778
6136
|
case "agent":
|
|
5779
|
-
viewComponent = /* @__PURE__ */
|
|
6137
|
+
viewComponent = /* @__PURE__ */ jsx15(AgentView, {});
|
|
5780
6138
|
break;
|
|
5781
6139
|
case "goals":
|
|
5782
|
-
viewComponent = /* @__PURE__ */
|
|
6140
|
+
viewComponent = /* @__PURE__ */ jsx15(GoalsView, {});
|
|
5783
6141
|
break;
|
|
5784
6142
|
case "hypotheses":
|
|
5785
|
-
viewComponent = /* @__PURE__ */
|
|
6143
|
+
viewComponent = /* @__PURE__ */ jsx15(HypothesesView, {});
|
|
5786
6144
|
break;
|
|
5787
6145
|
case "memory":
|
|
5788
|
-
viewComponent = /* @__PURE__ */
|
|
6146
|
+
viewComponent = /* @__PURE__ */ jsx15(MemoryTreeView, {});
|
|
5789
6147
|
break;
|
|
5790
6148
|
case "rawlog":
|
|
5791
|
-
viewComponent = /* @__PURE__ */
|
|
6149
|
+
viewComponent = /* @__PURE__ */ jsx15(RawLogView, {});
|
|
5792
6150
|
break;
|
|
5793
6151
|
case "chat":
|
|
5794
|
-
viewComponent = /* @__PURE__ */
|
|
6152
|
+
viewComponent = /* @__PURE__ */ jsx15(ChatView, {});
|
|
6153
|
+
break;
|
|
6154
|
+
case "chat-archive":
|
|
6155
|
+
viewComponent = /* @__PURE__ */ jsx15(ChatArchiveView, {});
|
|
5795
6156
|
break;
|
|
5796
6157
|
default:
|
|
5797
|
-
viewComponent = /* @__PURE__ */
|
|
6158
|
+
viewComponent = /* @__PURE__ */ jsx15(OverviewView, {});
|
|
5798
6159
|
}
|
|
5799
|
-
return /* @__PURE__ */
|
|
5800
|
-
/* @__PURE__ */
|
|
5801
|
-
!showConfig && !showHelp && /* @__PURE__ */
|
|
5802
|
-
/* @__PURE__ */
|
|
6160
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", height: process.stdout.rows || 40, children: [
|
|
6161
|
+
/* @__PURE__ */ jsx15(Header, {}),
|
|
6162
|
+
!showConfig && !showHelp && /* @__PURE__ */ jsx15(Notification, {}),
|
|
6163
|
+
/* @__PURE__ */ jsx15(Box14, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: showConfig ? /* @__PURE__ */ jsx15(ConfigDialog, { onClose: () => {
|
|
5803
6164
|
setShowConfig(false);
|
|
5804
6165
|
void persistConfig();
|
|
5805
|
-
} }) : showHelp ? /* @__PURE__ */
|
|
5806
|
-
/* @__PURE__ */
|
|
6166
|
+
} }) : showHelp ? /* @__PURE__ */ jsx15(HelpDialog, { view: state.view, onClose: () => setShowHelp(false) }) : viewComponent }),
|
|
6167
|
+
/* @__PURE__ */ jsx15(Footer, {})
|
|
5807
6168
|
] });
|
|
5808
6169
|
}
|
|
5809
6170
|
function App({ onReady }) {
|
|
5810
|
-
return /* @__PURE__ */
|
|
6171
|
+
return /* @__PURE__ */ jsx15(DashboardProvider, { children: /* @__PURE__ */ jsx15(DashboardApp, { onReady }) });
|
|
5811
6172
|
}
|
|
5812
6173
|
|
|
5813
6174
|
// src/cli/dashboard/index.ts
|
|
@@ -5817,7 +6178,7 @@ var InteractiveDashboard = class {
|
|
|
5817
6178
|
getConfigFn = null;
|
|
5818
6179
|
async start() {
|
|
5819
6180
|
this.app = render(
|
|
5820
|
-
|
|
6181
|
+
React11.createElement(App, {
|
|
5821
6182
|
onReady: (handler, getConfig) => {
|
|
5822
6183
|
this.updateHandler = handler;
|
|
5823
6184
|
this.getConfigFn = getConfig;
|
|
@@ -5862,4 +6223,4 @@ export {
|
|
|
5862
6223
|
handleCheckpointTool,
|
|
5863
6224
|
InteractiveDashboard
|
|
5864
6225
|
};
|
|
5865
|
-
//# sourceMappingURL=chunk-
|
|
6226
|
+
//# sourceMappingURL=chunk-QIS2VDJL.js.map
|