@triedotdev/mcp 1.0.127 → 1.0.129
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.
|
@@ -975,6 +975,8 @@ function Footer() {
|
|
|
975
975
|
hints = narrow ? "enter esc" : "enter save \xB7 esc cancel";
|
|
976
976
|
} else if (view === "hypotheses" && hypothesesPanel.inputMode === "add") {
|
|
977
977
|
hints = narrow ? "enter esc" : "enter save \xB7 esc cancel";
|
|
978
|
+
} else if (view === "chat" || view === "chat-archive") {
|
|
979
|
+
hints = "";
|
|
978
980
|
} else {
|
|
979
981
|
const hintMap = narrow ? CONTEXT_HINTS_SHORT : CONTEXT_HINTS;
|
|
980
982
|
hints = hintMap[view] || (narrow ? "/" : "/ help");
|
|
@@ -995,7 +997,7 @@ function Footer() {
|
|
|
995
997
|
!isLast && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: " \xB7 " })
|
|
996
998
|
] }, v);
|
|
997
999
|
}) }),
|
|
998
|
-
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
1000
|
+
hints && /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
999
1001
|
hints,
|
|
1000
1002
|
" \xB7 q quit"
|
|
1001
1003
|
] })
|
|
@@ -1016,7 +1018,7 @@ function Footer() {
|
|
|
1016
1018
|
!isLast && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: " \xB7 " })
|
|
1017
1019
|
] }, v);
|
|
1018
1020
|
}) }),
|
|
1019
|
-
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
1021
|
+
hints && /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
1020
1022
|
hints,
|
|
1021
1023
|
" \xB7 q quit"
|
|
1022
1024
|
] })
|
|
@@ -1043,12 +1045,12 @@ function Notification() {
|
|
|
1043
1045
|
}
|
|
1044
1046
|
|
|
1045
1047
|
// src/cli/dashboard/components/ConfigDialog.tsx
|
|
1046
|
-
import { useState } from "react";
|
|
1048
|
+
import React3, { useState } from "react";
|
|
1047
1049
|
import { Box as Box4, Text as Text4, useInput } from "ink";
|
|
1048
1050
|
import { existsSync } from "fs";
|
|
1049
1051
|
import { rm } from "fs/promises";
|
|
1050
1052
|
import { join } from "path";
|
|
1051
|
-
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1053
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1052
1054
|
function maskKey(key) {
|
|
1053
1055
|
if (!key || key.length < 12) return "Not set";
|
|
1054
1056
|
return key.slice(0, 7) + "..." + key.slice(-4);
|
|
@@ -1062,11 +1064,33 @@ function ConfigDialog({ onClose }) {
|
|
|
1062
1064
|
const [editIsText, setEditIsText] = useState(false);
|
|
1063
1065
|
const [showConfirmClear, setShowConfirmClear] = useState(false);
|
|
1064
1066
|
const [clearingMemory, setClearingMemory] = useState(false);
|
|
1067
|
+
const [indexStats, setIndexStats] = useState(null);
|
|
1068
|
+
const [indexing, setIndexing] = useState(false);
|
|
1065
1069
|
const config = state.agentConfig;
|
|
1070
|
+
React3.useEffect(() => {
|
|
1071
|
+
if (section === "codebaseIndex") {
|
|
1072
|
+
const loadStats = async () => {
|
|
1073
|
+
try {
|
|
1074
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1075
|
+
const { CodebaseIndex } = await import("./codebase-index-CR6Q2HEI.js");
|
|
1076
|
+
const index = new CodebaseIndex(workDir);
|
|
1077
|
+
const stats = index.getStats();
|
|
1078
|
+
setIndexStats({
|
|
1079
|
+
fileCount: stats.fileCount,
|
|
1080
|
+
lastUpdated: stats.lastUpdated || "Never"
|
|
1081
|
+
});
|
|
1082
|
+
} catch {
|
|
1083
|
+
setIndexStats(null);
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
void loadStats();
|
|
1087
|
+
}
|
|
1088
|
+
}, [section]);
|
|
1066
1089
|
const currentKeyDisplay = isAIAvailable() ? maskKey(getKeyFromKeychain() || process.env.ANTHROPIC_API_KEY || null) : "Not set";
|
|
1067
1090
|
const keyActive = isAIAvailable();
|
|
1068
1091
|
const mainMenu = [
|
|
1069
1092
|
{ label: "API Keys", key: "apiKeys", value: keyActive ? "Active" : "Not set", section: "main" },
|
|
1093
|
+
{ label: "Codebase Index", key: "codebaseIndex", value: "Stats & Re-index", section: "main" },
|
|
1070
1094
|
{ label: "AI Watcher", key: "aiWatcher", value: config.aiWatcher.enabled ? `${(config.aiWatcher.hourlyTokenLimit / 1e3).toFixed(0)}k/hr` : "Off", section: "main" },
|
|
1071
1095
|
{ label: "Performance", key: "performance", value: `${config.performance.maxConcurrency} concurrent`, section: "main" },
|
|
1072
1096
|
{ label: "Risk Thresholds", key: "riskThresholds", value: `critical: ${config.riskThresholds.critical}%`, section: "main" },
|
|
@@ -1098,7 +1122,11 @@ function ConfigDialog({ onClose }) {
|
|
|
1098
1122
|
const memoryItems = [
|
|
1099
1123
|
{ label: "Clear All Memory", key: "clearAll", value: "Reset ledger, context graph", section: "memory" }
|
|
1100
1124
|
];
|
|
1101
|
-
const
|
|
1125
|
+
const codebaseIndexItems = [
|
|
1126
|
+
{ label: "Re-index Codebase", key: "reindex", value: "Rebuild full index", section: "codebaseIndex" },
|
|
1127
|
+
{ label: "Clear Index", key: "clearIndex", value: "Delete index cache", section: "codebaseIndex" }
|
|
1128
|
+
];
|
|
1129
|
+
const items = section === "main" ? mainMenu : section === "apiKeys" ? apiKeysItems : section === "performance" ? performanceItems : section === "riskThresholds" ? riskItems : section === "aiWatcher" ? aiWatcherItems : section === "memory" ? memoryItems : section === "codebaseIndex" ? codebaseIndexItems : mainMenu;
|
|
1102
1130
|
useInput((_input, key) => {
|
|
1103
1131
|
if (showConfirmClear) {
|
|
1104
1132
|
if (_input === "y" || _input === "Y") {
|
|
@@ -1191,6 +1219,40 @@ function ConfigDialog({ onClose }) {
|
|
|
1191
1219
|
if (item && item.key === "clearAll") {
|
|
1192
1220
|
setShowConfirmClear(true);
|
|
1193
1221
|
}
|
|
1222
|
+
} else if (section === "codebaseIndex") {
|
|
1223
|
+
const item = items[selectedIndex];
|
|
1224
|
+
if (item && item.key === "reindex") {
|
|
1225
|
+
setIndexing(true);
|
|
1226
|
+
reindexCodebase().then(() => {
|
|
1227
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Codebase re-indexed successfully" });
|
|
1228
|
+
setIndexing(false);
|
|
1229
|
+
const loadStats = async () => {
|
|
1230
|
+
try {
|
|
1231
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1232
|
+
const { CodebaseIndex } = await import("./codebase-index-CR6Q2HEI.js");
|
|
1233
|
+
const index = new CodebaseIndex(workDir);
|
|
1234
|
+
const stats = index.getStats();
|
|
1235
|
+
setIndexStats({
|
|
1236
|
+
fileCount: stats.fileCount,
|
|
1237
|
+
lastUpdated: stats.lastUpdated || "Never"
|
|
1238
|
+
});
|
|
1239
|
+
} catch {
|
|
1240
|
+
setIndexStats(null);
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
void loadStats();
|
|
1244
|
+
}).catch(() => {
|
|
1245
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Failed to re-index codebase" });
|
|
1246
|
+
setIndexing(false);
|
|
1247
|
+
});
|
|
1248
|
+
} else if (item && item.key === "clearIndex") {
|
|
1249
|
+
clearCodebaseIndex().then(() => {
|
|
1250
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Index cleared" });
|
|
1251
|
+
setIndexStats({ fileCount: 0, lastUpdated: "Never" });
|
|
1252
|
+
}).catch(() => {
|
|
1253
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Failed to clear index" });
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1194
1256
|
} else {
|
|
1195
1257
|
const item = items[selectedIndex];
|
|
1196
1258
|
if (item) {
|
|
@@ -1213,7 +1275,7 @@ function ConfigDialog({ onClose }) {
|
|
|
1213
1275
|
}
|
|
1214
1276
|
}
|
|
1215
1277
|
});
|
|
1216
|
-
const sectionTitle = section === "main" ? "Settings" : section === "apiKeys" ? "API Keys" : section === "aiWatcher" ? "AI Watcher" : section === "performance" ? "Performance" : section === "riskThresholds" ? "Risk Thresholds" : section === "memory" ? "Memory" : "Settings";
|
|
1278
|
+
const sectionTitle = section === "main" ? "Settings" : section === "apiKeys" ? "API Keys" : section === "aiWatcher" ? "AI Watcher" : section === "performance" ? "Performance" : section === "riskThresholds" ? "Risk Thresholds" : section === "memory" ? "Memory" : section === "codebaseIndex" ? "Codebase Index" : "Settings";
|
|
1217
1279
|
async function clearMemory() {
|
|
1218
1280
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1219
1281
|
const trieDir = getTrieDirectory(workDir);
|
|
@@ -1232,6 +1294,40 @@ function ConfigDialog({ onClose }) {
|
|
|
1232
1294
|
}
|
|
1233
1295
|
}
|
|
1234
1296
|
}
|
|
1297
|
+
async function clearCodebaseIndex() {
|
|
1298
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1299
|
+
const trieDir = getTrieDirectory(workDir);
|
|
1300
|
+
const indexFile = join(trieDir, "codebase-index.json");
|
|
1301
|
+
if (existsSync(indexFile)) {
|
|
1302
|
+
await rm(indexFile, { force: true });
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
async function reindexCodebase() {
|
|
1306
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1307
|
+
const { CodebaseIndex } = await import("./codebase-index-CR6Q2HEI.js");
|
|
1308
|
+
const { glob } = await import("glob");
|
|
1309
|
+
const index = new CodebaseIndex(workDir);
|
|
1310
|
+
const indexPattern = `${workDir}/**/*.{ts,tsx,js,jsx,mjs,vue,svelte,astro,py,go,rs,java,c,cpp,h,hpp,cs,rb,php,css,scss,html}`;
|
|
1311
|
+
const indexFiles = await glob(indexPattern, {
|
|
1312
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.git/**", "**/.trie/**", "**/coverage/**"],
|
|
1313
|
+
nodir: true
|
|
1314
|
+
});
|
|
1315
|
+
let indexed = 0;
|
|
1316
|
+
const total = Math.min(indexFiles.length, 500);
|
|
1317
|
+
for (let i = 0; i < total; i++) {
|
|
1318
|
+
const filePath = indexFiles[i];
|
|
1319
|
+
if (!filePath) continue;
|
|
1320
|
+
let relativePath = filePath;
|
|
1321
|
+
if (filePath.toLowerCase().startsWith(workDir.toLowerCase() + "/")) {
|
|
1322
|
+
relativePath = filePath.slice(workDir.length + 1);
|
|
1323
|
+
} else if (filePath.startsWith("/")) {
|
|
1324
|
+
continue;
|
|
1325
|
+
}
|
|
1326
|
+
const result = await index.indexFile(relativePath);
|
|
1327
|
+
if (result) indexed++;
|
|
1328
|
+
}
|
|
1329
|
+
await index.save();
|
|
1330
|
+
}
|
|
1235
1331
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, children: [
|
|
1236
1332
|
/* @__PURE__ */ jsx5(Text4, { bold: true, children: sectionTitle }),
|
|
1237
1333
|
showConfirmClear && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
@@ -1251,6 +1347,35 @@ function ConfigDialog({ onClose }) {
|
|
|
1251
1347
|
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Reset ledger, context graph, issue store" }),
|
|
1252
1348
|
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to clear \xB7 esc back" })
|
|
1253
1349
|
] }),
|
|
1350
|
+
!showConfirmClear && section === "codebaseIndex" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1351
|
+
indexStats ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1352
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1353
|
+
" ",
|
|
1354
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, children: "Files indexed:" }),
|
|
1355
|
+
" ",
|
|
1356
|
+
indexStats.fileCount
|
|
1357
|
+
] }),
|
|
1358
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1359
|
+
" ",
|
|
1360
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, children: "Last updated:" }),
|
|
1361
|
+
" ",
|
|
1362
|
+
indexStats.lastUpdated
|
|
1363
|
+
] }),
|
|
1364
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, marginTop: 1, children: " Actions:" })
|
|
1365
|
+
] }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Loading index stats..." }),
|
|
1366
|
+
codebaseIndexItems.map((item, idx) => {
|
|
1367
|
+
const isSelected = selectedIndex === idx;
|
|
1368
|
+
return /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1369
|
+
isSelected ? /* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "> " }) : " ",
|
|
1370
|
+
/* @__PURE__ */ jsx5(Text4, { bold: isSelected, children: item.label }),
|
|
1371
|
+
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
1372
|
+
" ",
|
|
1373
|
+
item.value
|
|
1374
|
+
] })
|
|
1375
|
+
] }, item.key);
|
|
1376
|
+
}),
|
|
1377
|
+
indexing ? /* @__PURE__ */ jsx5(Text4, { dimColor: true, marginTop: 1, children: " Re-indexing codebase..." }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, marginTop: 1, children: " enter to execute \xB7 esc back" })
|
|
1378
|
+
] }),
|
|
1254
1379
|
!showConfirmClear && section === "apiKeys" && !editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1255
1380
|
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1256
1381
|
" ",
|
|
@@ -1268,7 +1393,7 @@ function ConfigDialog({ onClose }) {
|
|
|
1268
1393
|
] }) }),
|
|
1269
1394
|
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
1270
1395
|
] }),
|
|
1271
|
-
!showConfirmClear && section !== "apiKeys" && section !== "memory" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1396
|
+
!showConfirmClear && section !== "apiKeys" && section !== "memory" && section !== "codebaseIndex" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1272
1397
|
items.map((item, idx) => {
|
|
1273
1398
|
const isSelected = selectedIndex === idx;
|
|
1274
1399
|
return /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
@@ -1406,7 +1531,7 @@ function HelpDialog({ view }) {
|
|
|
1406
1531
|
|
|
1407
1532
|
// src/cli/dashboard/views/OverviewView.tsx
|
|
1408
1533
|
import { Box as Box6, Text as Text6, useInput as useInput2, useStdout as useStdout4 } from "ink";
|
|
1409
|
-
import { Fragment, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1534
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1410
1535
|
function truncate(str, max) {
|
|
1411
1536
|
return str.length > max ? str.slice(0, max - 1) + "..." : str;
|
|
1412
1537
|
}
|
|
@@ -1504,7 +1629,7 @@ function OverviewView() {
|
|
|
1504
1629
|
fix.confidence,
|
|
1505
1630
|
"%"
|
|
1506
1631
|
] }),
|
|
1507
|
-
narrow ? fix.status === "applying" && /* @__PURE__ */ jsx7(Text6, { color: "cyan", children: " applying..." }) : /* @__PURE__ */ jsxs6(
|
|
1632
|
+
narrow ? fix.status === "applying" && /* @__PURE__ */ jsx7(Text6, { color: "cyan", children: " applying..." }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1508
1633
|
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1509
1634
|
" confidence fix: ",
|
|
1510
1635
|
truncate(fix.suggestedFix, contentWidth - 25)
|
|
@@ -1762,7 +1887,7 @@ function AgentView() {
|
|
|
1762
1887
|
// src/cli/dashboard/views/GoalsView.tsx
|
|
1763
1888
|
import { useCallback as useCallback2 } from "react";
|
|
1764
1889
|
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
1765
|
-
import { Fragment as
|
|
1890
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1766
1891
|
function calculateGoalProgress(goal) {
|
|
1767
1892
|
if (goal.target <= 0) return 0;
|
|
1768
1893
|
const startValue = goal.startValue ?? goal.currentValue;
|
|
@@ -1886,14 +2011,7 @@ function GoalsView() {
|
|
|
1886
2011
|
const goal = goalsPanel.goals.find((g) => g.id === goalId);
|
|
1887
2012
|
if (!goal) return;
|
|
1888
2013
|
dispatch({ type: "ADD_ACTIVITY", message: `Checking goal: ${goal.description.slice(0, 30)}...` });
|
|
1889
|
-
|
|
1890
|
-
const codebaseIndex = new CodebaseIndex(workDir);
|
|
1891
|
-
if (codebaseIndex.isEmpty()) {
|
|
1892
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `Building codebase index (one-time)... This will speed up future checks.`, severity: "info", autoHideMs: 1e4 });
|
|
1893
|
-
dispatch({ type: "ADD_ACTIVITY", message: `Building codebase index...` });
|
|
1894
|
-
} else {
|
|
1895
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `Scanning files...`, severity: "info", autoHideMs: 5e3 });
|
|
1896
|
-
}
|
|
2014
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Scanning files...`, severity: "info", autoHideMs: 5e3 });
|
|
1897
2015
|
const { checkFilesForGoalViolations } = await import("./goal-validator-NLOJJ7FF.js");
|
|
1898
2016
|
const violations = await checkFilesForGoalViolations([goal], workDir);
|
|
1899
2017
|
if (violations.length === 0) {
|
|
@@ -1962,7 +2080,7 @@ function GoalsView() {
|
|
|
1962
2080
|
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "|" })
|
|
1963
2081
|
] }) }),
|
|
1964
2082
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
1965
|
-
] }) : /* @__PURE__ */ jsx9(
|
|
2083
|
+
] }) : /* @__PURE__ */ jsx9(Fragment3, { children: goalsPanel.goals.length === 0 ? /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " No goals yet. Press a to add one." }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1966
2084
|
activeGoals.length === 0 && goalsPanel.goals.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginBottom: 1, paddingX: 1, borderStyle: "round", borderColor: "yellow", children: [
|
|
1967
2085
|
/* @__PURE__ */ jsx9(Text8, { color: "yellow", bold: true, children: "\u26A0 No Active Goals" }),
|
|
1968
2086
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Goals exist but none are active. Violations won't be detected." }),
|
|
@@ -2020,7 +2138,7 @@ function GoalsView() {
|
|
|
2020
2138
|
// src/cli/dashboard/views/HypothesesView.tsx
|
|
2021
2139
|
import { useCallback as useCallback3 } from "react";
|
|
2022
2140
|
import { Box as Box9, Text as Text9, useInput as useInput5 } from "ink";
|
|
2023
|
-
import { Fragment as
|
|
2141
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2024
2142
|
function HypothesesView() {
|
|
2025
2143
|
const { state, dispatch } = useDashboard();
|
|
2026
2144
|
const { hypothesesPanel } = state;
|
|
@@ -2095,14 +2213,7 @@ function HypothesesView() {
|
|
|
2095
2213
|
const hypo = hypothesesPanel.hypotheses.find((h) => h.id === hypoId);
|
|
2096
2214
|
if (!hypo) return;
|
|
2097
2215
|
dispatch({ type: "ADD_ACTIVITY", message: `Testing hypothesis: ${hypo.statement.slice(0, 30)}...` });
|
|
2098
|
-
|
|
2099
|
-
const codebaseIndex = new CodebaseIndex(workDir);
|
|
2100
|
-
if (codebaseIndex.isEmpty()) {
|
|
2101
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `Building codebase index (one-time)...`, severity: "info", autoHideMs: 8e3 });
|
|
2102
|
-
dispatch({ type: "ADD_ACTIVITY", message: `Building codebase index...` });
|
|
2103
|
-
} else {
|
|
2104
|
-
dispatch({ type: "SHOW_NOTIFICATION", message: `Gathering evidence for hypothesis...`, severity: "info", autoHideMs: 3e3 });
|
|
2105
|
-
}
|
|
2216
|
+
dispatch({ type: "SHOW_NOTIFICATION", message: `Gathering evidence for hypothesis...`, severity: "info", autoHideMs: 3e3 });
|
|
2106
2217
|
const { gatherEvidenceForHypothesis } = await import("./hypothesis-HFYZNIMZ.js");
|
|
2107
2218
|
const evidence = await gatherEvidenceForHypothesis(hypoId, workDir);
|
|
2108
2219
|
if (evidence.length === 0) {
|
|
@@ -2164,7 +2275,7 @@ function HypothesesView() {
|
|
|
2164
2275
|
/* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "|" })
|
|
2165
2276
|
] }) }),
|
|
2166
2277
|
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2167
|
-
] }) : /* @__PURE__ */ jsx10(
|
|
2278
|
+
] }) : /* @__PURE__ */ jsx10(Fragment4, { children: hypothesesPanel.hypotheses.length === 0 ? /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " No hypotheses yet. Press a to add one." }) : /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
2168
2279
|
testing.map((hypo, idx) => {
|
|
2169
2280
|
const isSelected = hypothesesPanel.selectedIndex === idx;
|
|
2170
2281
|
const conf = Math.round(hypo.confidence * 100);
|
|
@@ -2217,7 +2328,7 @@ function HypothesesView() {
|
|
|
2217
2328
|
// src/cli/dashboard/views/MemoryTreeView.tsx
|
|
2218
2329
|
import { useEffect as useEffect2, useCallback as useCallback4 } from "react";
|
|
2219
2330
|
import { Box as Box10, Text as Text10, useInput as useInput6 } from "ink";
|
|
2220
|
-
import { Fragment as
|
|
2331
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2221
2332
|
function timeAgo2(iso) {
|
|
2222
2333
|
const ms = Date.now() - new Date(iso).getTime();
|
|
2223
2334
|
const mins = Math.floor(ms / 6e4);
|
|
@@ -2385,7 +2496,7 @@ function MemoryTreeView() {
|
|
|
2385
2496
|
] })
|
|
2386
2497
|
] }, pattern.id);
|
|
2387
2498
|
}),
|
|
2388
|
-
hotspots.length > 0 && /* @__PURE__ */ jsxs10(
|
|
2499
|
+
hotspots.length > 0 && /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
2389
2500
|
renderHeader("hotspots", "Risk Hotspots", hotspots.length),
|
|
2390
2501
|
expandedNodes.has("hotspots") && hotspots.slice(0, 10).map((n) => {
|
|
2391
2502
|
const nodeId = `file-${n.id}`;
|
|
@@ -4981,6 +5092,30 @@ var CHAT_TOOLS = [
|
|
|
4981
5092
|
required: ["file", "goal", "violation"]
|
|
4982
5093
|
}
|
|
4983
5094
|
},
|
|
5095
|
+
{
|
|
5096
|
+
name: "trie_propose_fixes_batch",
|
|
5097
|
+
description: "Propose fixes for multiple goal violations at once. More efficient than calling trie_propose_fix multiple times. Use when the user wants to fix multiple violations.",
|
|
5098
|
+
input_schema: {
|
|
5099
|
+
type: "object",
|
|
5100
|
+
properties: {
|
|
5101
|
+
fixes: {
|
|
5102
|
+
type: "array",
|
|
5103
|
+
description: "Array of fix proposals",
|
|
5104
|
+
items: {
|
|
5105
|
+
type: "object",
|
|
5106
|
+
properties: {
|
|
5107
|
+
file: { type: "string", description: "File path with the goal violation" },
|
|
5108
|
+
goal: { type: "string", description: "The goal that was violated" },
|
|
5109
|
+
violation: { type: "string", description: "Description of the violation" },
|
|
5110
|
+
suggestedFix: { type: "string", description: "Suggested fix for the violation (optional)" }
|
|
5111
|
+
},
|
|
5112
|
+
required: ["file", "goal", "violation"]
|
|
5113
|
+
}
|
|
5114
|
+
}
|
|
5115
|
+
},
|
|
5116
|
+
required: ["fixes"]
|
|
5117
|
+
}
|
|
5118
|
+
},
|
|
4984
5119
|
{
|
|
4985
5120
|
name: "trie_search_files",
|
|
4986
5121
|
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.",
|
|
@@ -5193,6 +5328,38 @@ Type "yes" to proceed, or "no" to cancel.
|
|
|
5193
5328
|
|
|
5194
5329
|
[PENDING_FIX:${JSON.stringify(fixProposal)}]`;
|
|
5195
5330
|
}
|
|
5331
|
+
case "trie_propose_fixes_batch": {
|
|
5332
|
+
const fixes = input.fixes;
|
|
5333
|
+
if (!Array.isArray(fixes) || fixes.length === 0) {
|
|
5334
|
+
return "At least one fix is required.";
|
|
5335
|
+
}
|
|
5336
|
+
for (const fix of fixes) {
|
|
5337
|
+
if (!fix.file?.trim()) return "All fixes must have a file path.";
|
|
5338
|
+
if (!fix.goal?.trim()) return "All fixes must have a goal.";
|
|
5339
|
+
if (!fix.violation?.trim()) return "All fixes must have a violation description.";
|
|
5340
|
+
}
|
|
5341
|
+
const fixProposals = fixes.map((f) => ({
|
|
5342
|
+
file: f.file.trim(),
|
|
5343
|
+
goal: f.goal.trim(),
|
|
5344
|
+
violation: f.violation.trim(),
|
|
5345
|
+
suggestedFix: f.suggestedFix?.trim(),
|
|
5346
|
+
directory
|
|
5347
|
+
}));
|
|
5348
|
+
let message = `Found ${fixes.length} violation(s) to fix:
|
|
5349
|
+
|
|
5350
|
+
`;
|
|
5351
|
+
for (const fix of fixProposals) {
|
|
5352
|
+
message += `\u2022 ${fix.file}
|
|
5353
|
+
`;
|
|
5354
|
+
}
|
|
5355
|
+
message += `
|
|
5356
|
+
Type "yes to all" to fix all files, or "no" to cancel.`;
|
|
5357
|
+
for (const fixProposal of fixProposals) {
|
|
5358
|
+
message += `
|
|
5359
|
+
[PENDING_FIX:${JSON.stringify(fixProposal)}]`;
|
|
5360
|
+
}
|
|
5361
|
+
return message;
|
|
5362
|
+
}
|
|
5196
5363
|
case "trie_search_files": {
|
|
5197
5364
|
const pattern = String(input.pattern || "").trim();
|
|
5198
5365
|
const filePattern = input.filePattern ? String(input.filePattern).trim() : void 0;
|
|
@@ -5264,7 +5431,6 @@ ${truncated}`;
|
|
|
5264
5431
|
const goalId = input.goalId ? String(input.goalId).trim() : void 0;
|
|
5265
5432
|
try {
|
|
5266
5433
|
const { checkFilesForGoalViolations, getActiveGoals } = await import("./goal-validator-NLOJJ7FF.js");
|
|
5267
|
-
const { CodebaseIndex } = await import("./codebase-index-CR6Q2HEI.js");
|
|
5268
5434
|
const agentState = getGuardianState(directory);
|
|
5269
5435
|
await agentState.load();
|
|
5270
5436
|
const allGoals = await getActiveGoals(directory);
|
|
@@ -5272,13 +5438,11 @@ ${truncated}`;
|
|
|
5272
5438
|
if (goalsToCheck.length === 0) {
|
|
5273
5439
|
return goalId ? `No active goal found with ID: ${goalId}` : "No active goals to check. Add goals in the Goals view first.";
|
|
5274
5440
|
}
|
|
5275
|
-
const codebaseIndex = new CodebaseIndex(directory);
|
|
5276
|
-
const indexMessage = codebaseIndex.isEmpty() ? "\u{1F4CB} Building codebase index (one-time operation)...\n\n" : "";
|
|
5277
5441
|
const violations = await checkFilesForGoalViolations(goalsToCheck, directory);
|
|
5278
5442
|
if (violations.length === 0) {
|
|
5279
|
-
return
|
|
5443
|
+
return `\u2713 Scan complete! No violations found for ${goalsToCheck.length} goal(s).`;
|
|
5280
5444
|
}
|
|
5281
|
-
let result =
|
|
5445
|
+
let result = `Found ${violations.length} violation(s):
|
|
5282
5446
|
|
|
5283
5447
|
`;
|
|
5284
5448
|
for (const v of violations) {
|
|
@@ -5304,7 +5468,7 @@ ${truncated}`;
|
|
|
5304
5468
|
}
|
|
5305
5469
|
|
|
5306
5470
|
// src/cli/dashboard/views/ChatView.tsx
|
|
5307
|
-
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5471
|
+
import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5308
5472
|
var VISIBLE_MESSAGES = 8;
|
|
5309
5473
|
async function buildContext(workDir, dashboardState) {
|
|
5310
5474
|
const parts = [];
|
|
@@ -5428,14 +5592,17 @@ var SYSTEM_PROMPT = `You are Trie, a code guardian assistant embedded in a termi
|
|
|
5428
5592
|
|
|
5429
5593
|
**When user asks to fix violations:**
|
|
5430
5594
|
1. Look in "Recent goal violations (nudges)" section of project context
|
|
5431
|
-
2. Extract: file path, goal description, and violation details
|
|
5432
|
-
3.
|
|
5433
|
-
4.
|
|
5595
|
+
2. Extract: file path, goal description, and violation details for ALL files
|
|
5596
|
+
3. If multiple violations: Call trie_propose_fixes_batch ONCE with all fixes
|
|
5597
|
+
4. If single violation: Call trie_propose_fix once
|
|
5598
|
+
5. AFTER the tool call completes, the system will ask for user confirmation - do NOT add your own confirmation message
|
|
5599
|
+
6. When the user says "yes", "yes to all", or "no", the system handles spawning Claude Code automatically
|
|
5434
5600
|
|
|
5435
5601
|
Examples:
|
|
5436
5602
|
- User: "do we have emojis?" \u2192 Check nudges first. If none or unclear: Call trie_scan_for_goal_violations to scan the codebase.
|
|
5437
5603
|
- User: "run a full scan for emojis" \u2192 Call trie_scan_for_goal_violations directly.
|
|
5438
|
-
- User: "fix the emoji
|
|
5604
|
+
- User: "fix the emoji violations" \u2192 Find ALL emoji violations in nudges, call trie_propose_fixes_batch ONCE with all fixes, then STOP
|
|
5605
|
+
- User responds "yes to all" after proposal \u2192 Just say "Spawning Claude Code to fix all files..." The system handles it.
|
|
5439
5606
|
- 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.
|
|
5440
5607
|
|
|
5441
5608
|
Answer concisely. Reference specific files, decisions, and patterns when relevant.`;
|
|
@@ -5586,7 +5753,7 @@ ${contextBlock}`;
|
|
|
5586
5753
|
tools: CHAT_TOOLS,
|
|
5587
5754
|
executeTool,
|
|
5588
5755
|
maxTokens: 4096,
|
|
5589
|
-
maxToolRounds:
|
|
5756
|
+
maxToolRounds: 8
|
|
5590
5757
|
});
|
|
5591
5758
|
if (result.success) {
|
|
5592
5759
|
const action = {
|
|
@@ -5744,10 +5911,13 @@ ${contextBlock}`;
|
|
|
5744
5911
|
canScrollDown && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " \u2193 more messages below" }),
|
|
5745
5912
|
loading && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: " Thinking..." })
|
|
5746
5913
|
] }),
|
|
5747
|
-
/* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: "green", paddingX: 1, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */
|
|
5914
|
+
/* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: "green", paddingX: 1, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */ jsx13(Text12, { children: inputBuffer ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
5915
|
+
inputBuffer,
|
|
5916
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, color: "green", children: cursor })
|
|
5917
|
+
] }) : /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
5748
5918
|
/* @__PURE__ */ jsx13(Text12, { bold: true, color: "green", children: cursor }),
|
|
5749
|
-
|
|
5750
|
-
] }) })
|
|
5919
|
+
/* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Ask a question..." })
|
|
5920
|
+
] }) }) })
|
|
5751
5921
|
] });
|
|
5752
5922
|
}
|
|
5753
5923
|
function formatToolInput(input) {
|
|
@@ -6373,4 +6543,4 @@ export {
|
|
|
6373
6543
|
handleCheckpointTool,
|
|
6374
6544
|
InteractiveDashboard
|
|
6375
6545
|
};
|
|
6376
|
-
//# sourceMappingURL=chunk-
|
|
6546
|
+
//# sourceMappingURL=chunk-VHQBL2I7.js.map
|