@triedotdev/mcp 1.0.116 → 1.0.118
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-2764RZVV.js → chunk-OZGDXRLD.js} +372 -12
- package/dist/chunk-OZGDXRLD.js.map +1 -0
- package/dist/{chunk-SRQ4DNOP.js → chunk-PPZYVTUO.js} +67 -1
- package/dist/{chunk-SRQ4DNOP.js.map → chunk-PPZYVTUO.js.map} +1 -1
- package/dist/cli/main.js +1 -1
- package/dist/cli/yolo-daemon.js +2 -2
- package/dist/index.js +152 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2764RZVV.js.map +0 -1
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
perceiveCurrentChanges,
|
|
11
11
|
reasonAboutChangesHumanReadable,
|
|
12
12
|
saveCheckpoint
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PPZYVTUO.js";
|
|
14
14
|
import {
|
|
15
15
|
TieredStorage,
|
|
16
16
|
findCrossProjectPatterns,
|
|
@@ -526,12 +526,25 @@ function dashboardReducer(state, action) {
|
|
|
526
526
|
(ni) => !existing.some((ei) => ei.message === ni.message && !ei.dismissed)
|
|
527
527
|
);
|
|
528
528
|
const merged = [...newOnes, ...existing].slice(0, 50);
|
|
529
|
+
console.error("[State] ADD_INSIGHTS:", {
|
|
530
|
+
newCount: newOnes.length,
|
|
531
|
+
existingCount: existing.length,
|
|
532
|
+
mergedCount: merged.length,
|
|
533
|
+
newInsights: newOnes.map((i) => ({ id: i.id, type: i.type, message: i.message.slice(0, 50) }))
|
|
534
|
+
});
|
|
529
535
|
let s = { ...state, agentInsights: merged };
|
|
536
|
+
const newAlerts = newOnes.filter((i) => i.type === "warning" && !i.dismissed).length;
|
|
537
|
+
if (newAlerts > 0) {
|
|
538
|
+
s.unreadNudgesCount = state.unreadNudgesCount + newAlerts;
|
|
539
|
+
}
|
|
530
540
|
if (newOnes.length > 0) {
|
|
531
541
|
s = addActivity(s, `Trie Agent: ${newOnes.length} new insight${newOnes.length > 1 ? "s" : ""}`);
|
|
532
542
|
}
|
|
533
543
|
return s;
|
|
534
544
|
}
|
|
545
|
+
case "MARK_NUDGES_READ": {
|
|
546
|
+
return { ...state, unreadNudgesCount: 0 };
|
|
547
|
+
}
|
|
535
548
|
case "SET_AGENT_INITIALIZED":
|
|
536
549
|
return { ...state, agentInitialized: action.initialized };
|
|
537
550
|
case "SET_AGENCY_STATUS":
|
|
@@ -784,6 +797,7 @@ function createInitialState() {
|
|
|
784
797
|
agencyStatus: null,
|
|
785
798
|
selectedInsight: 0,
|
|
786
799
|
expandedInsight: null,
|
|
800
|
+
unreadNudgesCount: 0,
|
|
787
801
|
agentConfig: {
|
|
788
802
|
agentSmith: {
|
|
789
803
|
aiEnhancement: true,
|
|
@@ -887,7 +901,7 @@ var VIEW_SHORT = {
|
|
|
887
901
|
};
|
|
888
902
|
var TAB_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
889
903
|
var CONTEXT_HINTS = {
|
|
890
|
-
goals: "j/k nav \xB7 a add \xB7 enter complete \xB7 d delete",
|
|
904
|
+
goals: "j/k nav \xB7 a add \xB7 enter complete \xB7 d delete \xB7 c clear achieved",
|
|
891
905
|
hypotheses: "j/k nav \xB7 a add \xB7 v validate \xB7 x invalidate",
|
|
892
906
|
agent: "j/k nav \xB7 enter expand \xB7 d dismiss",
|
|
893
907
|
memory: "j/k nav \xB7 enter expand",
|
|
@@ -895,7 +909,7 @@ var CONTEXT_HINTS = {
|
|
|
895
909
|
rawlog: "n/p pages \xB7 b back"
|
|
896
910
|
};
|
|
897
911
|
var CONTEXT_HINTS_SHORT = {
|
|
898
|
-
goals: "j/k a d",
|
|
912
|
+
goals: "j/k a d c",
|
|
899
913
|
hypotheses: "j/k a v x",
|
|
900
914
|
agent: "j/k enter d",
|
|
901
915
|
memory: "j/k enter",
|
|
@@ -904,12 +918,13 @@ var CONTEXT_HINTS_SHORT = {
|
|
|
904
918
|
};
|
|
905
919
|
function Footer() {
|
|
906
920
|
const { state } = useDashboard();
|
|
907
|
-
const { view, goalsPanel, hypothesesPanel } = state;
|
|
921
|
+
const { view, goalsPanel, hypothesesPanel, unreadNudgesCount } = state;
|
|
908
922
|
const { stdout } = useStdout2();
|
|
909
923
|
const cols = stdout?.columns || 80;
|
|
910
924
|
const narrow = cols < 60;
|
|
911
925
|
const veryNarrow = cols < 40;
|
|
912
926
|
const labels = narrow ? VIEW_SHORT : VIEW_LABELS;
|
|
927
|
+
const hasUnreadNudges = unreadNudgesCount > 0;
|
|
913
928
|
let hints;
|
|
914
929
|
if (view === "goals" && goalsPanel.inputMode === "add") {
|
|
915
930
|
hints = narrow ? "enter esc" : "enter save \xB7 esc cancel";
|
|
@@ -921,7 +936,22 @@ function Footer() {
|
|
|
921
936
|
}
|
|
922
937
|
if (veryNarrow) {
|
|
923
938
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
|
|
924
|
-
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) =>
|
|
939
|
+
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => {
|
|
940
|
+
const isAgent = v === "agent";
|
|
941
|
+
const isCurrent = v === view;
|
|
942
|
+
if (isCurrent) {
|
|
943
|
+
return /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: labels[v] }, v);
|
|
944
|
+
} else if (isAgent && hasUnreadNudges) {
|
|
945
|
+
return /* @__PURE__ */ jsxs2(Text2, { color: "yellow", bold: true, children: [
|
|
946
|
+
labels[v],
|
|
947
|
+
" (",
|
|
948
|
+
unreadNudgesCount,
|
|
949
|
+
")"
|
|
950
|
+
] }, v);
|
|
951
|
+
} else {
|
|
952
|
+
return /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: labels[v] }, v);
|
|
953
|
+
}
|
|
954
|
+
}) }),
|
|
925
955
|
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
926
956
|
hints,
|
|
927
957
|
" \xB7 q quit"
|
|
@@ -929,7 +959,22 @@ function Footer() {
|
|
|
929
959
|
] });
|
|
930
960
|
}
|
|
931
961
|
return /* @__PURE__ */ jsxs2(Box2, { paddingX: 1, justifyContent: "space-between", children: [
|
|
932
|
-
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) =>
|
|
962
|
+
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => {
|
|
963
|
+
const isAgent = v === "agent";
|
|
964
|
+
const isCurrent = v === view;
|
|
965
|
+
if (isCurrent) {
|
|
966
|
+
return /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: labels[v] }, v);
|
|
967
|
+
} else if (isAgent && hasUnreadNudges) {
|
|
968
|
+
return /* @__PURE__ */ jsxs2(Text2, { color: "yellow", bold: true, children: [
|
|
969
|
+
labels[v],
|
|
970
|
+
" (",
|
|
971
|
+
unreadNudgesCount,
|
|
972
|
+
")"
|
|
973
|
+
] }, v);
|
|
974
|
+
} else {
|
|
975
|
+
return /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: labels[v] }, v);
|
|
976
|
+
}
|
|
977
|
+
}) }),
|
|
933
978
|
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
934
979
|
hints,
|
|
935
980
|
" \xB7 q quit"
|
|
@@ -1132,11 +1177,13 @@ function ConfigDialog({ onClose }) {
|
|
|
1132
1177
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1133
1178
|
const trieDir = getTrieDirectory(workDir);
|
|
1134
1179
|
const filesToDelete = [
|
|
1135
|
-
join(trieDir, "context
|
|
1180
|
+
join(trieDir, "context.db"),
|
|
1181
|
+
join(trieDir, "context.json"),
|
|
1136
1182
|
join(trieDir, "incident-trie.json"),
|
|
1137
1183
|
join(trieDir, "memory", "ledger.json"),
|
|
1138
1184
|
join(trieDir, "memory", "issue-store.db"),
|
|
1139
|
-
join(trieDir, "memory", "insights.json")
|
|
1185
|
+
join(trieDir, "memory", "insights.json"),
|
|
1186
|
+
join(trieDir, "memory", "issues.json")
|
|
1140
1187
|
];
|
|
1141
1188
|
for (const file of filesToDelete) {
|
|
1142
1189
|
if (existsSync(file)) {
|
|
@@ -1385,6 +1432,17 @@ function AgentView() {
|
|
|
1385
1432
|
const visibleInsights = getVisibleInsights(state);
|
|
1386
1433
|
const alerts = visibleInsights.filter((i) => i.type === "warning");
|
|
1387
1434
|
const { decisions, patterns, loaded } = agentBrain;
|
|
1435
|
+
useEffect(() => {
|
|
1436
|
+
if (agentInsights.length > 0 || visibleInsights.length > 0) {
|
|
1437
|
+
console.error("[AgentView Debug]", {
|
|
1438
|
+
totalInsights: agentInsights.length,
|
|
1439
|
+
visibleInsights: visibleInsights.length,
|
|
1440
|
+
alerts: alerts.length,
|
|
1441
|
+
insightTypes: agentInsights.map((i) => i.type),
|
|
1442
|
+
visibleTypes: visibleInsights.map((i) => i.type)
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
}, [agentInsights, visibleInsights, alerts]);
|
|
1388
1446
|
const loadBrain = useCallback(async () => {
|
|
1389
1447
|
try {
|
|
1390
1448
|
const workDir = getWorkingDirectory(void 0, true);
|
|
@@ -1405,6 +1463,11 @@ function AgentView() {
|
|
|
1405
1463
|
void loadBrain();
|
|
1406
1464
|
}
|
|
1407
1465
|
}, [loaded, loadBrain]);
|
|
1466
|
+
useEffect(() => {
|
|
1467
|
+
if (state.unreadNudgesCount > 0) {
|
|
1468
|
+
dispatch({ type: "MARK_NUDGES_READ" });
|
|
1469
|
+
}
|
|
1470
|
+
}, [dispatch, state.unreadNudgesCount]);
|
|
1408
1471
|
useInput3((input, key) => {
|
|
1409
1472
|
if (key.upArrow || input === "k") dispatch({ type: "NAVIGATE_UP" });
|
|
1410
1473
|
else if (key.downArrow || input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
@@ -1625,6 +1688,24 @@ function GoalsView() {
|
|
|
1625
1688
|
} catch {
|
|
1626
1689
|
}
|
|
1627
1690
|
}, [dispatch, refreshGoals]);
|
|
1691
|
+
const clearAchievedGoals = useCallback2(async () => {
|
|
1692
|
+
try {
|
|
1693
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1694
|
+
const agentState = getGuardianState(workDir);
|
|
1695
|
+
await agentState.load();
|
|
1696
|
+
const achieved = goalsPanel.goals.filter((g) => g.status === "achieved");
|
|
1697
|
+
if (achieved.length === 0) {
|
|
1698
|
+
dispatch({ type: "ADD_ACTIVITY", message: "No achieved goals to clear" });
|
|
1699
|
+
return;
|
|
1700
|
+
}
|
|
1701
|
+
for (const goal of achieved) {
|
|
1702
|
+
await agentState.deleteGoal(goal.id);
|
|
1703
|
+
}
|
|
1704
|
+
dispatch({ type: "ADD_ACTIVITY", message: `Cleared ${achieved.length} achieved goal${achieved.length > 1 ? "s" : ""}` });
|
|
1705
|
+
await refreshGoals();
|
|
1706
|
+
} catch {
|
|
1707
|
+
}
|
|
1708
|
+
}, [dispatch, refreshGoals, goalsPanel.goals]);
|
|
1628
1709
|
useInput4((_input, key) => {
|
|
1629
1710
|
if (goalsPanel.inputMode === "add") {
|
|
1630
1711
|
if (key.escape) {
|
|
@@ -1648,6 +1729,8 @@ function GoalsView() {
|
|
|
1648
1729
|
} else if (_input === "d") {
|
|
1649
1730
|
const selected = activeGoals[goalsPanel.selectedIndex];
|
|
1650
1731
|
if (selected) void deleteGoal(selected.id);
|
|
1732
|
+
} else if (_input === "c") {
|
|
1733
|
+
void clearAchievedGoals();
|
|
1651
1734
|
} else if (_input === "x") {
|
|
1652
1735
|
const completed = goalsPanel.goals.filter((g) => g.status === "achieved" || g.status === "failed");
|
|
1653
1736
|
if (completed[0]) void deleteGoal(completed[0].id);
|
|
@@ -4480,6 +4563,197 @@ ${checkpoint.files.length > 0 ? `**Files:** ${checkpoint.files.join(", ")}` : ""
|
|
|
4480
4563
|
|
|
4481
4564
|
// src/cli/dashboard/chat-tools.ts
|
|
4482
4565
|
import { createHash } from "crypto";
|
|
4566
|
+
|
|
4567
|
+
// src/utils/terminal-spawn.ts
|
|
4568
|
+
import { exec } from "child_process";
|
|
4569
|
+
import { promisify } from "util";
|
|
4570
|
+
import { platform } from "os";
|
|
4571
|
+
var execAsync = promisify(exec);
|
|
4572
|
+
async function spawnTerminal(options) {
|
|
4573
|
+
const { command, cwd, title, keepOpen = true } = options;
|
|
4574
|
+
const os = platform();
|
|
4575
|
+
if (os === "darwin") {
|
|
4576
|
+
await spawnMacOSTerminal(command, cwd, title, keepOpen);
|
|
4577
|
+
} else if (os === "linux") {
|
|
4578
|
+
await spawnLinuxTerminal(command, cwd, title, keepOpen);
|
|
4579
|
+
} else {
|
|
4580
|
+
throw new Error(`Terminal spawning not supported on ${os}`);
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
async function spawnMacOSTerminal(command, cwd, title, keepOpen) {
|
|
4584
|
+
const escapedCommand = command.replace(/'/g, `'"'"'`);
|
|
4585
|
+
const escapedCwd = cwd?.replace(/'/g, `'"'"'`) || process.cwd();
|
|
4586
|
+
const escapedTitle = title?.replace(/'/g, `'"'"'`) || "Trie Agent";
|
|
4587
|
+
const fullCommand = cwd ? `cd '${escapedCwd}' && ${command}` : command;
|
|
4588
|
+
const escapedFullCommand = fullCommand.replace(/'/g, `'"'"'`);
|
|
4589
|
+
const script = `
|
|
4590
|
+
tell application "Terminal"
|
|
4591
|
+
activate
|
|
4592
|
+
set newTab to do script "${escapedFullCommand}"
|
|
4593
|
+
set custom title of newTab to "${escapedTitle}"
|
|
4594
|
+
end tell
|
|
4595
|
+
`.trim();
|
|
4596
|
+
try {
|
|
4597
|
+
await execAsync(`osascript -e '${script.replace(/'/g, `'"'"'`)}'`);
|
|
4598
|
+
} catch (error) {
|
|
4599
|
+
console.error("Terminal.app spawn failed, trying fallback...");
|
|
4600
|
+
const shellCmd = keepOpen ? `${fullCommand}; exec bash` : fullCommand;
|
|
4601
|
+
await execAsync(`open -a Terminal "${escapedCwd}" --args -e "${shellCmd}"`);
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
async function spawnLinuxTerminal(command, cwd, title, keepOpen) {
|
|
4605
|
+
const workDir = cwd || process.cwd();
|
|
4606
|
+
const termTitle = title || "Trie Agent";
|
|
4607
|
+
const shellCmd = keepOpen ? `${command}; exec bash` : command;
|
|
4608
|
+
const terminals = [
|
|
4609
|
+
// GNOME Terminal
|
|
4610
|
+
{
|
|
4611
|
+
command: "gnome-terminal",
|
|
4612
|
+
args: `--working-directory="${workDir}" --title="${termTitle}" -- bash -c "${shellCmd}"`
|
|
4613
|
+
},
|
|
4614
|
+
// Konsole (KDE)
|
|
4615
|
+
{
|
|
4616
|
+
command: "konsole",
|
|
4617
|
+
args: `--workdir "${workDir}" --title "${termTitle}" -e bash -c "${shellCmd}"`
|
|
4618
|
+
},
|
|
4619
|
+
// xterm (fallback)
|
|
4620
|
+
{
|
|
4621
|
+
command: "xterm",
|
|
4622
|
+
args: `-T "${termTitle}" -e "cd '${workDir}' && ${shellCmd}"`
|
|
4623
|
+
}
|
|
4624
|
+
];
|
|
4625
|
+
for (const term of terminals) {
|
|
4626
|
+
try {
|
|
4627
|
+
await execAsync(`which ${term.command}`);
|
|
4628
|
+
await execAsync(`${term.command} ${term.args} &`);
|
|
4629
|
+
return;
|
|
4630
|
+
} catch {
|
|
4631
|
+
continue;
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4634
|
+
throw new Error("No supported terminal emulator found (tried: gnome-terminal, konsole, xterm)");
|
|
4635
|
+
}
|
|
4636
|
+
async function spawnClaudeCodeFix(options) {
|
|
4637
|
+
const { file, goal, violation, suggestedFix, cwd } = options;
|
|
4638
|
+
const fixScript = `
|
|
4639
|
+
#!/bin/bash
|
|
4640
|
+
set -e
|
|
4641
|
+
|
|
4642
|
+
echo "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
|
|
4643
|
+
echo "\u{1F527} Trie Agent - Automated Fix"
|
|
4644
|
+
echo "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
|
|
4645
|
+
echo ""
|
|
4646
|
+
echo "File: ${file}"
|
|
4647
|
+
echo "Goal: ${goal}"
|
|
4648
|
+
echo "Violation: ${violation}"
|
|
4649
|
+
${suggestedFix ? `echo "Suggested: ${suggestedFix}"` : ""}
|
|
4650
|
+
echo ""
|
|
4651
|
+
echo "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
|
|
4652
|
+
echo ""
|
|
4653
|
+
|
|
4654
|
+
# Check if file exists
|
|
4655
|
+
if [ ! -f "${file}" ]; then
|
|
4656
|
+
echo "\u274C Error: File not found: ${file}"
|
|
4657
|
+
exit 1
|
|
4658
|
+
fi
|
|
4659
|
+
|
|
4660
|
+
# Check if ANTHROPIC_API_KEY is set
|
|
4661
|
+
if [ -z "\${ANTHROPIC_API_KEY}" ]; then
|
|
4662
|
+
echo "\u274C Error: ANTHROPIC_API_KEY not set"
|
|
4663
|
+
echo ""
|
|
4664
|
+
echo "Please set your API key:"
|
|
4665
|
+
echo " export ANTHROPIC_API_KEY=sk-ant-api03-..."
|
|
4666
|
+
echo ""
|
|
4667
|
+
exit 1
|
|
4668
|
+
fi
|
|
4669
|
+
|
|
4670
|
+
echo "\u{1F4D6} Reading file..."
|
|
4671
|
+
FILE_CONTENT=$(cat "${file}")
|
|
4672
|
+
|
|
4673
|
+
echo "\u{1F916} Analyzing with Claude..."
|
|
4674
|
+
echo ""
|
|
4675
|
+
|
|
4676
|
+
# Create the fix prompt
|
|
4677
|
+
PROMPT="You are fixing a code quality violation.
|
|
4678
|
+
|
|
4679
|
+
Goal: ${goal}
|
|
4680
|
+
Violation: ${violation}
|
|
4681
|
+
${suggestedFix ? `Suggested fix: ${suggestedFix}` : ""}
|
|
4682
|
+
|
|
4683
|
+
File: ${file}
|
|
4684
|
+
|
|
4685
|
+
Current content:
|
|
4686
|
+
$FILE_CONTENT
|
|
4687
|
+
|
|
4688
|
+
Please fix the violation while:
|
|
4689
|
+
1. Preserving all functionality
|
|
4690
|
+
2. Maintaining code style
|
|
4691
|
+
3. Not breaking anything
|
|
4692
|
+
4. Following the goal exactly
|
|
4693
|
+
|
|
4694
|
+
Output ONLY the fixed file content, no explanations or markdown fences."
|
|
4695
|
+
|
|
4696
|
+
# Call Claude API to generate fix
|
|
4697
|
+
# Using npx to run a simple Node script
|
|
4698
|
+
FIXED_CONTENT=$(npx --yes -q tsx -e "
|
|
4699
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
4700
|
+
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
4701
|
+
const msg = await client.messages.create({
|
|
4702
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
4703
|
+
max_tokens: 8000,
|
|
4704
|
+
messages: [{ role: 'user', content: \\\`\${PROMPT}\\\` }]
|
|
4705
|
+
});
|
|
4706
|
+
const text = msg.content.find(c => c.type === 'text');
|
|
4707
|
+
console.log(text ? text.text : '');
|
|
4708
|
+
")
|
|
4709
|
+
|
|
4710
|
+
if [ -z "$FIXED_CONTENT" ]; then
|
|
4711
|
+
echo "\u274C Error: Claude did not generate a fix"
|
|
4712
|
+
exit 1
|
|
4713
|
+
fi
|
|
4714
|
+
|
|
4715
|
+
echo "\u2705 Fix generated!"
|
|
4716
|
+
echo ""
|
|
4717
|
+
|
|
4718
|
+
# Show diff
|
|
4719
|
+
echo "\u{1F4CA} Changes:"
|
|
4720
|
+
echo ""
|
|
4721
|
+
diff -u "${file}" <(echo "$FIXED_CONTENT") || true
|
|
4722
|
+
echo ""
|
|
4723
|
+
|
|
4724
|
+
# Prompt for confirmation
|
|
4725
|
+
read -p "Apply this fix? [y/N] " -n 1 -r
|
|
4726
|
+
echo ""
|
|
4727
|
+
|
|
4728
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
4729
|
+
echo "$FIXED_CONTENT" > "${file}"
|
|
4730
|
+
echo "\u2705 Fix applied to ${file}"
|
|
4731
|
+
echo ""
|
|
4732
|
+
echo "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
|
|
4733
|
+
echo "\u2728 Done! File has been fixed."
|
|
4734
|
+
echo "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
|
|
4735
|
+
else
|
|
4736
|
+
echo "\u274C Fix cancelled"
|
|
4737
|
+
fi
|
|
4738
|
+
|
|
4739
|
+
echo ""
|
|
4740
|
+
read -p "Press Enter to close..."
|
|
4741
|
+
`.trim();
|
|
4742
|
+
const { writeFile: writeFile2, chmod, unlink } = await import("fs/promises");
|
|
4743
|
+
const { tmpdir } = await import("os");
|
|
4744
|
+
const { join: join3 } = await import("path");
|
|
4745
|
+
const scriptPath = join3(tmpdir(), `trie-fix-${Date.now()}.sh`);
|
|
4746
|
+
await writeFile2(scriptPath, fixScript, "utf-8");
|
|
4747
|
+
await chmod(scriptPath, 493);
|
|
4748
|
+
await spawnTerminal({
|
|
4749
|
+
command: `bash "${scriptPath}" && rm "${scriptPath}"`,
|
|
4750
|
+
cwd,
|
|
4751
|
+
title: `Fixing: ${file}`,
|
|
4752
|
+
keepOpen: true
|
|
4753
|
+
});
|
|
4754
|
+
}
|
|
4755
|
+
|
|
4756
|
+
// src/cli/dashboard/chat-tools.ts
|
|
4483
4757
|
function textFromResult(result) {
|
|
4484
4758
|
return result.content.map((c) => c.text).join("\n");
|
|
4485
4759
|
}
|
|
@@ -4629,6 +4903,20 @@ var CHAT_TOOLS = [
|
|
|
4629
4903
|
},
|
|
4630
4904
|
required: ["decision", "context"]
|
|
4631
4905
|
}
|
|
4906
|
+
},
|
|
4907
|
+
{
|
|
4908
|
+
name: "trie_fix_goal_violation",
|
|
4909
|
+
description: "Spawn Claude Code in a new terminal to fix a goal violation. Use when the user wants to auto-fix a goal violation detected by the watcher.",
|
|
4910
|
+
input_schema: {
|
|
4911
|
+
type: "object",
|
|
4912
|
+
properties: {
|
|
4913
|
+
file: { type: "string", description: "File path with the goal violation" },
|
|
4914
|
+
goal: { type: "string", description: "The goal that was violated" },
|
|
4915
|
+
violation: { type: "string", description: "Description of the violation" },
|
|
4916
|
+
suggestedFix: { type: "string", description: "Suggested fix for the violation (optional)" }
|
|
4917
|
+
},
|
|
4918
|
+
required: ["file", "goal", "violation"]
|
|
4919
|
+
}
|
|
4632
4920
|
}
|
|
4633
4921
|
];
|
|
4634
4922
|
async function executeTool(name, input) {
|
|
@@ -4778,6 +5066,35 @@ async function executeTool(name, input) {
|
|
|
4778
5066
|
});
|
|
4779
5067
|
return `Decision recorded [${hash}]: "${dec}"`;
|
|
4780
5068
|
}
|
|
5069
|
+
case "trie_fix_goal_violation": {
|
|
5070
|
+
const file = String(input.file || "").trim();
|
|
5071
|
+
const goal = String(input.goal || "").trim();
|
|
5072
|
+
const violation = String(input.violation || "").trim();
|
|
5073
|
+
const suggestedFix = input.suggestedFix ? String(input.suggestedFix) : void 0;
|
|
5074
|
+
if (!file) return "File path is required.";
|
|
5075
|
+
if (!goal) return "Goal description is required.";
|
|
5076
|
+
if (!violation) return "Violation description is required.";
|
|
5077
|
+
try {
|
|
5078
|
+
await spawnClaudeCodeFix({
|
|
5079
|
+
file,
|
|
5080
|
+
goal,
|
|
5081
|
+
violation,
|
|
5082
|
+
suggestedFix,
|
|
5083
|
+
cwd: directory
|
|
5084
|
+
});
|
|
5085
|
+
return `\u2713 Spawned Claude Code in a new terminal to fix "${file}".
|
|
5086
|
+
|
|
5087
|
+
Claude Code will:
|
|
5088
|
+
1. Review the file
|
|
5089
|
+
2. Understand the goal: "${goal}"
|
|
5090
|
+
3. Fix the violation: "${violation}"
|
|
5091
|
+
4. Preserve all functionality
|
|
5092
|
+
|
|
5093
|
+
Check the new terminal window to see the fix in progress.`;
|
|
5094
|
+
} catch (error) {
|
|
5095
|
+
return `Failed to spawn Claude Code: ${error instanceof Error ? error.message : "unknown error"}`;
|
|
5096
|
+
}
|
|
5097
|
+
}
|
|
4781
5098
|
default:
|
|
4782
5099
|
return `Unknown tool: ${name}`;
|
|
4783
5100
|
}
|
|
@@ -4785,8 +5102,36 @@ async function executeTool(name, input) {
|
|
|
4785
5102
|
|
|
4786
5103
|
// src/cli/dashboard/views/ChatView.tsx
|
|
4787
5104
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4788
|
-
async function buildContext(workDir) {
|
|
5105
|
+
async function buildContext(workDir, dashboardState) {
|
|
4789
5106
|
const parts = [];
|
|
5107
|
+
if (dashboardState?.agentInsights) {
|
|
5108
|
+
const recentNudges = dashboardState.agentInsights.filter((i) => i.type === "warning" && i.category === "quality" && !i.dismissed).slice(0, 5);
|
|
5109
|
+
if (recentNudges.length > 0) {
|
|
5110
|
+
parts.push("Recent goal violations (nudges):\n" + recentNudges.map((n) => {
|
|
5111
|
+
const fileMatch = n.message.match(/in ([^:]+):/);
|
|
5112
|
+
const goalMatch = n.message.match(/Goal "([^"]+)"/);
|
|
5113
|
+
const violationMatch = n.message.match(/: (.+?) \[/);
|
|
5114
|
+
return `- File: ${fileMatch?.[1] || "unknown"}
|
|
5115
|
+
Goal: ${goalMatch?.[1] || "unknown"}
|
|
5116
|
+
Violation: ${violationMatch?.[1] || n.message}
|
|
5117
|
+
Priority: ${n.priority}`;
|
|
5118
|
+
}).join("\n"));
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
try {
|
|
5122
|
+
const guardianState = getGuardianState(workDir);
|
|
5123
|
+
await guardianState.load();
|
|
5124
|
+
const activeGoals = guardianState.getAllGoals().filter((g) => g.status === "active");
|
|
5125
|
+
if (activeGoals.length > 0) {
|
|
5126
|
+
parts.push("Active goals:\n" + activeGoals.map((g) => {
|
|
5127
|
+
const metadata = g.metadata || {};
|
|
5128
|
+
const caughtCount = metadata.caughtCount || 0;
|
|
5129
|
+
const lastCaught = metadata.lastCaught ? ` (last violation: ${metadata.lastCaughtFile || "unknown"})` : "";
|
|
5130
|
+
return `- "${g.description}" [${g.category || "general"}]${caughtCount > 0 ? ` - ${caughtCount} violation(s)${lastCaught}` : ""}`;
|
|
5131
|
+
}).join("\n"));
|
|
5132
|
+
}
|
|
5133
|
+
} catch {
|
|
5134
|
+
}
|
|
4790
5135
|
try {
|
|
4791
5136
|
const storage = new TieredStorage(workDir);
|
|
4792
5137
|
try {
|
|
@@ -4851,6 +5196,19 @@ function chatHistoryToMessages(history) {
|
|
|
4851
5196
|
}
|
|
4852
5197
|
var SYSTEM_PROMPT = `You are Trie, a code guardian assistant embedded in a terminal TUI.
|
|
4853
5198
|
You have tools to take actions on the user's codebase \u2014 use them when the user asks you to check files, record incidents, give feedback, query decisions, or save checkpoints.
|
|
5199
|
+
|
|
5200
|
+
**IMPORTANT: When the user asks to "fix" or "remove" something related to goal violations:**
|
|
5201
|
+
1. Check the "Recent goal violations (nudges)" section in the project context
|
|
5202
|
+
2. Extract: file path, goal description, and violation details
|
|
5203
|
+
3. IMMEDIATELY use trie_fix_goal_violation to spawn Claude Code in a new terminal
|
|
5204
|
+
4. Do NOT ask for clarification if the context has the violation details
|
|
5205
|
+
5. Do NOT try to search for files - use the violation info from nudges
|
|
5206
|
+
|
|
5207
|
+
Examples:
|
|
5208
|
+
- User: "fix the emoji violation" \u2192 Look for emoji violations in nudges, call trie_fix_goal_violation
|
|
5209
|
+
- User: "remove emojis from this project" \u2192 Check nudges for emoji violations, call trie_fix_goal_violation
|
|
5210
|
+
- User: "can you fix Dashboard.tsx" \u2192 Check if Dashboard.tsx has violations in nudges, call trie_fix_goal_violation
|
|
5211
|
+
|
|
4854
5212
|
Answer concisely. Reference specific files, decisions, and patterns when relevant.
|
|
4855
5213
|
When you use a tool, briefly summarize what you did and what the result was.`;
|
|
4856
5214
|
function ChatView() {
|
|
@@ -4866,7 +5224,7 @@ function ChatView() {
|
|
|
4866
5224
|
dispatch({ type: "SET_CHAT_LOADING", loading: true });
|
|
4867
5225
|
try {
|
|
4868
5226
|
const workDir = getWorkingDirectory(void 0, true);
|
|
4869
|
-
const contextBlock = await buildContext(workDir);
|
|
5227
|
+
const contextBlock = await buildContext(workDir, state);
|
|
4870
5228
|
const fullSystem = `${SYSTEM_PROMPT}
|
|
4871
5229
|
|
|
4872
5230
|
Project context:
|
|
@@ -4938,7 +5296,7 @@ ${contextBlock}`;
|
|
|
4938
5296
|
dispatch({ type: "SET_CHAT_LOADING", loading: false });
|
|
4939
5297
|
loadingRef.current = false;
|
|
4940
5298
|
}
|
|
4941
|
-
}, [dispatch, messages]);
|
|
5299
|
+
}, [dispatch, messages, state]);
|
|
4942
5300
|
useInput8((input, key) => {
|
|
4943
5301
|
if (loading) return;
|
|
4944
5302
|
if (key.return && inputBuffer.trim().length > 0) {
|
|
@@ -5155,6 +5513,7 @@ function DashboardApp({ onReady }) {
|
|
|
5155
5513
|
dispatchRef.current({ type: "STREAM_UPDATE", update: { type: "raw_log", data: { time, level, message }, timestamp: Date.now() } });
|
|
5156
5514
|
},
|
|
5157
5515
|
onNudge: (nudge) => {
|
|
5516
|
+
console.error("[Dashboard] onNudge called:", { message: nudge.message, severity: nudge.severity, file: nudge.file });
|
|
5158
5517
|
const action = { type: "SHOW_NOTIFICATION", message: nudge.message, severity: nudge.severity };
|
|
5159
5518
|
if (nudge.file !== void 0) action.file = nudge.file;
|
|
5160
5519
|
if (nudge.autoHideMs !== void 0) action.autoHideMs = nudge.autoHideMs;
|
|
@@ -5171,6 +5530,7 @@ function DashboardApp({ onReady }) {
|
|
|
5171
5530
|
relatedIssues: [],
|
|
5172
5531
|
dismissed: false
|
|
5173
5532
|
};
|
|
5533
|
+
console.error("[Dashboard] Adding insight:", { id: insight.id, type: insight.type, category: insight.category, priority: insight.priority });
|
|
5174
5534
|
dispatchRef.current({ type: "ADD_INSIGHTS", insights: [insight] });
|
|
5175
5535
|
}
|
|
5176
5536
|
}
|
|
@@ -5358,4 +5718,4 @@ export {
|
|
|
5358
5718
|
handleCheckpointTool,
|
|
5359
5719
|
InteractiveDashboard
|
|
5360
5720
|
};
|
|
5361
|
-
//# sourceMappingURL=chunk-
|
|
5721
|
+
//# sourceMappingURL=chunk-OZGDXRLD.js.map
|