@triedotdev/mcp 1.0.162 → 1.0.164
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-Q4K7CFCK.js → chunk-D6E4Q4I6.js} +422 -36
- package/dist/chunk-D6E4Q4I6.js.map +1 -0
- package/dist/{chunk-UDQBOLIR.js → chunk-OKK4QNK3.js} +37 -3
- package/dist/chunk-OKK4QNK3.js.map +1 -0
- package/dist/chunk-WCN7S3EI.js +14 -0
- package/dist/chunk-WCN7S3EI.js.map +1 -0
- package/dist/cli/main.js +3 -3
- package/dist/cli/yolo-daemon.js +3 -2
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/parse-goal-violation-SACGFG3C.js +8 -0
- package/dist/parse-goal-violation-SACGFG3C.js.map +1 -0
- package/dist/server/mcp-server.js +4 -3
- package/package.json +1 -1
- package/dist/chunk-Q4K7CFCK.js.map +0 -1
- package/dist/chunk-UDQBOLIR.js.map +0 -1
|
@@ -4,12 +4,18 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
getTrieAgent
|
|
6
6
|
} from "./chunk-ERMLZJTK.js";
|
|
7
|
+
import {
|
|
8
|
+
parseGoalViolation
|
|
9
|
+
} from "./chunk-WCN7S3EI.js";
|
|
7
10
|
import {
|
|
8
11
|
CodebaseIndex
|
|
9
12
|
} from "./chunk-Q5EKA5YA.js";
|
|
10
13
|
import {
|
|
11
14
|
getOutputManager
|
|
12
15
|
} from "./chunk-VR4VWXXU.js";
|
|
16
|
+
import {
|
|
17
|
+
getInsightStore
|
|
18
|
+
} from "./chunk-T63OHG4Q.js";
|
|
13
19
|
import {
|
|
14
20
|
LearningEngine,
|
|
15
21
|
exportToJson,
|
|
@@ -21,6 +27,9 @@ import {
|
|
|
21
27
|
reasonAboutChangesHumanReadable,
|
|
22
28
|
saveCheckpoint
|
|
23
29
|
} from "./chunk-62JD7MIS.js";
|
|
30
|
+
import {
|
|
31
|
+
measureInitialGoalValue
|
|
32
|
+
} from "./chunk-ACU3IXZG.js";
|
|
24
33
|
import {
|
|
25
34
|
loadConfig,
|
|
26
35
|
saveConfig
|
|
@@ -38,9 +47,6 @@ import {
|
|
|
38
47
|
import {
|
|
39
48
|
ContextGraph
|
|
40
49
|
} from "./chunk-VUL52BQL.js";
|
|
41
|
-
import {
|
|
42
|
-
measureInitialGoalValue
|
|
43
|
-
} from "./chunk-ACU3IXZG.js";
|
|
44
50
|
import {
|
|
45
51
|
getKeyFromKeychain,
|
|
46
52
|
isAIAvailable,
|
|
@@ -693,9 +699,12 @@ function dashboardReducer(state, action) {
|
|
|
693
699
|
const blocks = action.ledgerBlocks ?? state.memoryTree.ledgerBlocks;
|
|
694
700
|
const gotchas = action.storageGotchas ?? state.memoryTree.storageGotchas;
|
|
695
701
|
const facts = action.storageFacts ?? state.memoryTree.storageFacts;
|
|
702
|
+
const nudges = action.storageNudges ?? state.memoryTree.storageNudges;
|
|
703
|
+
const insights = action.storageInsights ?? state.memoryTree.storageInsights;
|
|
696
704
|
const expanded = new Set(state.memoryTree.expandedNodes);
|
|
697
705
|
if (blocks.length > 0) expanded.add("ledger-chain");
|
|
698
706
|
if (gotchas.length > 0) expanded.add("gotchas");
|
|
707
|
+
if (nudges.length > 0 || insights.length > 0) expanded.add("patterns");
|
|
699
708
|
return {
|
|
700
709
|
...state,
|
|
701
710
|
memoryTree: {
|
|
@@ -706,6 +715,8 @@ function dashboardReducer(state, action) {
|
|
|
706
715
|
storageGovernance: action.storageGovernance ?? state.memoryTree.storageGovernance,
|
|
707
716
|
storageFacts: facts,
|
|
708
717
|
storageGotchas: gotchas,
|
|
718
|
+
storageNudges: nudges,
|
|
719
|
+
storageInsights: insights,
|
|
709
720
|
ledgerBlocks: blocks,
|
|
710
721
|
expandedNodes: expanded
|
|
711
722
|
}
|
|
@@ -970,7 +981,7 @@ function createInitialState() {
|
|
|
970
981
|
},
|
|
971
982
|
goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningGoalId: null, scanningProgress: "" },
|
|
972
983
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningHypothesisId: null, scanningProgress: "" },
|
|
973
|
-
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], storageGovernance: [], storageFacts: [], storageGotchas: [], ledgerBlocks: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), expandedItemId: null, selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
984
|
+
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], storageGovernance: [], storageFacts: [], storageGotchas: [], storageNudges: [], storageInsights: [], ledgerBlocks: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), expandedItemId: null, selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
974
985
|
agentBrain: { loaded: false, governance: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
|
|
975
986
|
chatState: { messages: [], inputBuffer: "", loading: false, progress: null, messageQueue: [], currentSessionId: null, currentSessionTitle: null },
|
|
976
987
|
chatArchivePanel: { sessions: [], selectedIndex: 0, showArchived: false, loading: false, inputMode: "browse", inputBuffer: "" },
|
|
@@ -1041,18 +1052,6 @@ function Header() {
|
|
|
1041
1052
|
// src/cli/dashboard/components/Footer.tsx
|
|
1042
1053
|
import React2 from "react";
|
|
1043
1054
|
import { Box as Box2, Text as Text2, useStdout as useStdout2 } from "ink";
|
|
1044
|
-
|
|
1045
|
-
// src/cli/dashboard/parse-goal-violation.ts
|
|
1046
|
-
function parseGoalViolation(message) {
|
|
1047
|
-
const match = message.match(/Goal "([^"]+)" violated in ([^:]+): (.+)/);
|
|
1048
|
-
if (!match) return null;
|
|
1049
|
-
const [, goal, file, violation] = match;
|
|
1050
|
-
if (!goal || !file || !violation) return null;
|
|
1051
|
-
const cleanViolation = violation.replace(/\s*\[\d+%\s*confidence\]\s*$/i, "").trim();
|
|
1052
|
-
return { file: file.trim(), goal: goal.trim(), violation: cleanViolation };
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
// src/cli/dashboard/components/Footer.tsx
|
|
1056
1055
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1057
1056
|
var VIEW_LABELS = {
|
|
1058
1057
|
overview: "Overview",
|
|
@@ -1188,7 +1187,7 @@ function Notification() {
|
|
|
1188
1187
|
/* @__PURE__ */ jsx4(Text3, { color, bold: true, children: "\u25CF " }),
|
|
1189
1188
|
notification.message
|
|
1190
1189
|
] }),
|
|
1191
|
-
notification.file && /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
1190
|
+
notification.file && /* @__PURE__ */ jsxs3(Text3, { wrap: "wrap", dimColor: true, children: [
|
|
1192
1191
|
" \u2192 ",
|
|
1193
1192
|
notification.file
|
|
1194
1193
|
] })
|
|
@@ -1983,8 +1982,8 @@ function AgentView() {
|
|
|
1983
1982
|
if (!insight) return;
|
|
1984
1983
|
try {
|
|
1985
1984
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1986
|
-
const { getInsightStore } = await import("./insight-store-EC4PLSAW.js");
|
|
1987
|
-
const store =
|
|
1985
|
+
const { getInsightStore: getInsightStore2 } = await import("./insight-store-EC4PLSAW.js");
|
|
1986
|
+
const store = getInsightStore2(workDir);
|
|
1988
1987
|
await store.dismissInsight(insight.id);
|
|
1989
1988
|
const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
|
|
1990
1989
|
const storage = getStorage2(workDir);
|
|
@@ -2819,7 +2818,7 @@ function timeAgo2(iso) {
|
|
|
2819
2818
|
function MemoryTreeView() {
|
|
2820
2819
|
const { state, dispatch } = useDashboard();
|
|
2821
2820
|
const { memoryTree } = state;
|
|
2822
|
-
const { snapshot, globalPatterns, storageGovernance, storageFacts, storageGotchas, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded } = memoryTree;
|
|
2821
|
+
const { snapshot, globalPatterns, storageGovernance, storageFacts, storageGotchas, storageNudges, storageInsights, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded } = memoryTree;
|
|
2823
2822
|
const { stdout } = useStdout8();
|
|
2824
2823
|
const cols = stdout?.columns || 80;
|
|
2825
2824
|
const narrow = cols < 60;
|
|
@@ -2829,15 +2828,19 @@ function MemoryTreeView() {
|
|
|
2829
2828
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2830
2829
|
const graph = new ContextGraph(workDir);
|
|
2831
2830
|
const storage = new TieredStorage(workDir);
|
|
2832
|
-
const
|
|
2831
|
+
const insightStore = getInsightStore(workDir);
|
|
2832
|
+
const [snap, patterns, governance2, facts, gotchas, nudges, blocks] = await Promise.all([
|
|
2833
2833
|
graph.getSnapshot(),
|
|
2834
2834
|
findCrossProjectPatterns(2),
|
|
2835
2835
|
storage.queryGovernance({ limit: 20 }).catch(() => []),
|
|
2836
2836
|
storage.queryFacts({ limit: 20 }).catch(() => []),
|
|
2837
2837
|
storage.queryGotchas({ limit: 20, resolved: false }).catch(() => []),
|
|
2838
|
+
storage.queryNudges({ limit: 20, resolved: false }).catch(() => []),
|
|
2838
2839
|
getLedgerBlocks(workDir).catch(() => [])
|
|
2839
2840
|
]);
|
|
2840
|
-
|
|
2841
|
+
await insightStore.load();
|
|
2842
|
+
const insights = insightStore.getActiveInsights(10);
|
|
2843
|
+
dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns, storageGovernance: governance2, storageFacts: facts, storageGotchas: gotchas, storageNudges: nudges, storageInsights: insights, ledgerBlocks: blocks });
|
|
2841
2844
|
} catch (err) {
|
|
2842
2845
|
dispatch({ type: "ADD_ACTIVITY", message: "Context graph load error" });
|
|
2843
2846
|
}
|
|
@@ -2914,7 +2917,7 @@ function MemoryTreeView() {
|
|
|
2914
2917
|
const order = { critical: 0, high: 1 };
|
|
2915
2918
|
return (order[a.data.riskLevel] ?? 2) - (order[b.data.riskLevel] ?? 2);
|
|
2916
2919
|
});
|
|
2917
|
-
const totalEntries = productGovernance.length + learnedSignals.length + (storageFacts?.length ?? 0) + incidentNodes.length + patternNodes.length + globalPatterns.length + hotspots.length + ledgerBlocks.length;
|
|
2920
|
+
const totalEntries = productGovernance.length + learnedSignals.length + (storageFacts?.length ?? 0) + (storageNudges?.length ?? 0) + (storageInsights?.length ?? 0) + incidentNodes.length + patternNodes.length + globalPatterns.length + hotspots.length + ledgerBlocks.length;
|
|
2918
2921
|
const expandedGovernance = expandedItemId?.startsWith("decision-") ? governance.find((g) => `decision-${g.id}` === expandedItemId) : null;
|
|
2919
2922
|
const expandedIncident = expandedItemId?.startsWith("incident-") ? incidentNodes.find((n) => `incident-${n.id}` === expandedItemId) : null;
|
|
2920
2923
|
const expandedGotcha = expandedItemId?.startsWith("gotcha-") ? storageGotchas.find((g) => `gotcha-${g.id}` === expandedItemId) ?? null : null;
|
|
@@ -3180,9 +3183,55 @@ function MemoryTreeView() {
|
|
|
3180
3183
|
] })
|
|
3181
3184
|
] }, g.id);
|
|
3182
3185
|
}),
|
|
3183
|
-
renderHeader("patterns", "Learned Signals", learnedSignals.length + (storageFacts?.length ?? 0) + patternNodes.length, learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && patternNodes.length === 0 ? "-- Trie learns as you work" : void 0),
|
|
3186
|
+
renderHeader("patterns", "Learned Signals", (storageInsights?.length ?? 0) + learnedSignals.length + (storageFacts?.length ?? 0) + (storageNudges?.length ?? 0) + patternNodes.length, (storageInsights?.length ?? 0) === 0 && learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && (storageNudges?.length ?? 0) === 0 && patternNodes.length === 0 ? "-- Trie learns as you work" : void 0),
|
|
3184
3187
|
expandedNodes.has("patterns") && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3185
|
-
|
|
3188
|
+
(storageInsights?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
3189
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3190
|
+
" ",
|
|
3191
|
+
" ",
|
|
3192
|
+
"Learnings"
|
|
3193
|
+
] }),
|
|
3194
|
+
storageInsights.slice(0, 5).map((insight) => {
|
|
3195
|
+
const descWidth = Math.max(30, contentWidth - 15);
|
|
3196
|
+
const desc = insight.message.length > descWidth ? insight.message.slice(0, descWidth - 3) + "..." : insight.message;
|
|
3197
|
+
const categoryLabel = insight.category === "security" ? "[sec]" : insight.category === "performance" ? "[perf]" : insight.category === "quality" ? "[qual]" : "[learn]";
|
|
3198
|
+
const confidenceColor = insight.priority >= 7 ? "green" : insight.priority >= 4 ? "yellow" : "white";
|
|
3199
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
3200
|
+
" ",
|
|
3201
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: categoryLabel }),
|
|
3202
|
+
" ",
|
|
3203
|
+
/* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
3204
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { color: confidenceColor, dimColor: true, children: [
|
|
3205
|
+
" ",
|
|
3206
|
+
insight.priority,
|
|
3207
|
+
"/10"
|
|
3208
|
+
] })
|
|
3209
|
+
] }, insight.id);
|
|
3210
|
+
})
|
|
3211
|
+
] }),
|
|
3212
|
+
(storageNudges?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 ? 1 : 0, children: [
|
|
3213
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3214
|
+
" ",
|
|
3215
|
+
" ",
|
|
3216
|
+
(storageInsights?.length ?? 0) > 0 ? "Raw Detections" : "AI Detections"
|
|
3217
|
+
] }),
|
|
3218
|
+
storageNudges.slice(0, (storageInsights?.length ?? 0) > 0 ? 3 : 5).map((n) => {
|
|
3219
|
+
const descWidth = Math.max(30, contentWidth - 15);
|
|
3220
|
+
const desc = n.message.length > descWidth ? n.message.slice(0, descWidth - 3) + "..." : n.message;
|
|
3221
|
+
const severityColor = n.severity === "critical" ? "red" : n.severity === "high" ? "yellow" : "cyan";
|
|
3222
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
3223
|
+
" ",
|
|
3224
|
+
/* @__PURE__ */ jsx11(Text10, { color: severityColor, children: "\u25CF" }),
|
|
3225
|
+
" ",
|
|
3226
|
+
/* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
3227
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3228
|
+
" ",
|
|
3229
|
+
timeAgo2(n.timestamp)
|
|
3230
|
+
] })
|
|
3231
|
+
] }, n.id);
|
|
3232
|
+
})
|
|
3233
|
+
] }),
|
|
3234
|
+
learnedSignals.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 ? 1 : 0, children: [
|
|
3186
3235
|
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3187
3236
|
" ",
|
|
3188
3237
|
" ",
|
|
@@ -3203,7 +3252,7 @@ function MemoryTreeView() {
|
|
|
3203
3252
|
] }, g.id);
|
|
3204
3253
|
})
|
|
3205
3254
|
] }),
|
|
3206
|
-
(storageFacts?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: learnedSignals.length > 0 ? 1 : 0, children: [
|
|
3255
|
+
(storageFacts?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 ? 1 : 0, children: [
|
|
3207
3256
|
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3208
3257
|
" ",
|
|
3209
3258
|
" ",
|
|
@@ -3224,8 +3273,8 @@ function MemoryTreeView() {
|
|
|
3224
3273
|
] }, f.id);
|
|
3225
3274
|
})
|
|
3226
3275
|
] }),
|
|
3227
|
-
patternNodes.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0 ? 1 : 0, children: [
|
|
3228
|
-
(learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0) && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3276
|
+
patternNodes.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0 ? 1 : 0, children: [
|
|
3277
|
+
((storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0) && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3229
3278
|
" ",
|
|
3230
3279
|
" ",
|
|
3231
3280
|
"Patterns"
|
|
@@ -3236,7 +3285,7 @@ function MemoryTreeView() {
|
|
|
3236
3285
|
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
3237
3286
|
const descWidth = Math.max(30, contentWidth - 15);
|
|
3238
3287
|
const desc = n.data.description.length > descWidth ? n.data.description.slice(0, descWidth - 3) + "..." : n.data.description;
|
|
3239
|
-
const hasPreceding = learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0;
|
|
3288
|
+
const hasPreceding = (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0;
|
|
3240
3289
|
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
3241
3290
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : hasPreceding ? " " : " ",
|
|
3242
3291
|
!hasPreceding && " ",
|
|
@@ -3256,7 +3305,7 @@ function MemoryTreeView() {
|
|
|
3256
3305
|
] }, n.id);
|
|
3257
3306
|
})
|
|
3258
3307
|
] }),
|
|
3259
|
-
patternNodes.length === 0 && learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3308
|
+
patternNodes.length === 0 && learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && (storageNudges?.length ?? 0) === 0 && (storageInsights?.length ?? 0) === 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3260
3309
|
" ",
|
|
3261
3310
|
" ",
|
|
3262
3311
|
"No signals learned yet. Trie will extract insights as you work."
|
|
@@ -6889,7 +6938,7 @@ var TrieGetBlockersTool = class {
|
|
|
6889
6938
|
const emoji = blocker.impact === "critical" ? "\u{1F534}" : blocker.impact === "high" ? "\u{1F7E0}" : blocker.impact === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
6890
6939
|
output += `${emoji} [${impact}] ${blocker.blocker}
|
|
6891
6940
|
`;
|
|
6892
|
-
if (blocker.affectedAreas
|
|
6941
|
+
if ((blocker.affectedAreas?.length ?? 0) > 0) {
|
|
6893
6942
|
output += ` Affects: ${blocker.affectedAreas.join(", ")}
|
|
6894
6943
|
`;
|
|
6895
6944
|
}
|
|
@@ -6976,6 +7025,48 @@ function formatNudges(nudges) {
|
|
|
6976
7025
|
}
|
|
6977
7026
|
return out;
|
|
6978
7027
|
}
|
|
7028
|
+
var TrieGetNudgesTool = class {
|
|
7029
|
+
async execute(input) {
|
|
7030
|
+
const workDir = input.directory || getWorkingDirectory(void 0, true);
|
|
7031
|
+
const storage = getStorage(workDir);
|
|
7032
|
+
await storage.initialize();
|
|
7033
|
+
const limit = input.limit ?? 20;
|
|
7034
|
+
const nudges = await storage.queryNudges({
|
|
7035
|
+
resolved: false,
|
|
7036
|
+
severity: input.severity,
|
|
7037
|
+
file: input.file,
|
|
7038
|
+
limit
|
|
7039
|
+
});
|
|
7040
|
+
if (nudges.length === 0) {
|
|
7041
|
+
return {
|
|
7042
|
+
content: [{
|
|
7043
|
+
type: "text",
|
|
7044
|
+
text: "No unresolved nudges (goal violations) found. Run trie scan to detect new issues."
|
|
7045
|
+
}]
|
|
7046
|
+
};
|
|
7047
|
+
}
|
|
7048
|
+
const { parseGoalViolation: parseGoalViolation2 } = await import("./parse-goal-violation-SACGFG3C.js");
|
|
7049
|
+
let out = `Found ${nudges.length} nudge(s) / goal violation(s):
|
|
7050
|
+
|
|
7051
|
+
`;
|
|
7052
|
+
for (const n of nudges) {
|
|
7053
|
+
const parsed = parseGoalViolation2(n.message);
|
|
7054
|
+
out += `\u26A0\uFE0F [${n.severity}] ${n.message}
|
|
7055
|
+
`;
|
|
7056
|
+
out += ` File: ${n.file || parsed?.file || "unknown"}
|
|
7057
|
+
`;
|
|
7058
|
+
if (parsed) {
|
|
7059
|
+
out += ` \u2192 trie_propose_fix: file="${parsed.file}" goal="${parsed.goal}" violation="${parsed.violation.slice(0, 80)}${parsed.violation.length > 80 ? "..." : ""}"
|
|
7060
|
+
`;
|
|
7061
|
+
}
|
|
7062
|
+
if (n.suggestedAction) out += ` Suggested: ${n.suggestedAction}
|
|
7063
|
+
`;
|
|
7064
|
+
out += "\n";
|
|
7065
|
+
}
|
|
7066
|
+
out += "To fix: call trie_propose_fix or trie_propose_fixes_batch with file, goal, violation from above.\n";
|
|
7067
|
+
return { content: [{ type: "text", text: out }] };
|
|
7068
|
+
}
|
|
7069
|
+
};
|
|
6979
7070
|
function formatIncidents(incidents) {
|
|
6980
7071
|
if (incidents.length === 0) return "No incidents found.";
|
|
6981
7072
|
let out = `Found ${incidents.length} incident(s):
|
|
@@ -7932,6 +8023,18 @@ var CHAT_TOOLS = [
|
|
|
7932
8023
|
}
|
|
7933
8024
|
}
|
|
7934
8025
|
},
|
|
8026
|
+
{
|
|
8027
|
+
name: "trie_get_nudges",
|
|
8028
|
+
description: "Get unresolved nudges (goal violations). Use when automating fixes: call trie_get_nudges, then trie_propose_fix or trie_propose_fixes_batch with file/goal/violation from results.",
|
|
8029
|
+
input_schema: {
|
|
8030
|
+
type: "object",
|
|
8031
|
+
properties: {
|
|
8032
|
+
limit: { type: "number", description: "Max results (default 20)" },
|
|
8033
|
+
severity: { type: "string", enum: ["critical", "high", "warning", "info"], description: "Filter by severity" },
|
|
8034
|
+
file: { type: "string", description: "Filter by file path" }
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
8037
|
+
},
|
|
7935
8038
|
{
|
|
7936
8039
|
name: "trie_query_ledger_blocks",
|
|
7937
8040
|
description: 'Query the ledger chain blocks \u2014 the tamper-evident chain of recorded issues. Use when user asks about "blocks", "ledger chain", "what issues in my blocks", "most frequent issues in blocks", etc. Returns block summary and aggregation of issues by file, severity, and agent.',
|
|
@@ -8212,6 +8315,11 @@ async function executeTool(name, input, onProgress) {
|
|
|
8212
8315
|
const result = await tool.execute(withDir);
|
|
8213
8316
|
return textFromResult(result);
|
|
8214
8317
|
}
|
|
8318
|
+
case "trie_get_nudges": {
|
|
8319
|
+
const tool = new TrieGetNudgesTool();
|
|
8320
|
+
const result = await tool.execute(withDir);
|
|
8321
|
+
return textFromResult(result);
|
|
8322
|
+
}
|
|
8215
8323
|
case "trie_query_ledger_blocks": {
|
|
8216
8324
|
const tool = new TrieQueryLedgerBlocksTool();
|
|
8217
8325
|
const result = await tool.execute(withDir);
|
|
@@ -8791,9 +8899,9 @@ var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
|
|
|
8791
8899
|
3. NEVER use numeric IDs like 1, 2, 3 - always use the full ID like "hyp-1771957097120-bogco0"
|
|
8792
8900
|
4. If hypothesis IDs aren't in the context, first call trie_query_context with type="hypotheses" to fetch them
|
|
8793
8901
|
|
|
8794
|
-
**When user asks to fix violations:**
|
|
8795
|
-
1.
|
|
8796
|
-
2. Extract: file path, goal description, and violation details for ALL
|
|
8902
|
+
**When user asks to fix violations (or automate fixes):**
|
|
8903
|
+
1. Call trie_get_nudges for full list of unresolved nudges (or check "Recent goal violations" in trie://context)
|
|
8904
|
+
2. Extract: file path, goal description, and violation details for ALL nudges
|
|
8797
8905
|
3. If multiple violations: Call trie_propose_fixes_batch ONCE with all fixes
|
|
8798
8906
|
4. If single violation: Call trie_propose_fix once
|
|
8799
8907
|
5. AFTER the tool call completes, the system will ask for user confirmation - do NOT add your own confirmation message
|
|
@@ -9907,7 +10015,248 @@ var InteractiveDashboard = class {
|
|
|
9907
10015
|
import { watch, existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
|
|
9908
10016
|
import { stat, readFile as readFile5 } from "fs/promises";
|
|
9909
10017
|
import { join as join4, extname as extname3, basename } from "path";
|
|
10018
|
+
import { createHash as createHash3 } from "crypto";
|
|
10019
|
+
|
|
10020
|
+
// src/agent/signal-summarizer.ts
|
|
10021
|
+
import Anthropic2 from "@anthropic-ai/sdk";
|
|
9910
10022
|
import { createHash as createHash2 } from "crypto";
|
|
10023
|
+
var SIGNAL_THRESHOLD = 5;
|
|
10024
|
+
var SUMMARIZE_PROMPT = `You are an AI that learns patterns about a codebase from repeated issues.
|
|
10025
|
+
|
|
10026
|
+
Given a batch of similar code quality issues, extract a LEARNING about the codebase's tendencies. Don't summarize or count issues - identify what this pattern reveals about the codebase or team habits.
|
|
10027
|
+
|
|
10028
|
+
Good learnings (what we want):
|
|
10029
|
+
- "Type safety tends to be weak in this codebase"
|
|
10030
|
+
- "Error handling is often skipped in async code"
|
|
10031
|
+
- "The dashboard module has inconsistent patterns"
|
|
10032
|
+
- "State management doesn't follow a clear convention"
|
|
10033
|
+
|
|
10034
|
+
Bad learnings (avoid these):
|
|
10035
|
+
- "5 type safety issues detected" (just counting)
|
|
10036
|
+
- "Consider adding null checks" (action without insight)
|
|
10037
|
+
- "Issues found in src/dashboard" (no actual learning)
|
|
10038
|
+
|
|
10039
|
+
Respond with JSON:
|
|
10040
|
+
{
|
|
10041
|
+
"learning": "One sentence stating what Trie learned about this codebase (a tendency, habit, or pattern)",
|
|
10042
|
+
"evidence": "Brief explanation of what patterns led to this conclusion",
|
|
10043
|
+
"suggestedAction": "What could improve this tendency",
|
|
10044
|
+
"category": "quality" | "security" | "performance" | "pattern",
|
|
10045
|
+
"confidence": 1-10 (how confident is this learning based on evidence)
|
|
10046
|
+
}`;
|
|
10047
|
+
var SignalSummarizer = class {
|
|
10048
|
+
client = null;
|
|
10049
|
+
projectPath;
|
|
10050
|
+
processedBatches = /* @__PURE__ */ new Set();
|
|
10051
|
+
constructor(projectPath) {
|
|
10052
|
+
this.projectPath = projectPath;
|
|
10053
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
10054
|
+
if (apiKey) {
|
|
10055
|
+
this.client = new Anthropic2({ apiKey });
|
|
10056
|
+
}
|
|
10057
|
+
}
|
|
10058
|
+
/**
|
|
10059
|
+
* Check if we have enough nudges to generate a signal
|
|
10060
|
+
*/
|
|
10061
|
+
async checkAndSummarize() {
|
|
10062
|
+
const storage = getStorage(this.projectPath);
|
|
10063
|
+
await storage.initialize();
|
|
10064
|
+
const nudges = await storage.queryNudges({ resolved: false, limit: 100 });
|
|
10065
|
+
if (nudges.length < SIGNAL_THRESHOLD) {
|
|
10066
|
+
return null;
|
|
10067
|
+
}
|
|
10068
|
+
const batches = this.groupNudges(nudges);
|
|
10069
|
+
for (const batch of batches) {
|
|
10070
|
+
if (batch.nudges.length >= SIGNAL_THRESHOLD && !this.processedBatches.has(batch.key)) {
|
|
10071
|
+
const insight = await this.summarizeBatch(batch);
|
|
10072
|
+
if (insight) {
|
|
10073
|
+
this.processedBatches.add(batch.key);
|
|
10074
|
+
return insight;
|
|
10075
|
+
}
|
|
10076
|
+
}
|
|
10077
|
+
}
|
|
10078
|
+
return null;
|
|
10079
|
+
}
|
|
10080
|
+
/**
|
|
10081
|
+
* Group nudges by similarity (same goal, same category, similar files)
|
|
10082
|
+
*/
|
|
10083
|
+
groupNudges(nudges) {
|
|
10084
|
+
const groups = /* @__PURE__ */ new Map();
|
|
10085
|
+
for (const nudge of nudges) {
|
|
10086
|
+
const goalMatch = nudge.message.match(/Goal "([^"]+)" violated/);
|
|
10087
|
+
const goalPattern = goalMatch?.[1];
|
|
10088
|
+
const key = goalPattern ? `goal:${goalPattern}` : `category:${nudge.category || "general"}`;
|
|
10089
|
+
if (!groups.has(key)) {
|
|
10090
|
+
groups.set(key, {
|
|
10091
|
+
key,
|
|
10092
|
+
nudges: [],
|
|
10093
|
+
category: nudge.category || "quality",
|
|
10094
|
+
goalPattern,
|
|
10095
|
+
files: []
|
|
10096
|
+
});
|
|
10097
|
+
}
|
|
10098
|
+
const batch = groups.get(key);
|
|
10099
|
+
batch.nudges.push(nudge);
|
|
10100
|
+
if (nudge.file && !batch.files.includes(nudge.file)) {
|
|
10101
|
+
batch.files.push(nudge.file);
|
|
10102
|
+
}
|
|
10103
|
+
}
|
|
10104
|
+
return Array.from(groups.values());
|
|
10105
|
+
}
|
|
10106
|
+
/**
|
|
10107
|
+
* Use AI to summarize a batch of nudges into an insight
|
|
10108
|
+
*/
|
|
10109
|
+
async summarizeBatch(batch) {
|
|
10110
|
+
if (!this.client) {
|
|
10111
|
+
return this.createFallbackInsight(batch);
|
|
10112
|
+
}
|
|
10113
|
+
try {
|
|
10114
|
+
const nudgeDescriptions = batch.nudges.slice(0, 10).map((n) => `- ${n.message}${n.file ? ` (${n.file})` : ""}`).join("\n");
|
|
10115
|
+
const response = await this.client.messages.create({
|
|
10116
|
+
model: "claude-3-haiku-20240307",
|
|
10117
|
+
max_tokens: 512,
|
|
10118
|
+
temperature: 0.3,
|
|
10119
|
+
messages: [{
|
|
10120
|
+
role: "user",
|
|
10121
|
+
content: `${SUMMARIZE_PROMPT}
|
|
10122
|
+
|
|
10123
|
+
Batch of ${batch.nudges.length} similar issues:
|
|
10124
|
+
${nudgeDescriptions}
|
|
10125
|
+
|
|
10126
|
+
Files affected: ${batch.files.slice(0, 5).join(", ")}${batch.files.length > 5 ? ` (+${batch.files.length - 5} more)` : ""}`
|
|
10127
|
+
}]
|
|
10128
|
+
});
|
|
10129
|
+
const text = response.content[0]?.type === "text" ? response.content[0].text : "";
|
|
10130
|
+
const parsed = this.parseResponse(text);
|
|
10131
|
+
if (!parsed) {
|
|
10132
|
+
return this.createFallbackInsight(batch);
|
|
10133
|
+
}
|
|
10134
|
+
const insight = {
|
|
10135
|
+
id: `signal-${createHash2("sha256").update(batch.key + Date.now()).digest("hex").slice(0, 12)}`,
|
|
10136
|
+
type: "observation",
|
|
10137
|
+
message: parsed.learning,
|
|
10138
|
+
context: parsed.evidence,
|
|
10139
|
+
suggestedAction: parsed.suggestedAction,
|
|
10140
|
+
relatedIssues: batch.nudges.map((n) => n.id),
|
|
10141
|
+
priority: parsed.confidence,
|
|
10142
|
+
timestamp: Date.now(),
|
|
10143
|
+
dismissed: false,
|
|
10144
|
+
category: parsed.category,
|
|
10145
|
+
details: {
|
|
10146
|
+
affectedFiles: batch.files,
|
|
10147
|
+
issueBreakdown: { [batch.category]: batch.nudges.length },
|
|
10148
|
+
summary: parsed.learning
|
|
10149
|
+
}
|
|
10150
|
+
};
|
|
10151
|
+
const insightStore = getInsightStore(this.projectPath);
|
|
10152
|
+
await insightStore.load();
|
|
10153
|
+
await insightStore.addInsight(insight);
|
|
10154
|
+
const storage = getStorage(this.projectPath);
|
|
10155
|
+
for (const nudge of batch.nudges) {
|
|
10156
|
+
await storage.resolveNudge(nudge.id, "auto-fixed");
|
|
10157
|
+
}
|
|
10158
|
+
return insight;
|
|
10159
|
+
} catch (error) {
|
|
10160
|
+
console.error("[SignalSummarizer] AI summarization failed:", error);
|
|
10161
|
+
return this.createFallbackInsight(batch);
|
|
10162
|
+
}
|
|
10163
|
+
}
|
|
10164
|
+
/**
|
|
10165
|
+
* Parse AI response
|
|
10166
|
+
*/
|
|
10167
|
+
parseResponse(text) {
|
|
10168
|
+
try {
|
|
10169
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
10170
|
+
if (!jsonMatch) return null;
|
|
10171
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
10172
|
+
return {
|
|
10173
|
+
learning: parsed.learning || "Pattern detected",
|
|
10174
|
+
evidence: parsed.evidence,
|
|
10175
|
+
suggestedAction: parsed.suggestedAction || "Review affected files",
|
|
10176
|
+
category: parsed.category || "quality",
|
|
10177
|
+
confidence: Math.min(10, Math.max(1, parsed.confidence || 5))
|
|
10178
|
+
};
|
|
10179
|
+
} catch {
|
|
10180
|
+
return null;
|
|
10181
|
+
}
|
|
10182
|
+
}
|
|
10183
|
+
/**
|
|
10184
|
+
* Create a fallback insight without AI
|
|
10185
|
+
*/
|
|
10186
|
+
createFallbackInsight(batch) {
|
|
10187
|
+
let message;
|
|
10188
|
+
let suggestedAction;
|
|
10189
|
+
if (batch.goalPattern) {
|
|
10190
|
+
const pattern = batch.goalPattern.toLowerCase();
|
|
10191
|
+
if (pattern.includes("type") || pattern.includes("safety")) {
|
|
10192
|
+
message = `Type safety tends to be weak in this codebase`;
|
|
10193
|
+
} else if (pattern.includes("error") || pattern.includes("handling")) {
|
|
10194
|
+
message = `Error handling is often incomplete`;
|
|
10195
|
+
} else if (pattern.includes("test")) {
|
|
10196
|
+
message = `Test coverage appears insufficient`;
|
|
10197
|
+
} else if (pattern.includes("security") || pattern.includes("auth")) {
|
|
10198
|
+
message = `Security practices need attention`;
|
|
10199
|
+
} else {
|
|
10200
|
+
message = `"${batch.goalPattern}" compliance tends to be inconsistent`;
|
|
10201
|
+
}
|
|
10202
|
+
suggestedAction = `Establish stricter conventions for ${pattern}`;
|
|
10203
|
+
} else {
|
|
10204
|
+
if (batch.category === "security") {
|
|
10205
|
+
message = `Security practices need strengthening`;
|
|
10206
|
+
} else if (batch.category === "performance") {
|
|
10207
|
+
message = `Performance optimizations are often overlooked`;
|
|
10208
|
+
} else {
|
|
10209
|
+
message = `Code quality patterns are inconsistent`;
|
|
10210
|
+
}
|
|
10211
|
+
suggestedAction = `Review ${batch.category} conventions across the codebase`;
|
|
10212
|
+
}
|
|
10213
|
+
return {
|
|
10214
|
+
id: `signal-${createHash2("sha256").update(batch.key + Date.now()).digest("hex").slice(0, 12)}`,
|
|
10215
|
+
type: "observation",
|
|
10216
|
+
message,
|
|
10217
|
+
suggestedAction,
|
|
10218
|
+
relatedIssues: batch.nudges.map((n) => n.id),
|
|
10219
|
+
priority: 5,
|
|
10220
|
+
timestamp: Date.now(),
|
|
10221
|
+
dismissed: false,
|
|
10222
|
+
category: batch.category || "quality",
|
|
10223
|
+
details: {
|
|
10224
|
+
affectedFiles: batch.files,
|
|
10225
|
+
issueBreakdown: { [batch.category]: batch.nudges.length }
|
|
10226
|
+
}
|
|
10227
|
+
};
|
|
10228
|
+
}
|
|
10229
|
+
/**
|
|
10230
|
+
* Force summarization of all current nudge batches
|
|
10231
|
+
*/
|
|
10232
|
+
async summarizeAll() {
|
|
10233
|
+
const storage = getStorage(this.projectPath);
|
|
10234
|
+
await storage.initialize();
|
|
10235
|
+
const nudges = await storage.queryNudges({ resolved: false, limit: 100 });
|
|
10236
|
+
const batches = this.groupNudges(nudges);
|
|
10237
|
+
const insights = [];
|
|
10238
|
+
for (const batch of batches) {
|
|
10239
|
+
if (batch.nudges.length >= SIGNAL_THRESHOLD) {
|
|
10240
|
+
const insight = await this.summarizeBatch(batch);
|
|
10241
|
+
if (insight) {
|
|
10242
|
+
insights.push(insight);
|
|
10243
|
+
}
|
|
10244
|
+
}
|
|
10245
|
+
}
|
|
10246
|
+
return insights;
|
|
10247
|
+
}
|
|
10248
|
+
};
|
|
10249
|
+
var summarizers = /* @__PURE__ */ new Map();
|
|
10250
|
+
function getSignalSummarizer(projectPath) {
|
|
10251
|
+
let summarizer = summarizers.get(projectPath);
|
|
10252
|
+
if (!summarizer) {
|
|
10253
|
+
summarizer = new SignalSummarizer(projectPath);
|
|
10254
|
+
summarizers.set(projectPath, summarizer);
|
|
10255
|
+
}
|
|
10256
|
+
return summarizer;
|
|
10257
|
+
}
|
|
10258
|
+
|
|
10259
|
+
// src/tools/watch.ts
|
|
9911
10260
|
var WATCH_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
9912
10261
|
".ts",
|
|
9913
10262
|
".tsx",
|
|
@@ -11277,7 +11626,7 @@ ${recentNudges || "(none)"}
|
|
|
11277
11626
|
*/
|
|
11278
11627
|
async persistNudge(params) {
|
|
11279
11628
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
11280
|
-
const nudgeId =
|
|
11629
|
+
const nudgeId = createHash3("sha256").update(`${params.message}|${params.file || ""}|${timestamp}`).digest("hex").slice(0, 16);
|
|
11281
11630
|
const nudge = {
|
|
11282
11631
|
id: nudgeId,
|
|
11283
11632
|
message: params.message,
|
|
@@ -11304,10 +11653,46 @@ ${recentNudges || "(none)"}
|
|
|
11304
11653
|
const storage = getStorage(this.watchedDirectory);
|
|
11305
11654
|
await storage.storeNudge(nudge);
|
|
11306
11655
|
console.debug(`[Watch] \u2713 Persisted nudge to storage: ${nudge.message.slice(0, 60)}...`);
|
|
11656
|
+
void this.checkSignalThreshold();
|
|
11307
11657
|
} catch (error) {
|
|
11308
11658
|
console.error("[Watch] Failed to persist nudge to storage:", error);
|
|
11309
11659
|
}
|
|
11310
11660
|
}
|
|
11661
|
+
/**
|
|
11662
|
+
* Check if we have enough nudges (5+) to generate an AI-summarized signal.
|
|
11663
|
+
* Runs periodically after nudge persistence to batch similar issues into insights.
|
|
11664
|
+
*/
|
|
11665
|
+
async checkSignalThreshold() {
|
|
11666
|
+
try {
|
|
11667
|
+
const summarizer = getSignalSummarizer(this.watchedDirectory);
|
|
11668
|
+
const insight = await summarizer.checkAndSummarize();
|
|
11669
|
+
if (insight) {
|
|
11670
|
+
getOutputManager().nudge(
|
|
11671
|
+
`Trie learned: ${insight.message}`,
|
|
11672
|
+
"info",
|
|
11673
|
+
void 0,
|
|
11674
|
+
15e3
|
|
11675
|
+
);
|
|
11676
|
+
if (!isInteractiveMode()) {
|
|
11677
|
+
console.error(` [+] Learning: ${insight.message}`);
|
|
11678
|
+
if (insight.suggestedAction) {
|
|
11679
|
+
console.error(` Suggestion: ${insight.suggestedAction}`);
|
|
11680
|
+
}
|
|
11681
|
+
}
|
|
11682
|
+
if (this.streamingManager) {
|
|
11683
|
+
this.streamingManager.reportSignalExtraction({
|
|
11684
|
+
governance: 1,
|
|
11685
|
+
// Insights are a form of governance
|
|
11686
|
+
facts: 0,
|
|
11687
|
+
blockers: 0,
|
|
11688
|
+
questions: 0
|
|
11689
|
+
});
|
|
11690
|
+
}
|
|
11691
|
+
}
|
|
11692
|
+
} catch (error) {
|
|
11693
|
+
console.debug("[Watch] Signal threshold check failed:", error);
|
|
11694
|
+
}
|
|
11695
|
+
}
|
|
11311
11696
|
getNudges() {
|
|
11312
11697
|
return {
|
|
11313
11698
|
content: [
|
|
@@ -11356,6 +11741,7 @@ export {
|
|
|
11356
11741
|
TrieGetBlockersTool,
|
|
11357
11742
|
TrieGetRelatedGovernanceTool,
|
|
11358
11743
|
TrieGetRelatedDecisionsTool,
|
|
11744
|
+
TrieGetNudgesTool,
|
|
11359
11745
|
TrieQueryContextTool,
|
|
11360
11746
|
TrieQueryLedgerBlocksTool,
|
|
11361
11747
|
handleCheckpointTool,
|
|
@@ -11364,4 +11750,4 @@ export {
|
|
|
11364
11750
|
InteractiveDashboard,
|
|
11365
11751
|
TrieWatchTool
|
|
11366
11752
|
};
|
|
11367
|
-
//# sourceMappingURL=chunk-
|
|
11753
|
+
//# sourceMappingURL=chunk-D6E4Q4I6.js.map
|