@triedotdev/mcp 1.0.163 → 1.0.165

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.
Files changed (62) hide show
  1. package/README.md +16 -2
  2. package/dist/{chunk-62JD7MIS.js → chunk-5LRDF2WB.js} +15 -35
  3. package/dist/chunk-5LRDF2WB.js.map +1 -0
  4. package/dist/{chunk-XSKLOBD2.js → chunk-CDG2GVBP.js} +601 -70
  5. package/dist/chunk-CDG2GVBP.js.map +1 -0
  6. package/dist/{chunk-5BYSJ7XT.js → chunk-GTKYBOXL.js} +13 -2
  7. package/dist/{chunk-5BYSJ7XT.js.map → chunk-GTKYBOXL.js.map} +1 -1
  8. package/dist/{chunk-ACU3IXZG.js → chunk-HC5P6FZD.js} +7 -7
  9. package/dist/{chunk-HFVPHQL3.js → chunk-IPNPHPNN.js} +9 -9
  10. package/dist/{chunk-GL62CXU4.js → chunk-IS5UBN2R.js} +86 -12
  11. package/dist/chunk-IS5UBN2R.js.map +1 -0
  12. package/dist/{chunk-LLDZDU2Y.js → chunk-LR5M4RTN.js} +79 -1
  13. package/dist/chunk-LR5M4RTN.js.map +1 -0
  14. package/dist/{chunk-ERMLZJTK.js → chunk-M7HMBZ3R.js} +13 -13
  15. package/dist/chunk-OBQ74FOU.js +27 -0
  16. package/dist/chunk-OBQ74FOU.js.map +1 -0
  17. package/dist/{chunk-5TRCQAOE.js → chunk-RQ6QZBIN.js} +16 -5
  18. package/dist/chunk-RQ6QZBIN.js.map +1 -0
  19. package/dist/{chunk-IRZXBQVQ.js → chunk-SS2O3MTC.js} +134 -101
  20. package/dist/chunk-SS2O3MTC.js.map +1 -0
  21. package/dist/{chunk-LR46VMIE.js → chunk-WRYQHVPD.js} +5 -5
  22. package/dist/{chunk-Y4B3VEL7.js → chunk-YAL3SUBG.js} +435 -202
  23. package/dist/chunk-YAL3SUBG.js.map +1 -0
  24. package/dist/cli/main.js +215 -57
  25. package/dist/cli/main.js.map +1 -1
  26. package/dist/cli/yolo-daemon.js +15 -14
  27. package/dist/cli/yolo-daemon.js.map +1 -1
  28. package/dist/{fast-analyzer-LLZ6FLP5.js → fast-analyzer-54AHLVO5.js} +3 -3
  29. package/dist/{goal-manager-D6XKE3FY.js → goal-manager-563BNILQ.js} +5 -5
  30. package/dist/{goal-validator-4DDL7NBP.js → goal-validator-FJEDIYU7.js} +5 -5
  31. package/dist/{hypothesis-RI3Q33JB.js → hypothesis-4KC7XRBZ.js} +5 -5
  32. package/dist/index.js +16 -15
  33. package/dist/index.js.map +1 -1
  34. package/dist/{issue-store-DUR5UTYK.js → issue-store-FOS4T736.js} +3 -3
  35. package/dist/{ledger-ZTR63P3L.js → ledger-EDLPF6SB.js} +8 -2
  36. package/dist/project-state-AHPA77SM.js +28 -0
  37. package/dist/server/mcp-server.js +16 -15
  38. package/dist/sync-M2FSWPBC.js +12 -0
  39. package/dist/{tiered-storage-FHHAJR4P.js → tiered-storage-OP74NPJY.js} +2 -2
  40. package/dist/tiered-storage-OP74NPJY.js.map +1 -0
  41. package/dist/{trie-agent-NYSPGZYS.js → trie-agent-TM6ATSNR.js} +12 -12
  42. package/dist/trie-agent-TM6ATSNR.js.map +1 -0
  43. package/package.json +1 -1
  44. package/dist/chunk-5TRCQAOE.js.map +0 -1
  45. package/dist/chunk-62JD7MIS.js.map +0 -1
  46. package/dist/chunk-GL62CXU4.js.map +0 -1
  47. package/dist/chunk-IRZXBQVQ.js.map +0 -1
  48. package/dist/chunk-LLDZDU2Y.js.map +0 -1
  49. package/dist/chunk-XSKLOBD2.js.map +0 -1
  50. package/dist/chunk-Y4B3VEL7.js.map +0 -1
  51. /package/dist/{chunk-ACU3IXZG.js.map → chunk-HC5P6FZD.js.map} +0 -0
  52. /package/dist/{chunk-HFVPHQL3.js.map → chunk-IPNPHPNN.js.map} +0 -0
  53. /package/dist/{chunk-ERMLZJTK.js.map → chunk-M7HMBZ3R.js.map} +0 -0
  54. /package/dist/{chunk-LR46VMIE.js.map → chunk-WRYQHVPD.js.map} +0 -0
  55. /package/dist/{fast-analyzer-LLZ6FLP5.js.map → fast-analyzer-54AHLVO5.js.map} +0 -0
  56. /package/dist/{goal-manager-D6XKE3FY.js.map → goal-manager-563BNILQ.js.map} +0 -0
  57. /package/dist/{goal-validator-4DDL7NBP.js.map → goal-validator-FJEDIYU7.js.map} +0 -0
  58. /package/dist/{hypothesis-RI3Q33JB.js.map → hypothesis-4KC7XRBZ.js.map} +0 -0
  59. /package/dist/{issue-store-DUR5UTYK.js.map → issue-store-FOS4T736.js.map} +0 -0
  60. /package/dist/{ledger-ZTR63P3L.js.map → ledger-EDLPF6SB.js.map} +0 -0
  61. /package/dist/{tiered-storage-FHHAJR4P.js.map → project-state-AHPA77SM.js.map} +0 -0
  62. /package/dist/{trie-agent-NYSPGZYS.js.map → sync-M2FSWPBC.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-JVMBCWKS.js";
4
4
  import {
5
5
  getTrieAgent
6
- } from "./chunk-ERMLZJTK.js";
6
+ } from "./chunk-M7HMBZ3R.js";
7
7
  import {
8
8
  parseGoalViolation
9
9
  } from "./chunk-WCN7S3EI.js";
@@ -13,9 +13,11 @@ import {
13
13
  import {
14
14
  getOutputManager
15
15
  } from "./chunk-VR4VWXXU.js";
16
+ import {
17
+ getInsightStore
18
+ } from "./chunk-T63OHG4Q.js";
16
19
  import {
17
20
  LearningEngine,
18
- exportToJson,
19
21
  formatFriendlyError,
20
22
  getLastCheckpoint,
21
23
  isTrieInitialized,
@@ -23,10 +25,13 @@ import {
23
25
  perceiveCurrentChanges,
24
26
  reasonAboutChangesHumanReadable,
25
27
  saveCheckpoint
26
- } from "./chunk-62JD7MIS.js";
28
+ } from "./chunk-5LRDF2WB.js";
27
29
  import {
28
30
  measureInitialGoalValue
29
- } from "./chunk-ACU3IXZG.js";
31
+ } from "./chunk-HC5P6FZD.js";
32
+ import {
33
+ exportToJson
34
+ } from "./chunk-OBQ74FOU.js";
30
35
  import {
31
36
  loadConfig,
32
37
  saveConfig
@@ -36,14 +41,14 @@ import {
36
41
  } from "./chunk-TN5WEKWI.js";
37
42
  import {
38
43
  findCrossProjectPatterns
39
- } from "./chunk-HFVPHQL3.js";
40
- import {
41
- TieredStorage,
42
- getStorage
43
- } from "./chunk-LLDZDU2Y.js";
44
+ } from "./chunk-IPNPHPNN.js";
44
45
  import {
45
46
  ContextGraph
46
47
  } from "./chunk-VUL52BQL.js";
48
+ import {
49
+ TieredStorage,
50
+ getStorage
51
+ } from "./chunk-LR5M4RTN.js";
47
52
  import {
48
53
  getKeyFromKeychain,
49
54
  isAIAvailable,
@@ -51,22 +56,26 @@ import {
51
56
  runAIWithTools,
52
57
  setAPIKey
53
58
  } from "./chunk-FQ45QP5A.js";
54
- import {
55
- getProjectState
56
- } from "./chunk-5BYSJ7XT.js";
57
59
  import {
58
60
  storeIssues
59
- } from "./chunk-IRZXBQVQ.js";
61
+ } from "./chunk-SS2O3MTC.js";
62
+ import {
63
+ getProjectState
64
+ } from "./chunk-GTKYBOXL.js";
60
65
  import {
61
66
  getAutonomyConfig,
62
67
  loadAutonomyConfig,
63
68
  saveAutonomyConfig
64
69
  } from "./chunk-ME2OERF5.js";
65
70
  import {
71
+ generateKeyPair,
66
72
  getChangedFilesSinceTimestamp,
67
73
  getGitChangedFiles,
68
- getLedgerBlocks
69
- } from "./chunk-Y4B3VEL7.js";
74
+ getLedgerBlocks,
75
+ getPublicKey,
76
+ hasSigningKey,
77
+ saveKeyPair
78
+ } from "./chunk-YAL3SUBG.js";
70
79
  import {
71
80
  getTrieDirectory,
72
81
  getWorkingDirectory
@@ -697,10 +706,11 @@ function dashboardReducer(state, action) {
697
706
  const gotchas = action.storageGotchas ?? state.memoryTree.storageGotchas;
698
707
  const facts = action.storageFacts ?? state.memoryTree.storageFacts;
699
708
  const nudges = action.storageNudges ?? state.memoryTree.storageNudges;
709
+ const insights = action.storageInsights ?? state.memoryTree.storageInsights;
700
710
  const expanded = new Set(state.memoryTree.expandedNodes);
701
711
  if (blocks.length > 0) expanded.add("ledger-chain");
702
712
  if (gotchas.length > 0) expanded.add("gotchas");
703
- if (nudges.length > 0) expanded.add("patterns");
713
+ if (nudges.length > 0 || insights.length > 0) expanded.add("patterns");
704
714
  return {
705
715
  ...state,
706
716
  memoryTree: {
@@ -712,6 +722,7 @@ function dashboardReducer(state, action) {
712
722
  storageFacts: facts,
713
723
  storageGotchas: gotchas,
714
724
  storageNudges: nudges,
725
+ storageInsights: insights,
715
726
  ledgerBlocks: blocks,
716
727
  expandedNodes: expanded
717
728
  }
@@ -723,6 +734,8 @@ function dashboardReducer(state, action) {
723
734
  return { ...state, memoryTree: { ...state.memoryTree, selectedNode: action.nodeId } };
724
735
  case "SET_MEMORY_EXPANDED_ITEM":
725
736
  return { ...state, memoryTree: { ...state.memoryTree, expandedItemId: action.itemId } };
737
+ case "TOGGLE_SIGNALS_VIEW_ALL":
738
+ return { ...state, memoryTree: { ...state.memoryTree, signalsViewAll: !state.memoryTree.signalsViewAll } };
726
739
  case "TOGGLE_MEMORY_NODE": {
727
740
  const expandable = ["decisions", "incidents", "patterns", "cross-project", "hotspots", "ledger-chain"];
728
741
  if (expandable.includes(action.nodeId)) {
@@ -976,7 +989,7 @@ function createInitialState() {
976
989
  },
977
990
  goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningGoalId: null, scanningProgress: "" },
978
991
  hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningHypothesisId: null, scanningProgress: "" },
979
- memoryTree: { loaded: false, snapshot: null, globalPatterns: [], storageGovernance: [], storageFacts: [], storageGotchas: [], storageNudges: [], ledgerBlocks: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), expandedItemId: null, selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
992
+ 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, signalsViewAll: false },
980
993
  agentBrain: { loaded: false, governance: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
981
994
  chatState: { messages: [], inputBuffer: "", loading: false, progress: null, messageQueue: [], currentSessionId: null, currentSessionTitle: null },
982
995
  chatArchivePanel: { sessions: [], selectedIndex: 0, showArchived: false, loading: false, inputMode: "browse", inputBuffer: "" },
@@ -1115,6 +1128,8 @@ function Footer() {
1115
1128
  hints = narrow ? "d r" : "d delete \xB7 r resolve";
1116
1129
  } else if (ledgerBlockSelected) {
1117
1130
  hints = narrow ? "enter" : "Enter details \xB7 Esc close";
1131
+ } else if (view === "memory" && memoryTree.expandedNodes.has("patterns")) {
1132
+ hints = memoryTree.signalsViewAll ? narrow ? "a" : "a collapse" : narrow ? "a" : "a view all";
1118
1133
  } else if (view === "goals" && goalsPanel.goals.filter((g) => g.status === "achieved").length > 0 && goalsPanel.goals.filter((g) => g.status === "active").length === 0) {
1119
1134
  hints = narrow ? "U" : "U reactivate all achieved";
1120
1135
  } else {
@@ -1216,6 +1231,8 @@ function ConfigDialog({ onClose }) {
1216
1231
  const [cursorKeyDisplay, setCursorKeyDisplay] = useState("Not set");
1217
1232
  const [linearKeyDisplay, setLinearKeyDisplay] = useState("Not set");
1218
1233
  const [githubKeyDisplay, setGithubKeyDisplay] = useState("Not set");
1234
+ const [signingKeyStatus, setSigningKeyStatus] = useState({ hasKey: false, pubKey: null });
1235
+ const [generatingKey, setGeneratingKey] = useState(false);
1219
1236
  const config = state.agentConfig;
1220
1237
  React3.useEffect(() => {
1221
1238
  const loadApiKeys = async () => {
@@ -1237,6 +1254,14 @@ function ConfigDialog({ onClose }) {
1237
1254
  setLinearKeyDisplay("Not set");
1238
1255
  setGithubKeyDisplay("Not set");
1239
1256
  }
1257
+ try {
1258
+ const workDir = getWorkingDirectory(void 0, true);
1259
+ const hasKey = hasSigningKey(workDir);
1260
+ const pubKey = hasKey ? getPublicKey(workDir) : null;
1261
+ setSigningKeyStatus({ hasKey, pubKey });
1262
+ } catch {
1263
+ setSigningKeyStatus({ hasKey: false, pubKey: null });
1264
+ }
1240
1265
  };
1241
1266
  void loadApiKeys();
1242
1267
  }, []);
@@ -1277,6 +1302,7 @@ function ConfigDialog({ onClose }) {
1277
1302
  const keyActive = isAIAvailable();
1278
1303
  const mainMenu = [
1279
1304
  { label: "API Keys", key: "apiKeys", value: keyActive ? "Active" : "Not set", section: "main" },
1305
+ { label: "Signing Keys", key: "signingKeys", value: signingKeyStatus.hasKey ? "Active (Ed25519)" : "Not set", section: "main" },
1280
1306
  { label: "Codebase Index", key: "codebaseIndex", value: "Stats & Re-index", section: "main" },
1281
1307
  { label: "AI Watcher", key: "aiWatcher", value: config.aiWatcher.enabled ? `${(config.aiWatcher.hourlyTokenLimit / 1e3).toFixed(0)}k/hr` : "Off", section: "main" },
1282
1308
  { label: "Performance", key: "performance", value: `${config.performance.maxConcurrency} concurrent`, section: "main" },
@@ -1316,7 +1342,8 @@ function ConfigDialog({ onClose }) {
1316
1342
  { label: "Re-index Codebase", key: "reindex", value: "Rebuild full index", section: "codebaseIndex" },
1317
1343
  { label: "Clear Index", key: "clearIndex", value: "Delete index cache", section: "codebaseIndex" }
1318
1344
  ];
1319
- const items = section === "main" ? mainMenu : section === "apiKeys" ? apiKeysItems : section === "performance" ? performanceItems : section === "riskThresholds" ? riskItems : section === "aiWatcher" ? aiWatcherItems : section === "memory" ? memoryItems : section === "codebaseIndex" ? codebaseIndexItems : mainMenu;
1345
+ const signingKeysItems = signingKeyStatus.hasKey ? [{ label: "Regenerate Key", key: "regenerate", value: "WARNING: invalidates signatures", section: "signingKeys" }] : [{ label: "Generate Key", key: "generate", value: "Create Ed25519 signing key", section: "signingKeys" }];
1346
+ const items = section === "main" ? mainMenu : section === "apiKeys" ? apiKeysItems : section === "performance" ? performanceItems : section === "riskThresholds" ? riskItems : section === "aiWatcher" ? aiWatcherItems : section === "memory" ? memoryItems : section === "codebaseIndex" ? codebaseIndexItems : section === "signingKeys" ? signingKeysItems : mainMenu;
1320
1347
  useInput((_input, key) => {
1321
1348
  if (showConfirmClear) {
1322
1349
  if (_input === "y" || _input === "Y") {
@@ -1462,6 +1489,19 @@ function ConfigDialog({ onClose }) {
1462
1489
  dispatch({ type: "ADD_ACTIVITY", message: "Failed to clear index" });
1463
1490
  });
1464
1491
  }
1492
+ } else if (section === "signingKeys") {
1493
+ const item = items[selectedIndex];
1494
+ if (item && (item.key === "generate" || item.key === "regenerate")) {
1495
+ setGeneratingKey(true);
1496
+ generateSigningKey().then((pubKey) => {
1497
+ setSigningKeyStatus({ hasKey: true, pubKey });
1498
+ dispatch({ type: "ADD_ACTIVITY", message: "Ed25519 signing key generated" });
1499
+ setGeneratingKey(false);
1500
+ }).catch(() => {
1501
+ dispatch({ type: "ADD_ACTIVITY", message: "Failed to generate signing key" });
1502
+ setGeneratingKey(false);
1503
+ });
1504
+ }
1465
1505
  } else {
1466
1506
  const item = items[selectedIndex];
1467
1507
  if (item) {
@@ -1484,7 +1524,7 @@ function ConfigDialog({ onClose }) {
1484
1524
  }
1485
1525
  }
1486
1526
  });
1487
- 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";
1527
+ 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" : section === "signingKeys" ? "Ed25519 Signing Keys" : "Settings";
1488
1528
  async function clearMemory() {
1489
1529
  const workDir = getWorkingDirectory(void 0, true);
1490
1530
  const trieDir = getTrieDirectory(workDir);
@@ -1511,6 +1551,12 @@ function ConfigDialog({ onClose }) {
1511
1551
  await rm(indexFile, { force: true });
1512
1552
  }
1513
1553
  }
1554
+ async function generateSigningKey() {
1555
+ const workDir = getWorkingDirectory(void 0, true);
1556
+ const keyPair = await generateKeyPair();
1557
+ saveKeyPair(keyPair, workDir);
1558
+ return keyPair.publicKey;
1559
+ }
1514
1560
  async function reindexCodebase() {
1515
1561
  const workDir = getWorkingDirectory(void 0, true);
1516
1562
  const { CodebaseIndex: CodebaseIndex2 } = await import("./codebase-index-VAPF32XX.js");
@@ -1585,6 +1631,40 @@ function ConfigDialog({ onClose }) {
1585
1631
  }),
1586
1632
  indexing ? /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Re-indexing codebase..." }) }) : /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to execute \xB7 esc back" }) })
1587
1633
  ] }),
1634
+ !showConfirmClear && section === "signingKeys" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
1635
+ /* @__PURE__ */ jsx5(Text4, { bold: true, children: "Ed25519 Signing for Governance Ledger" }),
1636
+ /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: signingKeyStatus.hasKey ? /* @__PURE__ */ jsx5(Fragment, { children: /* @__PURE__ */ jsxs4(Text4, { children: [
1637
+ " Status: ",
1638
+ /* @__PURE__ */ jsx5(Text4, { color: "green", children: "\u2713 Active" })
1639
+ ] }) }) : /* @__PURE__ */ jsxs4(Text4, { children: [
1640
+ " Status: ",
1641
+ /* @__PURE__ */ jsx5(Text4, { color: "yellow", children: "\u25CB Not configured" })
1642
+ ] }) }),
1643
+ signingKeyStatus.hasKey && signingKeyStatus.pubKey && /* @__PURE__ */ jsxs4(Text4, { children: [
1644
+ " Public key: ",
1645
+ /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
1646
+ signingKeyStatus.pubKey.slice(0, 16),
1647
+ "...",
1648
+ signingKeyStatus.pubKey.slice(-8)
1649
+ ] })
1650
+ ] }),
1651
+ /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Signing provides:" }) }),
1652
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " \u2022 Authenticity - prove who created each entry" }),
1653
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " \u2022 Tamper-evidence - detect if entries are modified" }),
1654
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " \u2022 Accountability - track decisions to humans/agents" }),
1655
+ /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: signingKeysItems.map((item, idx) => {
1656
+ const isSelected = selectedIndex === idx;
1657
+ return /* @__PURE__ */ jsxs4(Text4, { children: [
1658
+ isSelected ? /* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "> " }) : " ",
1659
+ item.key === "regenerate" ? /* @__PURE__ */ jsx5(Text4, { bold: isSelected, color: "yellow", children: item.label }) : /* @__PURE__ */ jsx5(Text4, { bold: isSelected, children: item.label }),
1660
+ /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
1661
+ " ",
1662
+ item.value
1663
+ ] })
1664
+ ] }, item.key);
1665
+ }) }),
1666
+ generatingKey ? /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Generating key..." }) }) : /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to execute \xB7 esc back" }) })
1667
+ ] }),
1588
1668
  !showConfirmClear && section === "apiKeys" && !editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
1589
1669
  apiKeysItems.map((item, idx) => {
1590
1670
  const isSelected = selectedIndex === idx;
@@ -1614,7 +1694,7 @@ function ConfigDialog({ onClose }) {
1614
1694
  ] }) }),
1615
1695
  /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter save \xB7 esc cancel" })
1616
1696
  ] }),
1617
- !showConfirmClear && section !== "apiKeys" && section !== "memory" && section !== "codebaseIndex" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
1697
+ !showConfirmClear && section !== "apiKeys" && section !== "memory" && section !== "codebaseIndex" && section !== "signingKeys" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
1618
1698
  items.map((item, idx) => {
1619
1699
  const isSelected = selectedIndex === idx;
1620
1700
  return /* @__PURE__ */ jsxs4(Text4, { children: [
@@ -1977,10 +2057,10 @@ function AgentView() {
1977
2057
  if (!insight) return;
1978
2058
  try {
1979
2059
  const workDir = getWorkingDirectory(void 0, true);
1980
- const { getInsightStore } = await import("./insight-store-EC4PLSAW.js");
1981
- const store = getInsightStore(workDir);
2060
+ const { getInsightStore: getInsightStore2 } = await import("./insight-store-EC4PLSAW.js");
2061
+ const store = getInsightStore2(workDir);
1982
2062
  await store.dismissInsight(insight.id);
1983
- const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
2063
+ const { getStorage: getStorage2 } = await import("./tiered-storage-OP74NPJY.js");
1984
2064
  const storage = getStorage2(workDir);
1985
2065
  await storage.dismissNudge(insight.id).catch(() => {
1986
2066
  });
@@ -1992,7 +2072,7 @@ function AgentView() {
1992
2072
  const clearAllNudges = useCallback(async () => {
1993
2073
  try {
1994
2074
  const workDir = getWorkingDirectory(void 0, true);
1995
- const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
2075
+ const { getStorage: getStorage2 } = await import("./tiered-storage-OP74NPJY.js");
1996
2076
  const storage = getStorage2(workDir);
1997
2077
  await storage.clearAllNudges();
1998
2078
  dispatch({ type: "CLEAR_ALL_INSIGHTS" });
@@ -2028,8 +2108,8 @@ function AgentView() {
2028
2108
  }
2029
2109
  await spawnClaudeCodeFixIssue({
2030
2110
  message: insight.message,
2031
- file,
2032
- suggestedAction: insight.suggestedAction,
2111
+ ...file !== void 0 && { file },
2112
+ ...insight.suggestedAction !== void 0 && { suggestedAction: insight.suggestedAction },
2033
2113
  cwd: workDir
2034
2114
  });
2035
2115
  const fileDisplay = file ? ` for ${file.split("/").pop()}` : "";
@@ -2366,7 +2446,7 @@ function GoalsView() {
2366
2446
  dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Starting scan..." });
2367
2447
  dispatch({ type: "ADD_ACTIVITY", message: `Scanning goal: ${goalSummary.description}...` });
2368
2448
  dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Loading goal configuration..." });
2369
- const { checkFilesForGoalViolations } = await import("./goal-validator-4DDL7NBP.js");
2449
+ const { checkFilesForGoalViolations } = await import("./goal-validator-FJEDIYU7.js");
2370
2450
  const agentState = getProjectState(workDir);
2371
2451
  await agentState.load();
2372
2452
  const fullGoal = agentState.getAllGoals().find((g) => g.id === goalId);
@@ -2641,7 +2721,7 @@ function HypothesesView() {
2641
2721
  dispatch({ type: "SET_HYPOTHESIS_SCANNING", hypothesisId: hypoId, progress: "Gathering evidence..." });
2642
2722
  dispatch({ type: "ADD_ACTIVITY", message: `Testing hypothesis: ${hypo.statement}` });
2643
2723
  dispatch({ type: "SHOW_NOTIFICATION", message: `Gathering evidence for hypothesis...`, severity: "info", autoHideMs: 3e3 });
2644
- const { gatherEvidenceForHypothesis } = await import("./hypothesis-RI3Q33JB.js");
2724
+ const { gatherEvidenceForHypothesis } = await import("./hypothesis-4KC7XRBZ.js");
2645
2725
  const evidence = await gatherEvidenceForHypothesis(hypoId, workDir, signal);
2646
2726
  scanAbortRef.current = null;
2647
2727
  dispatch({ type: "SET_HYPOTHESIS_SCANNING", hypothesisId: null, progress: "" });
@@ -2813,7 +2893,7 @@ function timeAgo2(iso) {
2813
2893
  function MemoryTreeView() {
2814
2894
  const { state, dispatch } = useDashboard();
2815
2895
  const { memoryTree } = state;
2816
- const { snapshot, globalPatterns, storageGovernance, storageFacts, storageGotchas, storageNudges, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded } = memoryTree;
2896
+ const { snapshot, globalPatterns, storageGovernance, storageFacts, storageGotchas, storageNudges, storageInsights, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded, signalsViewAll } = memoryTree;
2817
2897
  const { stdout } = useStdout8();
2818
2898
  const cols = stdout?.columns || 80;
2819
2899
  const narrow = cols < 60;
@@ -2823,6 +2903,7 @@ function MemoryTreeView() {
2823
2903
  const workDir = getWorkingDirectory(void 0, true);
2824
2904
  const graph = new ContextGraph(workDir);
2825
2905
  const storage = new TieredStorage(workDir);
2906
+ const insightStore = getInsightStore(workDir);
2826
2907
  const [snap, patterns, governance2, facts, gotchas, nudges, blocks] = await Promise.all([
2827
2908
  graph.getSnapshot(),
2828
2909
  findCrossProjectPatterns(2),
@@ -2832,7 +2913,9 @@ function MemoryTreeView() {
2832
2913
  storage.queryNudges({ limit: 20, resolved: false }).catch(() => []),
2833
2914
  getLedgerBlocks(workDir).catch(() => [])
2834
2915
  ]);
2835
- dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns, storageGovernance: governance2, storageFacts: facts, storageGotchas: gotchas, storageNudges: nudges, ledgerBlocks: blocks });
2916
+ await insightStore.load();
2917
+ const insights = insightStore.getActiveInsights(10);
2918
+ dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns, storageGovernance: governance2, storageFacts: facts, storageGotchas: gotchas, storageNudges: nudges, storageInsights: insights, ledgerBlocks: blocks });
2836
2919
  } catch (err) {
2837
2920
  dispatch({ type: "ADD_ACTIVITY", message: "Context graph load error" });
2838
2921
  }
@@ -2876,6 +2959,10 @@ function MemoryTreeView() {
2876
2959
  dispatch({ type: "INVALIDATE_MEMORY_TREE" });
2877
2960
  return;
2878
2961
  }
2962
+ if (expandedNodes.has("patterns") && (_input === "a" || _input === "A")) {
2963
+ dispatch({ type: "TOGGLE_SIGNALS_VIEW_ALL" });
2964
+ return;
2965
+ }
2879
2966
  if (key.upArrow || _input === "k") dispatch({ type: "NAVIGATE_UP" });
2880
2967
  else if (key.downArrow || _input === "j") dispatch({ type: "NAVIGATE_DOWN" });
2881
2968
  else if (key.return) dispatch({ type: "TOGGLE_MEMORY_NODE", nodeId: selectedNode });
@@ -2909,7 +2996,7 @@ function MemoryTreeView() {
2909
2996
  const order = { critical: 0, high: 1 };
2910
2997
  return (order[a.data.riskLevel] ?? 2) - (order[b.data.riskLevel] ?? 2);
2911
2998
  });
2912
- const totalEntries = productGovernance.length + learnedSignals.length + (storageFacts?.length ?? 0) + (storageNudges?.length ?? 0) + incidentNodes.length + patternNodes.length + globalPatterns.length + hotspots.length + ledgerBlocks.length;
2999
+ 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;
2913
3000
  const expandedGovernance = expandedItemId?.startsWith("decision-") ? governance.find((g) => `decision-${g.id}` === expandedItemId) : null;
2914
3001
  const expandedIncident = expandedItemId?.startsWith("incident-") ? incidentNodes.find((n) => `incident-${n.id}` === expandedItemId) : null;
2915
3002
  const expandedGotcha = expandedItemId?.startsWith("gotcha-") ? storageGotchas.find((g) => `gotcha-${g.id}` === expandedItemId) ?? null : null;
@@ -2917,7 +3004,7 @@ function MemoryTreeView() {
2917
3004
  const blockIndex = parseInt(expandedItemId.replace("ledger-block-", ""), 10);
2918
3005
  return ledgerBlocks[blockIndex] || null;
2919
3006
  })() : null;
2920
- function renderHeader(id, label, count, emptyHint) {
3007
+ function renderHeader(id, label, count, emptyHint, viewHint) {
2921
3008
  const expanded = expandedNodes.has(id);
2922
3009
  const isEmpty = count === 0;
2923
3010
  return /* @__PURE__ */ jsxs10(Text10, { children: [
@@ -2932,6 +3019,10 @@ function MemoryTreeView() {
2932
3019
  ] }) : isEmpty && emptyHint ? /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
2933
3020
  " ",
2934
3021
  emptyHint
3022
+ ] }) : null,
3023
+ count > 0 && viewHint ? /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3024
+ " ",
3025
+ viewHint
2935
3026
  ] }) : null
2936
3027
  ] });
2937
3028
  }
@@ -3030,7 +3121,40 @@ function MemoryTreeView() {
3030
3121
  ] }) })
3031
3122
  ] }),
3032
3123
  expandedLedgerBlock && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "magenta", paddingX: 1, paddingY: 1, children: [
3033
- /* @__PURE__ */ jsx11(Text10, { bold: true, color: "magenta", children: "Ledger Block Details \xB7 d delete \xB7 Esc close" }),
3124
+ /* @__PURE__ */ jsx11(Text10, { bold: true, color: "magenta", children: "Ledger Block Details \xB7 Esc close" }),
3125
+ (() => {
3126
+ const syncBlock = expandedLedgerBlock;
3127
+ const blockAuthor = syncBlock.author;
3128
+ const gitCommit = syncBlock.gitCommit;
3129
+ const signedCount = expandedLedgerBlock.entries.filter((e) => e.signature).length;
3130
+ const totalEntries2 = expandedLedgerBlock.entries.length;
3131
+ return /* @__PURE__ */ jsxs10(Fragment6, { children: [
3132
+ blockAuthor ? /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
3133
+ /* @__PURE__ */ jsx11(Text10, { bold: true, children: "Block author:" }),
3134
+ " ",
3135
+ /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: blockAuthor }),
3136
+ " ",
3137
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "(person or agent who created block)" })
3138
+ ] }) }) : null,
3139
+ gitCommit ? /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
3140
+ /* @__PURE__ */ jsx11(Text10, { bold: true, children: "Git commit:" }),
3141
+ " ",
3142
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: gitCommit.slice(0, 8) })
3143
+ ] }) }) : null,
3144
+ /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { children: [
3145
+ /* @__PURE__ */ jsx11(Text10, { bold: true, children: "Ed25519 signatures:" }),
3146
+ " ",
3147
+ /* @__PURE__ */ jsxs10(Text10, { color: signedCount === totalEntries2 ? "green" : signedCount > 0 ? "yellow" : "dim", children: [
3148
+ signedCount,
3149
+ "/",
3150
+ totalEntries2,
3151
+ " signed"
3152
+ ] }),
3153
+ " ",
3154
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "(\u2713 = signed, \u25CB = unsigned)" })
3155
+ ] }) })
3156
+ ] });
3157
+ })(),
3034
3158
  (() => {
3035
3159
  const aiAgents = /* @__PURE__ */ new Set(["goal-violation", "claude", "agent", "ai"]);
3036
3160
  const hasAIAgents = expandedLedgerBlock.entries.some((e) => aiAgents.has(e.agent));
@@ -3097,6 +3221,35 @@ function MemoryTreeView() {
3097
3221
  ] }) })
3098
3222
  ] });
3099
3223
  })(),
3224
+ /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { bold: true, children: "Entries (who made/changed what):" }) }),
3225
+ expandedLedgerBlock.entries.slice(0, 15).map((entry, idx) => {
3226
+ const sigIcon = entry.signature ? "\u2713" : "\u25CB";
3227
+ const sigColor = entry.signature ? "green" : "dim";
3228
+ const fileShort = entry.file.split("/").pop() || entry.file;
3229
+ const corrected = entry.status === "corrected" || entry.correctedBy;
3230
+ return /* @__PURE__ */ jsx11(Box10, { marginTop: 0, children: /* @__PURE__ */ jsxs10(Text10, { children: [
3231
+ /* @__PURE__ */ jsx11(Text10, { color: sigColor, children: sigIcon }),
3232
+ " ",
3233
+ /* @__PURE__ */ jsx11(Text10, { ...entry.severity === "critical" ? { color: "red" } : entry.severity === "high" ? { color: "yellow" } : {}, children: entry.severity }),
3234
+ " ",
3235
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: fileShort }),
3236
+ " ",
3237
+ /* @__PURE__ */ jsxs10(Text10, { color: "cyan", children: [
3238
+ "by ",
3239
+ entry.agent
3240
+ ] }),
3241
+ entry.signedAt ? /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3242
+ " \xB7 signed ",
3243
+ timeAgo2(entry.signedAt)
3244
+ ] }) : null,
3245
+ corrected ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " \xB7 corrected" }) : null
3246
+ ] }) }, entry.id || idx);
3247
+ }),
3248
+ expandedLedgerBlock.entries.length > 15 && /* @__PURE__ */ jsx11(Box10, { marginTop: 0, children: /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3249
+ " \u2026 and ",
3250
+ expandedLedgerBlock.entries.length - 15,
3251
+ " more"
3252
+ ] }) }),
3100
3253
  /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3101
3254
  "Created: ",
3102
3255
  expandedLedgerBlock.createdAt
@@ -3175,15 +3328,44 @@ function MemoryTreeView() {
3175
3328
  ] })
3176
3329
  ] }, g.id);
3177
3330
  }),
3178
- renderHeader("patterns", "Learned Signals", learnedSignals.length + (storageFacts?.length ?? 0) + (storageNudges?.length ?? 0) + patternNodes.length, learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && (storageNudges?.length ?? 0) === 0 && patternNodes.length === 0 ? "-- Trie learns as you work" : void 0),
3331
+ 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, (storageInsights?.length ?? 0) + learnedSignals.length + (storageFacts?.length ?? 0) + (storageNudges?.length ?? 0) + patternNodes.length > 5 ? signalsViewAll ? "\xB7 a collapse" : "\xB7 a view all" : void 0),
3179
3332
  expandedNodes.has("patterns") && /* @__PURE__ */ jsxs10(Fragment6, { children: [
3180
- (storageNudges?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
3333
+ signalsViewAll && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3334
+ " ",
3335
+ " ",
3336
+ "Showing all \xB7 a to collapse"
3337
+ ] }),
3338
+ (storageInsights?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
3181
3339
  /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3182
3340
  " ",
3183
3341
  " ",
3184
- "AI Detections"
3342
+ "Learnings"
3185
3343
  ] }),
3186
- storageNudges.slice(0, 5).map((n) => {
3344
+ (signalsViewAll ? storageInsights : storageInsights.slice(0, 5)).map((insight) => {
3345
+ const descWidth = Math.max(30, contentWidth - 15);
3346
+ const desc = insight.message.length > descWidth ? insight.message.slice(0, descWidth - 3) + "..." : insight.message;
3347
+ const categoryLabel = insight.category === "security" ? "[sec]" : insight.category === "performance" ? "[perf]" : insight.category === "quality" ? "[qual]" : "[learn]";
3348
+ const confidenceColor = insight.priority >= 7 ? "green" : insight.priority >= 4 ? "yellow" : "white";
3349
+ return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
3350
+ " ",
3351
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: categoryLabel }),
3352
+ " ",
3353
+ /* @__PURE__ */ jsx11(Text10, { children: desc }),
3354
+ narrow ? null : /* @__PURE__ */ jsxs10(Text10, { color: confidenceColor, dimColor: true, children: [
3355
+ " ",
3356
+ insight.priority,
3357
+ "/10"
3358
+ ] })
3359
+ ] }, insight.id);
3360
+ })
3361
+ ] }),
3362
+ (storageNudges?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 ? 1 : 0, children: [
3363
+ /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3364
+ " ",
3365
+ " ",
3366
+ (storageInsights?.length ?? 0) > 0 ? "Raw Detections" : "AI Detections"
3367
+ ] }),
3368
+ (signalsViewAll ? storageNudges : storageNudges.slice(0, (storageInsights?.length ?? 0) > 0 ? 3 : 5)).map((n) => {
3187
3369
  const descWidth = Math.max(30, contentWidth - 15);
3188
3370
  const desc = n.message.length > descWidth ? n.message.slice(0, descWidth - 3) + "..." : n.message;
3189
3371
  const severityColor = n.severity === "critical" ? "red" : n.severity === "high" ? "yellow" : "cyan";
@@ -3199,13 +3381,13 @@ function MemoryTreeView() {
3199
3381
  ] }, n.id);
3200
3382
  })
3201
3383
  ] }),
3202
- learnedSignals.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageNudges?.length ?? 0) > 0 ? 1 : 0, children: [
3384
+ learnedSignals.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 ? 1 : 0, children: [
3203
3385
  /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3204
3386
  " ",
3205
3387
  " ",
3206
3388
  "Governance"
3207
3389
  ] }),
3208
- learnedSignals.slice(0, 5).map((g) => {
3390
+ (signalsViewAll ? learnedSignals : learnedSignals.slice(0, 5)).map((g) => {
3209
3391
  const descWidth = Math.max(30, contentWidth - 15);
3210
3392
  const desc = g.decision.length > descWidth ? g.decision.slice(0, descWidth - 3) + "..." : g.decision;
3211
3393
  return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
@@ -3220,13 +3402,13 @@ function MemoryTreeView() {
3220
3402
  ] }, g.id);
3221
3403
  })
3222
3404
  ] }),
3223
- (storageFacts?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 ? 1 : 0, children: [
3405
+ (storageFacts?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 ? 1 : 0, children: [
3224
3406
  /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3225
3407
  " ",
3226
3408
  " ",
3227
3409
  "Facts"
3228
3410
  ] }),
3229
- storageFacts.slice(0, 5).map((f) => {
3411
+ (signalsViewAll ? storageFacts : storageFacts.slice(0, 5)).map((f) => {
3230
3412
  const descWidth = Math.max(30, contentWidth - 15);
3231
3413
  const desc = f.fact.length > descWidth ? f.fact.slice(0, descWidth - 3) + "..." : f.fact;
3232
3414
  return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
@@ -3241,19 +3423,19 @@ function MemoryTreeView() {
3241
3423
  ] }, f.id);
3242
3424
  })
3243
3425
  ] }),
3244
- patternNodes.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0 ? 1 : 0, children: [
3245
- ((storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0) && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3426
+ 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: [
3427
+ ((storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0) && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3246
3428
  " ",
3247
3429
  " ",
3248
3430
  "Patterns"
3249
3431
  ] }),
3250
- patternNodes.slice(0, 10).map((n) => {
3432
+ (signalsViewAll ? patternNodes : patternNodes.slice(0, 10)).map((n) => {
3251
3433
  const nodeId = `pattern-${n.id}`;
3252
3434
  const conf = Math.round(n.data.confidence * 100);
3253
3435
  const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
3254
3436
  const descWidth = Math.max(30, contentWidth - 15);
3255
3437
  const desc = n.data.description.length > descWidth ? n.data.description.slice(0, descWidth - 3) + "..." : n.data.description;
3256
- const hasPreceding = (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0;
3438
+ const hasPreceding = (storageInsights?.length ?? 0) > 0 || (storageNudges?.length ?? 0) > 0 || learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0;
3257
3439
  return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
3258
3440
  sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : hasPreceding ? " " : " ",
3259
3441
  !hasPreceding && " ",
@@ -3273,7 +3455,7 @@ function MemoryTreeView() {
3273
3455
  ] }, n.id);
3274
3456
  })
3275
3457
  ] }),
3276
- patternNodes.length === 0 && learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && (storageNudges?.length ?? 0) === 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3458
+ patternNodes.length === 0 && learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && (storageNudges?.length ?? 0) === 0 && (storageInsights?.length ?? 0) === 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3277
3459
  " ",
3278
3460
  " ",
3279
3461
  "No signals learned yet. Trie will extract insights as you work."
@@ -3348,6 +3530,9 @@ function MemoryTreeView() {
3348
3530
  const topAgent = Object.keys(agentCounts).sort((a, b) => (agentCounts[b] ?? 0) - (agentCounts[a] ?? 0))[0];
3349
3531
  const blkShort = block.blockHash?.slice(0, 6) || "\u2014";
3350
3532
  const mkShort = block.merkleRoot?.slice(0, 6) || "\u2014";
3533
+ const signedCount = block.entries.filter((e) => e.signature).length;
3534
+ const allSigned = signedCount === block.entries.length && block.entries.length > 0;
3535
+ const blockAuthor = block.author;
3351
3536
  return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
3352
3537
  sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : " ",
3353
3538
  " ",
@@ -3406,7 +3591,24 @@ function MemoryTreeView() {
3406
3591
  topAgent
3407
3592
  ] })
3408
3593
  ] }) : null,
3409
- sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " [Enter: details, d: delete]" }) : null
3594
+ !narrow && blockAuthor ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
3595
+ " ",
3596
+ /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3597
+ "\xB7 author: ",
3598
+ blockAuthor
3599
+ ] })
3600
+ ] }) : null,
3601
+ !narrow && block.entries.length > 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
3602
+ " ",
3603
+ allSigned ? /* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u2713 Ed25519" }) : signedCount > 0 ? /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
3604
+ "(",
3605
+ signedCount,
3606
+ "/",
3607
+ block.entries.length,
3608
+ " signed)"
3609
+ ] }) : null
3610
+ ] }) : null,
3611
+ sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " [Enter: details]" }) : null
3410
3612
  ] }, nodeId);
3411
3613
  })
3412
3614
  ] })
@@ -6400,7 +6602,7 @@ function getPendingFixes() {
6400
6602
  }
6401
6603
  async function loadPendingFixesFromMemory() {
6402
6604
  try {
6403
- const { getRecentIssues } = await import("./issue-store-DUR5UTYK.js");
6605
+ const { getRecentIssues } = await import("./issue-store-FOS4T736.js");
6404
6606
  pendingFixes.clear();
6405
6607
  const recentIssues = await getRecentIssues({ limit: 50, includeResolved: false });
6406
6608
  for (const storedIssue of recentIssues) {
@@ -6703,7 +6905,7 @@ var TrieCloudFixTool = class {
6703
6905
  if (pending.length === 0) {
6704
6906
  try {
6705
6907
  console.log("Loading issues from memory...");
6706
- const { getRecentIssues } = await import("./issue-store-DUR5UTYK.js");
6908
+ const { getRecentIssues } = await import("./issue-store-FOS4T736.js");
6707
6909
  const recentIssues = await getRecentIssues({ limit: 50, includeResolved: false });
6708
6910
  console.log(`Found ${recentIssues.length} recent issues in memory`);
6709
6911
  const memoryIssues = recentIssues.map((storedIssue) => ({
@@ -7001,8 +7203,8 @@ var TrieGetNudgesTool = class {
7001
7203
  const limit = input.limit ?? 20;
7002
7204
  const nudges = await storage.queryNudges({
7003
7205
  resolved: false,
7004
- severity: input.severity,
7005
- file: input.file,
7206
+ ...input.severity !== void 0 && { severity: input.severity },
7207
+ ...input.file !== void 0 && { file: input.file },
7006
7208
  limit
7007
7209
  });
7008
7210
  if (nudges.length === 0) {
@@ -7249,8 +7451,12 @@ var TrieQueryLedgerBlocksTool = class {
7249
7451
  output += "**Block summary:**\n";
7250
7452
  for (let i = 0; i < limited.length; i++) {
7251
7453
  const b = limited[i];
7454
+ const syncB = b;
7252
7455
  const critical = b.entries.filter((e) => e.severity === "critical").length;
7253
- output += ` Block ${blocks.length - limited.length + i + 1}: ${b.date} \u2014 ${b.entries.length} entries (${critical} critical)
7456
+ const signed = b.entries.filter((e) => e.signature).length;
7457
+ const authorPart = syncB.author ? ` \xB7 author: ${syncB.author}` : "";
7458
+ const sigPart = b.entries.length > 0 ? ` \xB7 ${signed}/${b.entries.length} Ed25519 signed` : "";
7459
+ output += ` Block ${blocks.length - limited.length + i + 1}: ${b.date} \u2014 ${b.entries.length} entries (${critical} critical)${authorPart}${sigPart}
7254
7460
  `;
7255
7461
  }
7256
7462
  output += "\n";
@@ -8554,7 +8760,7 @@ ${truncated}`;
8554
8760
  const goalId = input.goalId ? String(input.goalId).trim() : void 0;
8555
8761
  try {
8556
8762
  onProgress?.("Loading goals...");
8557
- const { getActiveGoals } = await import("./goal-validator-4DDL7NBP.js");
8763
+ const { getActiveGoals } = await import("./goal-validator-FJEDIYU7.js");
8558
8764
  const agentState = getProjectState(directory);
8559
8765
  await agentState.load();
8560
8766
  const allGoals = await getActiveGoals(directory);
@@ -8563,7 +8769,7 @@ ${truncated}`;
8563
8769
  return goalId ? `No active goal found with ID: ${goalId}` : "No active goals to check. Add goals in the Goals view first.";
8564
8770
  }
8565
8771
  onProgress?.("Scanning codebase for violations...");
8566
- const { analyzeFilesRapidly } = await import("./fast-analyzer-LLZ6FLP5.js");
8772
+ const { analyzeFilesRapidly } = await import("./fast-analyzer-54AHLVO5.js");
8567
8773
  const analysisOptions = {
8568
8774
  maxFiles: 50,
8569
8775
  enableSmartBatching: true
@@ -8577,7 +8783,7 @@ ${truncated}`;
8577
8783
  const cacheInfo2 = analysisResult.cacheHitRatio > 0 ? ` (${Math.round(analysisResult.cacheHitRatio * 100)}% cache hit, ${analysisResult.timeMs}ms)` : ` (${analysisResult.timeMs}ms)`;
8578
8784
  return `\u2713 Scan complete! No violations found for ${goalsToCheck.length} goal(s).${cacheInfo2}`;
8579
8785
  }
8580
- const { storeIssues: storeIssues2 } = await import("./issue-store-DUR5UTYK.js");
8786
+ const { storeIssues: storeIssues2 } = await import("./issue-store-FOS4T736.js");
8581
8787
  const { basename: basename2 } = await import("path");
8582
8788
  const issuesToStore = violations.map((v, i) => ({
8583
8789
  id: `goal-violation-${Date.now()}-${i}`,
@@ -8656,7 +8862,7 @@ ${truncated}`;
8656
8862
  }
8657
8863
  try {
8658
8864
  onProgress?.("Gathering evidence for hypothesis...");
8659
- const { gatherEvidenceForHypothesis } = await import("./hypothesis-RI3Q33JB.js");
8865
+ const { gatherEvidenceForHypothesis } = await import("./hypothesis-4KC7XRBZ.js");
8660
8866
  const evidence = await gatherEvidenceForHypothesis(hypothesisId, directory);
8661
8867
  if (evidence.length === 0) {
8662
8868
  return `No evidence found for this hypothesis yet. The codebase may not have enough data to validate it \u2014 try running trie_scan_for_goal_violations first to populate issues, or add more context.`;
@@ -9595,7 +9801,7 @@ ${content}
9595
9801
  fixedContent = fixedContent.replace(/^```\w*\n?/, "").replace(/\n?```$/, "");
9596
9802
  }
9597
9803
  await writeFile2(fullPath, fixedContent, "utf-8");
9598
- const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-4DDL7NBP.js");
9804
+ const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-FJEDIYU7.js");
9599
9805
  const goals = await getActiveGoals(projectPath);
9600
9806
  const matchedGoal = goals.find((g) => g.description === fix.goalDescription);
9601
9807
  if (matchedGoal) {
@@ -9711,7 +9917,7 @@ function DashboardApp({ onReady }) {
9711
9917
  const loadPersistedNudges = useCallback7(async () => {
9712
9918
  try {
9713
9919
  const workDir = getWorkingDirectory(void 0, true);
9714
- const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
9920
+ const { getStorage: getStorage2 } = await import("./tiered-storage-OP74NPJY.js");
9715
9921
  const storage = getStorage2(workDir);
9716
9922
  await storage.initialize();
9717
9923
  const nudges = await storage.queryNudges({ resolved: false, limit: 50 });
@@ -9983,7 +10189,248 @@ var InteractiveDashboard = class {
9983
10189
  import { watch, existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
9984
10190
  import { stat, readFile as readFile5 } from "fs/promises";
9985
10191
  import { join as join4, extname as extname3, basename } from "path";
10192
+ import { createHash as createHash3 } from "crypto";
10193
+
10194
+ // src/agent/signal-summarizer.ts
10195
+ import Anthropic2 from "@anthropic-ai/sdk";
9986
10196
  import { createHash as createHash2 } from "crypto";
10197
+ var SIGNAL_THRESHOLD = 5;
10198
+ var SUMMARIZE_PROMPT = `You are an AI that learns patterns about a codebase from repeated issues.
10199
+
10200
+ 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.
10201
+
10202
+ Good learnings (what we want):
10203
+ - "Type safety tends to be weak in this codebase"
10204
+ - "Error handling is often skipped in async code"
10205
+ - "The dashboard module has inconsistent patterns"
10206
+ - "State management doesn't follow a clear convention"
10207
+
10208
+ Bad learnings (avoid these):
10209
+ - "5 type safety issues detected" (just counting)
10210
+ - "Consider adding null checks" (action without insight)
10211
+ - "Issues found in src/dashboard" (no actual learning)
10212
+
10213
+ Respond with JSON:
10214
+ {
10215
+ "learning": "One sentence stating what Trie learned about this codebase (a tendency, habit, or pattern)",
10216
+ "evidence": "Brief explanation of what patterns led to this conclusion",
10217
+ "suggestedAction": "What could improve this tendency",
10218
+ "category": "quality" | "security" | "performance" | "pattern",
10219
+ "confidence": 1-10 (how confident is this learning based on evidence)
10220
+ }`;
10221
+ var SignalSummarizer = class {
10222
+ client = null;
10223
+ projectPath;
10224
+ processedBatches = /* @__PURE__ */ new Set();
10225
+ constructor(projectPath) {
10226
+ this.projectPath = projectPath;
10227
+ const apiKey = process.env.ANTHROPIC_API_KEY;
10228
+ if (apiKey) {
10229
+ this.client = new Anthropic2({ apiKey });
10230
+ }
10231
+ }
10232
+ /**
10233
+ * Check if we have enough nudges to generate a signal
10234
+ */
10235
+ async checkAndSummarize() {
10236
+ const storage = getStorage(this.projectPath);
10237
+ await storage.initialize();
10238
+ const nudges = await storage.queryNudges({ resolved: false, limit: 100 });
10239
+ if (nudges.length < SIGNAL_THRESHOLD) {
10240
+ return null;
10241
+ }
10242
+ const batches = this.groupNudges(nudges);
10243
+ for (const batch of batches) {
10244
+ if (batch.nudges.length >= SIGNAL_THRESHOLD && !this.processedBatches.has(batch.key)) {
10245
+ const insight = await this.summarizeBatch(batch);
10246
+ if (insight) {
10247
+ this.processedBatches.add(batch.key);
10248
+ return insight;
10249
+ }
10250
+ }
10251
+ }
10252
+ return null;
10253
+ }
10254
+ /**
10255
+ * Group nudges by similarity (same goal, same category, similar files)
10256
+ */
10257
+ groupNudges(nudges) {
10258
+ const groups = /* @__PURE__ */ new Map();
10259
+ for (const nudge of nudges) {
10260
+ const goalMatch = nudge.message.match(/Goal "([^"]+)" violated/);
10261
+ const goalPattern = goalMatch?.[1];
10262
+ const key = goalPattern ? `goal:${goalPattern}` : `category:${nudge.category || "general"}`;
10263
+ if (!groups.has(key)) {
10264
+ groups.set(key, {
10265
+ key,
10266
+ nudges: [],
10267
+ category: nudge.category || "quality",
10268
+ goalPattern,
10269
+ files: []
10270
+ });
10271
+ }
10272
+ const batch = groups.get(key);
10273
+ batch.nudges.push(nudge);
10274
+ if (nudge.file && !batch.files.includes(nudge.file)) {
10275
+ batch.files.push(nudge.file);
10276
+ }
10277
+ }
10278
+ return Array.from(groups.values());
10279
+ }
10280
+ /**
10281
+ * Use AI to summarize a batch of nudges into an insight
10282
+ */
10283
+ async summarizeBatch(batch) {
10284
+ if (!this.client) {
10285
+ return this.createFallbackInsight(batch);
10286
+ }
10287
+ try {
10288
+ const nudgeDescriptions = batch.nudges.slice(0, 10).map((n) => `- ${n.message}${n.file ? ` (${n.file})` : ""}`).join("\n");
10289
+ const response = await this.client.messages.create({
10290
+ model: "claude-3-haiku-20240307",
10291
+ max_tokens: 512,
10292
+ temperature: 0.3,
10293
+ messages: [{
10294
+ role: "user",
10295
+ content: `${SUMMARIZE_PROMPT}
10296
+
10297
+ Batch of ${batch.nudges.length} similar issues:
10298
+ ${nudgeDescriptions}
10299
+
10300
+ Files affected: ${batch.files.slice(0, 5).join(", ")}${batch.files.length > 5 ? ` (+${batch.files.length - 5} more)` : ""}`
10301
+ }]
10302
+ });
10303
+ const text = response.content[0]?.type === "text" ? response.content[0].text : "";
10304
+ const parsed = this.parseResponse(text);
10305
+ if (!parsed) {
10306
+ return this.createFallbackInsight(batch);
10307
+ }
10308
+ const insight = {
10309
+ id: `signal-${createHash2("sha256").update(batch.key + Date.now()).digest("hex").slice(0, 12)}`,
10310
+ type: "observation",
10311
+ message: parsed.learning,
10312
+ context: parsed.evidence,
10313
+ suggestedAction: parsed.suggestedAction,
10314
+ relatedIssues: batch.nudges.map((n) => n.id),
10315
+ priority: parsed.confidence,
10316
+ timestamp: Date.now(),
10317
+ dismissed: false,
10318
+ category: parsed.category,
10319
+ details: {
10320
+ affectedFiles: batch.files,
10321
+ issueBreakdown: { [batch.category]: batch.nudges.length },
10322
+ summary: parsed.learning
10323
+ }
10324
+ };
10325
+ const insightStore = getInsightStore(this.projectPath);
10326
+ await insightStore.load();
10327
+ await insightStore.addInsight(insight);
10328
+ const storage = getStorage(this.projectPath);
10329
+ for (const nudge of batch.nudges) {
10330
+ await storage.resolveNudge(nudge.id, "auto-fixed");
10331
+ }
10332
+ return insight;
10333
+ } catch (error) {
10334
+ console.error("[SignalSummarizer] AI summarization failed:", error);
10335
+ return this.createFallbackInsight(batch);
10336
+ }
10337
+ }
10338
+ /**
10339
+ * Parse AI response
10340
+ */
10341
+ parseResponse(text) {
10342
+ try {
10343
+ const jsonMatch = text.match(/\{[\s\S]*\}/);
10344
+ if (!jsonMatch) return null;
10345
+ const parsed = JSON.parse(jsonMatch[0]);
10346
+ return {
10347
+ learning: parsed.learning || "Pattern detected",
10348
+ evidence: parsed.evidence,
10349
+ suggestedAction: parsed.suggestedAction || "Review affected files",
10350
+ category: parsed.category || "quality",
10351
+ confidence: Math.min(10, Math.max(1, parsed.confidence || 5))
10352
+ };
10353
+ } catch {
10354
+ return null;
10355
+ }
10356
+ }
10357
+ /**
10358
+ * Create a fallback insight without AI
10359
+ */
10360
+ createFallbackInsight(batch) {
10361
+ let message;
10362
+ let suggestedAction;
10363
+ if (batch.goalPattern) {
10364
+ const pattern = batch.goalPattern.toLowerCase();
10365
+ if (pattern.includes("type") || pattern.includes("safety")) {
10366
+ message = `Type safety tends to be weak in this codebase`;
10367
+ } else if (pattern.includes("error") || pattern.includes("handling")) {
10368
+ message = `Error handling is often incomplete`;
10369
+ } else if (pattern.includes("test")) {
10370
+ message = `Test coverage appears insufficient`;
10371
+ } else if (pattern.includes("security") || pattern.includes("auth")) {
10372
+ message = `Security practices need attention`;
10373
+ } else {
10374
+ message = `"${batch.goalPattern}" compliance tends to be inconsistent`;
10375
+ }
10376
+ suggestedAction = `Establish stricter conventions for ${pattern}`;
10377
+ } else {
10378
+ if (batch.category === "security") {
10379
+ message = `Security practices need strengthening`;
10380
+ } else if (batch.category === "performance") {
10381
+ message = `Performance optimizations are often overlooked`;
10382
+ } else {
10383
+ message = `Code quality patterns are inconsistent`;
10384
+ }
10385
+ suggestedAction = `Review ${batch.category} conventions across the codebase`;
10386
+ }
10387
+ return {
10388
+ id: `signal-${createHash2("sha256").update(batch.key + Date.now()).digest("hex").slice(0, 12)}`,
10389
+ type: "observation",
10390
+ message,
10391
+ suggestedAction,
10392
+ relatedIssues: batch.nudges.map((n) => n.id),
10393
+ priority: 5,
10394
+ timestamp: Date.now(),
10395
+ dismissed: false,
10396
+ category: batch.category || "quality",
10397
+ details: {
10398
+ affectedFiles: batch.files,
10399
+ issueBreakdown: { [batch.category]: batch.nudges.length }
10400
+ }
10401
+ };
10402
+ }
10403
+ /**
10404
+ * Force summarization of all current nudge batches
10405
+ */
10406
+ async summarizeAll() {
10407
+ const storage = getStorage(this.projectPath);
10408
+ await storage.initialize();
10409
+ const nudges = await storage.queryNudges({ resolved: false, limit: 100 });
10410
+ const batches = this.groupNudges(nudges);
10411
+ const insights = [];
10412
+ for (const batch of batches) {
10413
+ if (batch.nudges.length >= SIGNAL_THRESHOLD) {
10414
+ const insight = await this.summarizeBatch(batch);
10415
+ if (insight) {
10416
+ insights.push(insight);
10417
+ }
10418
+ }
10419
+ }
10420
+ return insights;
10421
+ }
10422
+ };
10423
+ var summarizers = /* @__PURE__ */ new Map();
10424
+ function getSignalSummarizer(projectPath) {
10425
+ let summarizer = summarizers.get(projectPath);
10426
+ if (!summarizer) {
10427
+ summarizer = new SignalSummarizer(projectPath);
10428
+ summarizers.set(projectPath, summarizer);
10429
+ }
10430
+ return summarizer;
10431
+ }
10432
+
10433
+ // src/tools/watch.ts
9987
10434
  var WATCH_EXTENSIONS = /* @__PURE__ */ new Set([
9988
10435
  ".ts",
9989
10436
  ".tsx",
@@ -10099,6 +10546,7 @@ var TrieWatchTool = class _TrieWatchTool {
10099
10546
  try {
10100
10547
  const storage = getStorage(directory);
10101
10548
  await storage.initialize();
10549
+ await this.validateAndCleanNudges(storage, directory);
10102
10550
  const unresolvedNudges = await storage.queryNudges({ resolved: false });
10103
10551
  console.debug(`[Watch] Found ${unresolvedNudges.length} unresolved nudges in storage`);
10104
10552
  for (const nudge of unresolvedNudges) {
@@ -10466,7 +10914,7 @@ ${f.content.slice(0, 1e3)}`
10466
10914
  async checkAndGenerateHypotheses(projectPath) {
10467
10915
  if (!isAIAvailable()) return;
10468
10916
  try {
10469
- const { getHypothesisEngine } = await import("./hypothesis-RI3Q33JB.js");
10917
+ const { getHypothesisEngine } = await import("./hypothesis-4KC7XRBZ.js");
10470
10918
  const { getOutputManager: getOutputManager2 } = await import("./output-manager-JNMEAXFO.js");
10471
10919
  const hypothesisEngine = getHypothesisEngine(projectPath);
10472
10920
  const recentIssues = Array.from(this.state.issueCache.values()).flat();
@@ -10531,7 +10979,7 @@ ${f.content.slice(0, 1e3)}`
10531
10979
  */
10532
10980
  async discoverPatternsFromIssues(projectPath) {
10533
10981
  try {
10534
- const { searchIssues } = await import("./issue-store-DUR5UTYK.js");
10982
+ const { searchIssues } = await import("./issue-store-FOS4T736.js");
10535
10983
  const allIssues = await searchIssues("", {
10536
10984
  workDir: projectPath,
10537
10985
  limit: 1e3,
@@ -10606,7 +11054,7 @@ ${f.content.slice(0, 1e3)}`
10606
11054
  }
10607
11055
  }
10608
11056
  if (patternsAdded > 0) {
10609
- const { exportToJson: exportToJson2 } = await import("./graph-B3NA4S7I.js");
11057
+ const { exportToJson: exportToJson2 } = await import("./sync-M2FSWPBC.js");
10610
11058
  await exportToJson2(graph);
10611
11059
  if (!isInteractiveMode()) {
10612
11060
  console.error(` [\u2713] Discovered ${patternsAdded} pattern(s) from ${allIssues.length} issues`);
@@ -10692,7 +11140,7 @@ ${f.content.slice(0, 1e3)}`
10692
11140
  if (remaining < 500) return;
10693
11141
  try {
10694
11142
  const graph = new ContextGraph(projectPath);
10695
- const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-4DDL7NBP.js");
11143
+ const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-FJEDIYU7.js");
10696
11144
  console.debug("[AI Watcher] Loading active goals...");
10697
11145
  const activeGoals = await getActiveGoals(projectPath);
10698
11146
  const hasGoals = activeGoals.length > 0;
@@ -10947,7 +11395,7 @@ ${filesBlock}`,
10947
11395
  const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
10948
11396
  console.debug("[Initial Hypothesis] Starting initial hypothesis generation", { projectPath });
10949
11397
  try {
10950
- const { getHypothesisEngine } = await import("./hypothesis-RI3Q33JB.js");
11398
+ const { getHypothesisEngine } = await import("./hypothesis-4KC7XRBZ.js");
10951
11399
  const hypothesisEngine = getHypothesisEngine(projectPath);
10952
11400
  console.debug("[Initial Hypothesis] Running AI-powered hypothesis generation...");
10953
11401
  const generated = await hypothesisEngine.generateHypothesesWithAI({
@@ -11005,7 +11453,7 @@ ${filesBlock}`,
11005
11453
  const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
11006
11454
  console.debug("[Initial Scan] Starting initial goal compliance scan", { projectPath });
11007
11455
  try {
11008
- const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-4DDL7NBP.js");
11456
+ const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-FJEDIYU7.js");
11009
11457
  const activeGoals = await getActiveGoals(projectPath);
11010
11458
  console.debug("[Initial Scan] Loaded goals for initial scan:", {
11011
11459
  goalCount: activeGoals.length,
@@ -11148,9 +11596,9 @@ ${filesBlock}`,
11148
11596
  this.streamingManager.reportLedgerUpdate(issuesToStore.length, "goal-violation");
11149
11597
  }
11150
11598
  }
11151
- const { resolveGoalViolation } = await import("./issue-store-DUR5UTYK.js");
11152
- const { recordGoalViolationFixed } = await import("./goal-validator-4DDL7NBP.js");
11153
- const scannedFiles = new Set(issues.map((i) => i.file));
11599
+ const { resolveGoalViolation } = await import("./issue-store-FOS4T736.js");
11600
+ const { recordGoalViolationFixed } = await import("./goal-validator-FJEDIYU7.js");
11601
+ const scannedFiles = new Set(valid.map((f) => f.path));
11154
11602
  const filesWithViolations = new Set(issuesToStore.map((i) => i.file));
11155
11603
  for (const scannedFile of scannedFiles) {
11156
11604
  if (!filesWithViolations.has(scannedFile)) {
@@ -11302,7 +11750,7 @@ Use \`trie_watch start\` to begin autonomous scanning.`
11302
11750
  ).join("\n");
11303
11751
  let agencyStatus = "";
11304
11752
  try {
11305
- const { getTrieAgent: getTrieAgent2 } = await import("./trie-agent-NYSPGZYS.js");
11753
+ const { getTrieAgent: getTrieAgent2 } = await import("./trie-agent-TM6ATSNR.js");
11306
11754
  const trieAgent = getTrieAgent2(this.watchedDirectory || getWorkingDirectory(void 0, true));
11307
11755
  await trieAgent.initialize();
11308
11756
  const status = await trieAgent.getAgencyStatus();
@@ -11353,7 +11801,7 @@ ${recentNudges || "(none)"}
11353
11801
  */
11354
11802
  async persistNudge(params) {
11355
11803
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
11356
- const nudgeId = createHash2("sha256").update(`${params.message}|${params.file || ""}|${timestamp}`).digest("hex").slice(0, 16);
11804
+ const nudgeId = createHash3("sha256").update(`${params.message}|${params.file || ""}|${timestamp}`).digest("hex").slice(0, 16);
11357
11805
  const nudge = {
11358
11806
  id: nudgeId,
11359
11807
  message: params.message,
@@ -11380,10 +11828,46 @@ ${recentNudges || "(none)"}
11380
11828
  const storage = getStorage(this.watchedDirectory);
11381
11829
  await storage.storeNudge(nudge);
11382
11830
  console.debug(`[Watch] \u2713 Persisted nudge to storage: ${nudge.message.slice(0, 60)}...`);
11831
+ void this.checkSignalThreshold();
11383
11832
  } catch (error) {
11384
11833
  console.error("[Watch] Failed to persist nudge to storage:", error);
11385
11834
  }
11386
11835
  }
11836
+ /**
11837
+ * Check if we have enough nudges (5+) to generate an AI-summarized signal.
11838
+ * Runs periodically after nudge persistence to batch similar issues into insights.
11839
+ */
11840
+ async checkSignalThreshold() {
11841
+ try {
11842
+ const summarizer = getSignalSummarizer(this.watchedDirectory);
11843
+ const insight = await summarizer.checkAndSummarize();
11844
+ if (insight) {
11845
+ getOutputManager().nudge(
11846
+ `Trie learned: ${insight.message}`,
11847
+ "info",
11848
+ void 0,
11849
+ 15e3
11850
+ );
11851
+ if (!isInteractiveMode()) {
11852
+ console.error(` [+] Learning: ${insight.message}`);
11853
+ if (insight.suggestedAction) {
11854
+ console.error(` Suggestion: ${insight.suggestedAction}`);
11855
+ }
11856
+ }
11857
+ if (this.streamingManager) {
11858
+ this.streamingManager.reportSignalExtraction({
11859
+ governance: 1,
11860
+ // Insights are a form of governance
11861
+ facts: 0,
11862
+ blockers: 0,
11863
+ questions: 0
11864
+ });
11865
+ }
11866
+ }
11867
+ } catch (error) {
11868
+ console.debug("[Watch] Signal threshold check failed:", error);
11869
+ }
11870
+ }
11387
11871
  getNudges() {
11388
11872
  return {
11389
11873
  content: [
@@ -11415,6 +11899,53 @@ To get a full report, run \`trie watch\` on your codebase.`
11415
11899
  }]
11416
11900
  };
11417
11901
  }
11902
+ /**
11903
+ * Validate existing nudges and resolve ones that are no longer valid.
11904
+ * This runs at watch startup to clean up stale nudges.
11905
+ *
11906
+ * Type-agnostic auto-resolution strategy:
11907
+ * 1. Files that no longer exist -> resolve immediately
11908
+ * 2. Goals that are achieved/deleted -> resolve immediately
11909
+ * 3. All other nudges -> kept until next scan shows the file is clean
11910
+ *
11911
+ * The actual goal validation happens during scans - when a file is scanned
11912
+ * and no violations are found, existing nudges for that file are auto-resolved.
11913
+ */
11914
+ async validateAndCleanNudges(storage, directory) {
11915
+ let totalResolved = 0;
11916
+ try {
11917
+ const missingResolved = await storage.resolveNudgesForMissingFiles();
11918
+ if (missingResolved > 0) {
11919
+ totalResolved += missingResolved;
11920
+ console.log(`[Watch] Resolved ${missingResolved} nudge(s) for deleted files`);
11921
+ }
11922
+ } catch (e) {
11923
+ console.debug("[Watch] resolveNudgesForMissingFiles failed:", e);
11924
+ }
11925
+ try {
11926
+ const { getActiveGoals } = await import("./goal-validator-FJEDIYU7.js");
11927
+ const { getProjectState: getProjectState2 } = await import("./project-state-AHPA77SM.js");
11928
+ const projectState = getProjectState2(directory);
11929
+ await projectState.load();
11930
+ const allGoals = projectState.getAllGoals();
11931
+ const activeGoals = await getActiveGoals(directory);
11932
+ const activeGoalIds = new Set(activeGoals.map((g) => g.id));
11933
+ for (const goal of allGoals) {
11934
+ if (goal.status === "achieved" || !activeGoalIds.has(goal.id)) {
11935
+ const goalResolved = await storage.resolveNudgesForGoal(goal.description);
11936
+ if (goalResolved > 0) {
11937
+ totalResolved += goalResolved;
11938
+ console.log(`[Watch] Resolved ${goalResolved} nudge(s) for ${goal.status === "achieved" ? "achieved" : "inactive"} goal: "${goal.description.slice(0, 40)}..."`);
11939
+ }
11940
+ }
11941
+ }
11942
+ } catch (e) {
11943
+ console.debug("[Watch] Goal validation check failed:", e);
11944
+ }
11945
+ if (totalResolved > 0) {
11946
+ console.log(`[Watch] \u2713 Cleaned up ${totalResolved} stale nudge(s)`);
11947
+ }
11948
+ }
11418
11949
  };
11419
11950
 
11420
11951
  export {
@@ -11441,4 +11972,4 @@ export {
11441
11972
  InteractiveDashboard,
11442
11973
  TrieWatchTool
11443
11974
  };
11444
- //# sourceMappingURL=chunk-XSKLOBD2.js.map
11975
+ //# sourceMappingURL=chunk-CDG2GVBP.js.map