@theihtisham/agent-shadow-brain 5.2.0 → 6.0.2

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 (301) hide show
  1. package/README.md +310 -1014
  2. package/dist/brain/agent-firewall.d.ts +7 -0
  3. package/dist/brain/agent-firewall.d.ts.map +1 -0
  4. package/dist/brain/agent-firewall.js +152 -0
  5. package/dist/brain/agent-firewall.js.map +1 -0
  6. package/dist/brain/agent-handoff.d.ts +19 -0
  7. package/dist/brain/agent-handoff.d.ts.map +1 -0
  8. package/dist/brain/agent-handoff.js +127 -0
  9. package/dist/brain/agent-handoff.js.map +1 -0
  10. package/dist/brain/air-gap.d.ts +23 -0
  11. package/dist/brain/air-gap.d.ts.map +1 -0
  12. package/dist/brain/air-gap.js +137 -0
  13. package/dist/brain/air-gap.js.map +1 -0
  14. package/dist/brain/attention-heatmap.d.ts +24 -0
  15. package/dist/brain/attention-heatmap.d.ts.map +1 -0
  16. package/dist/brain/attention-heatmap.js +108 -0
  17. package/dist/brain/attention-heatmap.js.map +1 -0
  18. package/dist/brain/auto-setup.js +19 -14
  19. package/dist/brain/auto-setup.js.map +1 -1
  20. package/dist/brain/auto-update.js +1 -1
  21. package/dist/brain/brain-3d.d.ts +79 -0
  22. package/dist/brain/brain-3d.d.ts.map +1 -0
  23. package/dist/brain/brain-3d.js +468 -0
  24. package/dist/brain/brain-3d.js.map +1 -0
  25. package/dist/brain/brain-active-learner.d.ts +74 -0
  26. package/dist/brain/brain-active-learner.d.ts.map +1 -0
  27. package/dist/brain/brain-active-learner.js +425 -0
  28. package/dist/brain/brain-active-learner.js.map +1 -0
  29. package/dist/brain/brain-ascii.d.ts +32 -0
  30. package/dist/brain/brain-ascii.d.ts.map +1 -0
  31. package/dist/brain/brain-ascii.js +402 -0
  32. package/dist/brain/brain-ascii.js.map +1 -0
  33. package/dist/brain/brain-chat.d.ts +42 -0
  34. package/dist/brain/brain-chat.d.ts.map +1 -0
  35. package/dist/brain/brain-chat.js +162 -0
  36. package/dist/brain/brain-chat.js.map +1 -0
  37. package/dist/brain/brain-cinema.d.ts +45 -0
  38. package/dist/brain/brain-cinema.d.ts.map +1 -0
  39. package/dist/brain/brain-cinema.js +393 -0
  40. package/dist/brain/brain-cinema.js.map +1 -0
  41. package/dist/brain/brain-coach.d.ts +45 -0
  42. package/dist/brain/brain-coach.d.ts.map +1 -0
  43. package/dist/brain/brain-coach.js +383 -0
  44. package/dist/brain/brain-coach.js.map +1 -0
  45. package/dist/brain/brain-consolidator.d.ts +56 -0
  46. package/dist/brain/brain-consolidator.d.ts.map +1 -0
  47. package/dist/brain/brain-consolidator.js +386 -0
  48. package/dist/brain/brain-consolidator.js.map +1 -0
  49. package/dist/brain/brain-contradictions.d.ts +57 -0
  50. package/dist/brain/brain-contradictions.d.ts.map +1 -0
  51. package/dist/brain/brain-contradictions.js +443 -0
  52. package/dist/brain/brain-contradictions.js.map +1 -0
  53. package/dist/brain/brain-diff.d.ts +61 -0
  54. package/dist/brain/brain-diff.d.ts.map +1 -0
  55. package/dist/brain/brain-diff.js +439 -0
  56. package/dist/brain/brain-diff.js.map +1 -0
  57. package/dist/brain/brain-dna.d.ts +59 -0
  58. package/dist/brain/brain-dna.d.ts.map +1 -0
  59. package/dist/brain/brain-dna.js +336 -0
  60. package/dist/brain/brain-dna.js.map +1 -0
  61. package/dist/brain/brain-doppelganger.d.ts +32 -0
  62. package/dist/brain/brain-doppelganger.d.ts.map +1 -0
  63. package/dist/brain/brain-doppelganger.js +417 -0
  64. package/dist/brain/brain-doppelganger.js.map +1 -0
  65. package/dist/brain/brain-encryption.d.ts +14 -0
  66. package/dist/brain/brain-encryption.d.ts.map +1 -0
  67. package/dist/brain/brain-encryption.js +68 -0
  68. package/dist/brain/brain-encryption.js.map +1 -0
  69. package/dist/brain/brain-exchange.d.ts +30 -0
  70. package/dist/brain/brain-exchange.d.ts.map +1 -0
  71. package/dist/brain/brain-exchange.js +106 -0
  72. package/dist/brain/brain-exchange.js.map +1 -0
  73. package/dist/brain/brain-garden.d.ts +18 -0
  74. package/dist/brain/brain-garden.d.ts.map +1 -0
  75. package/dist/brain/brain-garden.js +81 -0
  76. package/dist/brain/brain-garden.js.map +1 -0
  77. package/dist/brain/brain-graph-walker.d.ts +54 -0
  78. package/dist/brain/brain-graph-walker.d.ts.map +1 -0
  79. package/dist/brain/brain-graph-walker.js +412 -0
  80. package/dist/brain/brain-graph-walker.js.map +1 -0
  81. package/dist/brain/brain-holiday-card.d.ts +50 -0
  82. package/dist/brain/brain-holiday-card.d.ts.map +1 -0
  83. package/dist/brain/brain-holiday-card.js +432 -0
  84. package/dist/brain/brain-holiday-card.js.map +1 -0
  85. package/dist/brain/brain-memes.d.ts +44 -0
  86. package/dist/brain/brain-memes.d.ts.map +1 -0
  87. package/dist/brain/brain-memes.js +438 -0
  88. package/dist/brain/brain-memes.js.map +1 -0
  89. package/dist/brain/brain-memory-tiers.d.ts +67 -0
  90. package/dist/brain/brain-memory-tiers.d.ts.map +1 -0
  91. package/dist/brain/brain-memory-tiers.js +292 -0
  92. package/dist/brain/brain-memory-tiers.js.map +1 -0
  93. package/dist/brain/brain-notebook.d.ts +68 -0
  94. package/dist/brain/brain-notebook.d.ts.map +1 -0
  95. package/dist/brain/brain-notebook.js +379 -0
  96. package/dist/brain/brain-notebook.js.map +1 -0
  97. package/dist/brain/brain-portability.js +1 -1
  98. package/dist/brain/brain-quantize.d.ts +62 -0
  99. package/dist/brain/brain-quantize.d.ts.map +1 -0
  100. package/dist/brain/brain-quantize.js +346 -0
  101. package/dist/brain/brain-quantize.js.map +1 -0
  102. package/dist/brain/brain-query-expander.d.ts +31 -0
  103. package/dist/brain/brain-query-expander.d.ts.map +1 -0
  104. package/dist/brain/brain-query-expander.js +417 -0
  105. package/dist/brain/brain-query-expander.js.map +1 -0
  106. package/dist/brain/brain-quest.d.ts +58 -0
  107. package/dist/brain/brain-quest.d.ts.map +1 -0
  108. package/dist/brain/brain-quest.js +541 -0
  109. package/dist/brain/brain-quest.js.map +1 -0
  110. package/dist/brain/brain-recall-cache.d.ts +73 -0
  111. package/dist/brain/brain-recall-cache.d.ts.map +1 -0
  112. package/dist/brain/brain-recall-cache.js +444 -0
  113. package/dist/brain/brain-recall-cache.js.map +1 -0
  114. package/dist/brain/brain-reflex.d.ts +55 -0
  115. package/dist/brain/brain-reflex.d.ts.map +1 -0
  116. package/dist/brain/brain-reflex.js +364 -0
  117. package/dist/brain/brain-reflex.js.map +1 -0
  118. package/dist/brain/brain-replay.d.ts +74 -0
  119. package/dist/brain/brain-replay.d.ts.map +1 -0
  120. package/dist/brain/brain-replay.js +336 -0
  121. package/dist/brain/brain-replay.js.map +1 -0
  122. package/dist/brain/brain-rerank.d.ts +39 -0
  123. package/dist/brain/brain-rerank.d.ts.map +1 -0
  124. package/dist/brain/brain-rerank.js +216 -0
  125. package/dist/brain/brain-rerank.js.map +1 -0
  126. package/dist/brain/brain-roast.d.ts +44 -0
  127. package/dist/brain/brain-roast.d.ts.map +1 -0
  128. package/dist/brain/brain-roast.js +566 -0
  129. package/dist/brain/brain-roast.js.map +1 -0
  130. package/dist/brain/brain-sonification.d.ts +57 -0
  131. package/dist/brain/brain-sonification.d.ts.map +1 -0
  132. package/dist/brain/brain-sonification.js +286 -0
  133. package/dist/brain/brain-sonification.js.map +1 -0
  134. package/dist/brain/brain-tarot.d.ts +49 -0
  135. package/dist/brain/brain-tarot.d.ts.map +1 -0
  136. package/dist/brain/brain-tarot.js +634 -0
  137. package/dist/brain/brain-tarot.js.map +1 -0
  138. package/dist/brain/brain-time-capsule.d.ts +80 -0
  139. package/dist/brain/brain-time-capsule.d.ts.map +1 -0
  140. package/dist/brain/brain-time-capsule.js +289 -0
  141. package/dist/brain/brain-time-capsule.js.map +1 -0
  142. package/dist/brain/brain-trophies.d.ts +60 -0
  143. package/dist/brain/brain-trophies.d.ts.map +1 -0
  144. package/dist/brain/brain-trophies.js +431 -0
  145. package/dist/brain/brain-trophies.js.map +1 -0
  146. package/dist/brain/brain-working-memory.d.ts +78 -0
  147. package/dist/brain/brain-working-memory.d.ts.map +1 -0
  148. package/dist/brain/brain-working-memory.js +367 -0
  149. package/dist/brain/brain-working-memory.js.map +1 -0
  150. package/dist/brain/branch-brain.d.ts +23 -0
  151. package/dist/brain/branch-brain.d.ts.map +1 -0
  152. package/dist/brain/branch-brain.js +159 -0
  153. package/dist/brain/branch-brain.js.map +1 -0
  154. package/dist/brain/calibration-monitor.d.ts +20 -0
  155. package/dist/brain/calibration-monitor.d.ts.map +1 -0
  156. package/dist/brain/calibration-monitor.js +144 -0
  157. package/dist/brain/calibration-monitor.js.map +1 -0
  158. package/dist/brain/causal-chains.d.ts +37 -0
  159. package/dist/brain/causal-chains.d.ts.map +1 -0
  160. package/dist/brain/causal-chains.js +250 -0
  161. package/dist/brain/causal-chains.js.map +1 -0
  162. package/dist/brain/collision-detective.d.ts +32 -0
  163. package/dist/brain/collision-detective.d.ts.map +1 -0
  164. package/dist/brain/collision-detective.js +233 -0
  165. package/dist/brain/collision-detective.js.map +1 -0
  166. package/dist/brain/confidence-gate.d.ts +69 -0
  167. package/dist/brain/confidence-gate.d.ts.map +1 -0
  168. package/dist/brain/confidence-gate.js +244 -0
  169. package/dist/brain/confidence-gate.js.map +1 -0
  170. package/dist/brain/constitution.d.ts +59 -0
  171. package/dist/brain/constitution.d.ts.map +1 -0
  172. package/dist/brain/constitution.js +315 -0
  173. package/dist/brain/constitution.js.map +1 -0
  174. package/dist/brain/cost-aware-spawner.d.ts +7 -0
  175. package/dist/brain/cost-aware-spawner.d.ts.map +1 -0
  176. package/dist/brain/cost-aware-spawner.js +77 -0
  177. package/dist/brain/cost-aware-spawner.js.map +1 -0
  178. package/dist/brain/dream-engine.d.ts +35 -0
  179. package/dist/brain/dream-engine.d.ts.map +1 -0
  180. package/dist/brain/dream-engine.js +273 -0
  181. package/dist/brain/dream-engine.js.map +1 -0
  182. package/dist/brain/embeddings-v2.d.ts +58 -0
  183. package/dist/brain/embeddings-v2.d.ts.map +1 -0
  184. package/dist/brain/embeddings-v2.js +344 -0
  185. package/dist/brain/embeddings-v2.js.map +1 -0
  186. package/dist/brain/embeddings.d.ts +27 -0
  187. package/dist/brain/embeddings.d.ts.map +1 -0
  188. package/dist/brain/embeddings.js +175 -0
  189. package/dist/brain/embeddings.js.map +1 -0
  190. package/dist/brain/forgetting-curve.d.ts +21 -0
  191. package/dist/brain/forgetting-curve.d.ts.map +1 -0
  192. package/dist/brain/forgetting-curve.js +174 -0
  193. package/dist/brain/forgetting-curve.js.map +1 -0
  194. package/dist/brain/formal-verification-bridge.d.ts +26 -0
  195. package/dist/brain/formal-verification-bridge.d.ts.map +1 -0
  196. package/dist/brain/formal-verification-bridge.js +219 -0
  197. package/dist/brain/formal-verification-bridge.js.map +1 -0
  198. package/dist/brain/global-brain.d.ts +8 -1
  199. package/dist/brain/global-brain.d.ts.map +1 -1
  200. package/dist/brain/global-brain.js +24 -0
  201. package/dist/brain/global-brain.js.map +1 -1
  202. package/dist/brain/hallucination-quarantine.d.ts +26 -0
  203. package/dist/brain/hallucination-quarantine.d.ts.map +1 -0
  204. package/dist/brain/hallucination-quarantine.js +135 -0
  205. package/dist/brain/hallucination-quarantine.js.map +1 -0
  206. package/dist/brain/hive-accelerator.d.ts +39 -0
  207. package/dist/brain/hive-accelerator.d.ts.map +1 -0
  208. package/dist/brain/hive-accelerator.js +152 -0
  209. package/dist/brain/hive-accelerator.js.map +1 -0
  210. package/dist/brain/hive-voice.d.ts +71 -0
  211. package/dist/brain/hive-voice.d.ts.map +1 -0
  212. package/dist/brain/hive-voice.js +352 -0
  213. package/dist/brain/hive-voice.js.map +1 -0
  214. package/dist/brain/json-output.d.ts +26 -0
  215. package/dist/brain/json-output.d.ts.map +1 -0
  216. package/dist/brain/json-output.js +112 -0
  217. package/dist/brain/json-output.js.map +1 -0
  218. package/dist/brain/l0-cache.js +1 -1
  219. package/dist/brain/l0-cache.js.map +1 -1
  220. package/dist/brain/local-llm.d.ts +20 -0
  221. package/dist/brain/local-llm.d.ts.map +1 -0
  222. package/dist/brain/local-llm.js +132 -0
  223. package/dist/brain/local-llm.js.map +1 -0
  224. package/dist/brain/markdown-export.d.ts +48 -0
  225. package/dist/brain/markdown-export.d.ts.map +1 -0
  226. package/dist/brain/markdown-export.js +382 -0
  227. package/dist/brain/markdown-export.js.map +1 -0
  228. package/dist/brain/mcp-server.d.ts +40 -0
  229. package/dist/brain/mcp-server.d.ts.map +1 -1
  230. package/dist/brain/mcp-server.js +395 -12
  231. package/dist/brain/mcp-server.js.map +1 -1
  232. package/dist/brain/model-registry.d.ts +96 -0
  233. package/dist/brain/model-registry.d.ts.map +1 -0
  234. package/dist/brain/model-registry.js +585 -0
  235. package/dist/brain/model-registry.js.map +1 -0
  236. package/dist/brain/multimodal-vision.d.ts +38 -0
  237. package/dist/brain/multimodal-vision.d.ts.map +1 -0
  238. package/dist/brain/multimodal-vision.js +257 -0
  239. package/dist/brain/multimodal-vision.js.map +1 -0
  240. package/dist/brain/orchestrator.js +1 -1
  241. package/dist/brain/otel-lite.d.ts +71 -0
  242. package/dist/brain/otel-lite.d.ts.map +1 -0
  243. package/dist/brain/otel-lite.js +232 -0
  244. package/dist/brain/otel-lite.js.map +1 -0
  245. package/dist/brain/pr-auto-review.d.ts +17 -0
  246. package/dist/brain/pr-auto-review.d.ts.map +1 -0
  247. package/dist/brain/pr-auto-review.js +73 -0
  248. package/dist/brain/pr-auto-review.js.map +1 -0
  249. package/dist/brain/pre-mortem.d.ts +21 -0
  250. package/dist/brain/pre-mortem.d.ts.map +1 -0
  251. package/dist/brain/pre-mortem.js +210 -0
  252. package/dist/brain/pre-mortem.js.map +1 -0
  253. package/dist/brain/prompt-cache.d.ts +54 -0
  254. package/dist/brain/prompt-cache.d.ts.map +1 -0
  255. package/dist/brain/prompt-cache.js +105 -0
  256. package/dist/brain/prompt-cache.js.map +1 -0
  257. package/dist/brain/reputation-ledger.d.ts +42 -0
  258. package/dist/brain/reputation-ledger.d.ts.map +1 -0
  259. package/dist/brain/reputation-ledger.js +326 -0
  260. package/dist/brain/reputation-ledger.js.map +1 -0
  261. package/dist/brain/session-hooks.d.ts +19 -0
  262. package/dist/brain/session-hooks.d.ts.map +1 -1
  263. package/dist/brain/session-hooks.js +249 -18
  264. package/dist/brain/session-hooks.js.map +1 -1
  265. package/dist/brain/subagent-bridge.d.ts +46 -0
  266. package/dist/brain/subagent-bridge.d.ts.map +1 -0
  267. package/dist/brain/subagent-bridge.js +364 -0
  268. package/dist/brain/subagent-bridge.js.map +1 -0
  269. package/dist/brain/swarm-debate.d.ts +22 -0
  270. package/dist/brain/swarm-debate.d.ts.map +1 -0
  271. package/dist/brain/swarm-debate.js +134 -0
  272. package/dist/brain/swarm-debate.js.map +1 -0
  273. package/dist/brain/team-brain-sync.d.ts +22 -0
  274. package/dist/brain/team-brain-sync.d.ts.map +1 -0
  275. package/dist/brain/team-brain-sync.js +132 -0
  276. package/dist/brain/team-brain-sync.js.map +1 -0
  277. package/dist/brain/token-economy.d.ts +25 -0
  278. package/dist/brain/token-economy.d.ts.map +1 -0
  279. package/dist/brain/token-economy.js +216 -0
  280. package/dist/brain/token-economy.js.map +1 -0
  281. package/dist/brain/voice-mode.d.ts +15 -0
  282. package/dist/brain/voice-mode.d.ts.map +1 -0
  283. package/dist/brain/voice-mode.js +97 -0
  284. package/dist/brain/voice-mode.js.map +1 -0
  285. package/dist/cli.js +1702 -4
  286. package/dist/cli.js.map +1 -1
  287. package/dist/dashboard/server.d.ts +6 -0
  288. package/dist/dashboard/server.d.ts.map +1 -1
  289. package/dist/dashboard/server.js +1118 -368
  290. package/dist/dashboard/server.js.map +1 -1
  291. package/dist/dashboard/v6-dashboard-html.d.ts +2 -0
  292. package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -0
  293. package/dist/dashboard/v6-dashboard-html.js +2474 -0
  294. package/dist/dashboard/v6-dashboard-html.js.map +1 -0
  295. package/dist/index.d.ts +27 -0
  296. package/dist/index.d.ts.map +1 -1
  297. package/dist/index.js +29 -1
  298. package/dist/index.js.map +1 -1
  299. package/dist/types.d.ts +518 -2
  300. package/dist/types.d.ts.map +1 -1
  301. package/package.json +33 -4
@@ -0,0 +1,7 @@
1
+ import { FirewallCheckInput, FirewallDecision } from '../types.js';
2
+ export declare class AgentFirewall {
3
+ check(input: FirewallCheckInput): FirewallDecision;
4
+ formatClaudeHookDecision(decision: FirewallDecision): string;
5
+ private excerpt;
6
+ }
7
+ //# sourceMappingURL=agent-firewall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-firewall.d.ts","sourceRoot":"","sources":["../../src/brain/agent-firewall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAmB,MAAM,aAAa,CAAC;AA8BpF,qBAAa,aAAa;IACxB,KAAK,CAAC,KAAK,EAAE,kBAAkB,GAAG,gBAAgB;IAmHlD,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM;IAW5D,OAAO,CAAC,OAAO;CAGhB"}
@@ -0,0 +1,152 @@
1
+ // src/brain/agent-firewall.ts — Local safety firewall for AI agent tool calls
2
+ const SECRET_PATH = /(^|[/\\])(\.env(\.|$)|id_rsa|id_ed25519|\.npmrc|\.pypirc|\.netrc|credentials|secrets?)([/\\]|$)/i;
3
+ const DESTRUCTIVE_COMMANDS = [
4
+ /\brm\s+-rf\s+(?:\/|\*|~|\$HOME|\.{1,2})(?:\s|$)/i,
5
+ /\bgit\s+reset\s+--hard\b/i,
6
+ /\bgit\s+clean\s+-fdx\b/i,
7
+ /\b(?:mkfs|diskpart|format)\b/i,
8
+ /\bdd\s+if=.*\s+of=\/dev\//i,
9
+ /\bchmod\s+-R\s+777\b/i,
10
+ ];
11
+ const PACKAGE_RISKS = [
12
+ /\b(?:curl|wget)\b[^|;&]*(?:\||&&)\s*(?:sh|bash|zsh)\b/i,
13
+ /\bnpm\s+(?:install|i)\s+(?:-g\s+)?(?:https?:|git\+|github:)/i,
14
+ /\bpip\s+install\s+(?:https?:|git\+)/i,
15
+ /\b(?:npx|pnpm dlx|bunx)\s+[^;\n]*--yes\b/i,
16
+ ];
17
+ const PROMPT_INJECTION = [
18
+ /ignore (?:all )?(?:previous|prior|system|developer) instructions/i,
19
+ /reveal (?:the )?(?:system prompt|developer message|hidden instructions)/i,
20
+ /exfiltrat(?:e|ion)|send (?:all )?(?:files|secrets|credentials)/i,
21
+ /disable (?:security|safety|guardrails|firewall)/i,
22
+ ];
23
+ const SECRET_CONTENT = [
24
+ /(?:api[_-]?key|secret|token|password|passwd|pwd)\s*[:=]\s*["'][^"']{8,}["']/i,
25
+ /(?:api[_-]?key|secret|token|password|passwd|pwd)\s*[:=]\s*[A-Za-z0-9_\-./+=]{12,}/i,
26
+ /-----BEGIN (?:RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----/i,
27
+ /Bearer\s+[A-Za-z0-9\-._~+/]+=*/i,
28
+ ];
29
+ export class AgentFirewall {
30
+ check(input) {
31
+ const findings = [];
32
+ if (input.filePath && SECRET_PATH.test(input.filePath)) {
33
+ findings.push({
34
+ type: 'secret-access',
35
+ severity: 'critical',
36
+ blocked: true,
37
+ reason: 'Agent attempted to access a sensitive credential path.',
38
+ evidence: input.filePath,
39
+ recommendation: 'Use a redacted example file or explicitly approve the path for this session.',
40
+ });
41
+ }
42
+ if (input.command) {
43
+ for (const pattern of DESTRUCTIVE_COMMANDS) {
44
+ if (pattern.test(input.command)) {
45
+ findings.push({
46
+ type: 'destructive-command',
47
+ severity: 'critical',
48
+ blocked: true,
49
+ reason: 'Command matches a destructive shell pattern.',
50
+ evidence: input.command,
51
+ recommendation: 'Use a scoped command, dry-run flag, or require explicit human approval.',
52
+ });
53
+ break;
54
+ }
55
+ }
56
+ for (const pattern of PACKAGE_RISKS) {
57
+ if (pattern.test(input.command)) {
58
+ findings.push({
59
+ type: 'package-risk',
60
+ severity: 'high',
61
+ blocked: true,
62
+ reason: 'Command downloads or executes remote code without a pinned, reviewable artifact.',
63
+ evidence: input.command,
64
+ recommendation: 'Pin the package/version, inspect it first, and avoid curl-to-shell execution.',
65
+ });
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ if (input.url) {
71
+ try {
72
+ const url = new URL(input.url);
73
+ if (url.protocol !== 'https:' && !['localhost', '127.0.0.1', '::1'].includes(url.hostname)) {
74
+ findings.push({
75
+ type: 'network-risk',
76
+ severity: 'medium',
77
+ blocked: false,
78
+ reason: 'Agent is using a non-HTTPS external URL.',
79
+ evidence: input.url,
80
+ recommendation: 'Prefer HTTPS or a localhost development target.',
81
+ });
82
+ }
83
+ }
84
+ catch {
85
+ findings.push({
86
+ type: 'network-risk',
87
+ severity: 'low',
88
+ blocked: false,
89
+ reason: 'URL could not be parsed for safety checks.',
90
+ evidence: input.url,
91
+ recommendation: 'Verify the destination manually before allowing the agent to proceed.',
92
+ });
93
+ }
94
+ }
95
+ if (input.content) {
96
+ for (const pattern of PROMPT_INJECTION) {
97
+ if (pattern.test(input.content)) {
98
+ findings.push({
99
+ type: 'prompt-injection',
100
+ severity: 'high',
101
+ blocked: true,
102
+ reason: 'Content contains prompt-injection language aimed at overriding instructions or leaking data.',
103
+ evidence: this.excerpt(input.content),
104
+ recommendation: 'Treat this content as untrusted. Summarize it instead of injecting it directly.',
105
+ });
106
+ break;
107
+ }
108
+ }
109
+ for (const pattern of SECRET_CONTENT) {
110
+ if (pattern.test(input.content)) {
111
+ findings.push({
112
+ type: 'secret-access',
113
+ severity: 'critical',
114
+ blocked: true,
115
+ reason: 'Content appears to contain a secret or credential.',
116
+ evidence: this.excerpt(input.content),
117
+ recommendation: 'Redact secrets before storing, sharing, or injecting this context.',
118
+ });
119
+ break;
120
+ }
121
+ }
122
+ }
123
+ const riskScore = findings.reduce((score, finding) => {
124
+ const weight = finding.severity === 'critical' ? 1 : finding.severity === 'high' ? 0.7 : finding.severity === 'medium' ? 0.4 : 0.15;
125
+ return Math.max(score, weight);
126
+ }, 0);
127
+ const allowed = !findings.some(f => f.blocked);
128
+ return {
129
+ allowed,
130
+ riskScore,
131
+ findings,
132
+ summary: findings.length
133
+ ? `${findings.filter(f => f.blocked).length} blocked, ${findings.length} finding(s), risk ${(riskScore * 100).toFixed(0)}%`
134
+ : 'Allowed: no firewall findings',
135
+ };
136
+ }
137
+ formatClaudeHookDecision(decision) {
138
+ if (decision.allowed)
139
+ return '';
140
+ return JSON.stringify({
141
+ hookSpecificOutput: {
142
+ hookEventName: 'PreToolUse',
143
+ permissionDecision: 'deny',
144
+ permissionDecisionReason: decision.summary,
145
+ },
146
+ });
147
+ }
148
+ excerpt(content) {
149
+ return content.replace(/\s+/g, ' ').slice(0, 180);
150
+ }
151
+ }
152
+ //# sourceMappingURL=agent-firewall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-firewall.js","sourceRoot":"","sources":["../../src/brain/agent-firewall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { AgentHandoffPacket, AgentTool } from '../types.js';
2
+ import { GlobalBrain } from './global-brain.js';
3
+ export declare class AgentHandoff {
4
+ private brain;
5
+ private firewall;
6
+ constructor(brain?: GlobalBrain);
7
+ generate(opts: {
8
+ fromAgent: AgentTool;
9
+ toAgent: AgentTool;
10
+ projectDir: string;
11
+ task?: string;
12
+ limit?: number;
13
+ }): Promise<AgentHandoffPacket>;
14
+ private getChangedFiles;
15
+ private getGitSummary;
16
+ private getSafetyWarnings;
17
+ private toMarkdown;
18
+ }
19
+ //# sourceMappingURL=agent-handoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-handoff.d.ts","sourceRoot":"","sources":["../../src/brain/agent-handoff.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAGhE,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,KAAK,cAAmB;IAI9B,QAAQ,CAAC,IAAI,EAAE;QACnB,SAAS,EAAE,SAAS,CAAC;QACrB,OAAO,EAAE,SAAS,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAmCjB,eAAe;YAef,aAAa;IAgB3B,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,UAAU;CA+CnB"}
@@ -0,0 +1,127 @@
1
+ // src/brain/agent-handoff.ts — Cross-agent continuation packets
2
+ import * as path from 'path';
3
+ import { GlobalBrain, getGlobalBrain } from './global-brain.js';
4
+ import { AgentFirewall } from './agent-firewall.js';
5
+ export class AgentHandoff {
6
+ constructor(brain = getGlobalBrain()) {
7
+ this.firewall = new AgentFirewall();
8
+ this.brain = brain;
9
+ }
10
+ async generate(opts) {
11
+ await this.brain.init();
12
+ const projectDir = path.resolve(opts.projectDir);
13
+ const projectId = GlobalBrain.projectIdFor(projectDir);
14
+ const projectName = path.basename(projectDir);
15
+ const recentMemories = this.brain.timeline({
16
+ projectId,
17
+ limit: opts.limit ?? 12,
18
+ });
19
+ const changedFiles = await this.getChangedFiles(projectDir);
20
+ const gitSummary = await this.getGitSummary(projectDir);
21
+ const safetyWarnings = this.getSafetyWarnings(recentMemories, changedFiles);
22
+ const task = opts.task || 'Continue the current implementation with the project conventions and warnings below.';
23
+ const packet = {
24
+ fromAgent: opts.fromAgent,
25
+ toAgent: opts.toAgent,
26
+ projectDir,
27
+ projectName,
28
+ task,
29
+ createdAt: new Date(),
30
+ recentMemories,
31
+ changedFiles,
32
+ gitSummary,
33
+ safetyWarnings,
34
+ };
35
+ return {
36
+ ...packet,
37
+ markdown: this.toMarkdown(packet),
38
+ };
39
+ }
40
+ async getChangedFiles(projectDir) {
41
+ try {
42
+ const { execa } = await import('execa');
43
+ const { stdout } = await execa('git', ['status', '--short'], { cwd: projectDir, reject: false });
44
+ return stdout
45
+ .split('\n')
46
+ .map(line => line.trim())
47
+ .filter(Boolean)
48
+ .map(line => line.replace(/^..?\s+/, '').replace(/^"|"$/g, ''))
49
+ .slice(0, 40);
50
+ }
51
+ catch {
52
+ return [];
53
+ }
54
+ }
55
+ async getGitSummary(projectDir) {
56
+ try {
57
+ const { execa } = await import('execa');
58
+ const [branch, diff] = await Promise.all([
59
+ execa('git', ['branch', '--show-current'], { cwd: projectDir, reject: false }),
60
+ execa('git', ['diff', '--stat'], { cwd: projectDir, reject: false }),
61
+ ]);
62
+ return [
63
+ branch.stdout ? `Branch: ${branch.stdout}` : 'Branch: unknown',
64
+ diff.stdout || 'No unstaged diff stat available',
65
+ ].join('\n');
66
+ }
67
+ catch {
68
+ return 'Git summary unavailable.';
69
+ }
70
+ }
71
+ getSafetyWarnings(memories, changedFiles) {
72
+ const warnings = new Set();
73
+ for (const file of changedFiles) {
74
+ const decision = this.firewall.check({ filePath: file });
75
+ for (const finding of decision.findings)
76
+ warnings.add(finding.reason);
77
+ }
78
+ for (const event of memories) {
79
+ const decision = this.firewall.check({ content: event.content });
80
+ for (const finding of decision.findings)
81
+ warnings.add(finding.reason);
82
+ }
83
+ return Array.from(warnings).slice(0, 8);
84
+ }
85
+ toMarkdown(packet) {
86
+ const lines = [
87
+ `# Shadow Brain Agent Handoff`,
88
+ ``,
89
+ `**From:** ${packet.fromAgent}`,
90
+ `**To:** ${packet.toAgent}`,
91
+ `**Project:** ${packet.projectName}`,
92
+ `**Created:** ${packet.createdAt.toISOString()}`,
93
+ ``,
94
+ `## Current Task`,
95
+ packet.task,
96
+ ``,
97
+ `## Git State`,
98
+ '```text',
99
+ packet.gitSummary,
100
+ '```',
101
+ ``,
102
+ `## Changed Files`,
103
+ ...(packet.changedFiles.length ? packet.changedFiles.map(f => `- ${f}`) : ['- No changed files detected']),
104
+ ``,
105
+ `## Recent Shared Memory`,
106
+ ];
107
+ if (packet.recentMemories.length) {
108
+ for (const memory of packet.recentMemories) {
109
+ lines.push(`- [${memory.agentTool}/${memory.category}] ${memory.content.slice(0, 220)}`);
110
+ }
111
+ }
112
+ else {
113
+ lines.push('- No global memories yet. Start by recording decisions and warnings.');
114
+ }
115
+ lines.push('', '## Safety Warnings');
116
+ if (packet.safetyWarnings.length) {
117
+ for (const warning of packet.safetyWarnings)
118
+ lines.push(`- ${warning}`);
119
+ }
120
+ else {
121
+ lines.push('- No safety warnings detected in the handoff packet.');
122
+ }
123
+ lines.push('', '## Instruction For Receiving Agent', 'Continue from this packet. Prefer project-specific memory over generic assumptions. Do not access secrets or run destructive commands without explicit user approval.', '');
124
+ return lines.join('\n');
125
+ }
126
+ }
127
+ //# sourceMappingURL=agent-handoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-handoff.js","sourceRoot":"","sources":["../../src/brain/agent-handoff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { AirGapStatus } from '../types.js';
2
+ export declare class AirGapMode {
3
+ private enabled;
4
+ private policy;
5
+ private blockedOutbound;
6
+ private allowedLocal;
7
+ private lastAttempt;
8
+ private initialized;
9
+ init(): Promise<void>;
10
+ enable(policy?: 'strict' | 'loose'): Promise<void>;
11
+ disable(): Promise<void>;
12
+ isEnabled(): boolean;
13
+ /**
14
+ * Check if a URL is allowed. Call this before any fetch/http from Shadow Brain.
15
+ * Returns false if air-gap is on and the URL is not localhost.
16
+ */
17
+ gate(url: string): Promise<boolean>;
18
+ status(): AirGapStatus;
19
+ private persist;
20
+ }
21
+ export declare function getAirGapMode(): AirGapMode;
22
+ export declare function resetAirGapModeForTests(): void;
23
+ //# sourceMappingURL=air-gap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"air-gap.d.ts","sourceRoot":"","sources":["../../src/brain/air-gap.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAa3C,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,WAAW,CAAS;IAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBrB,MAAM,CAAC,MAAM,GAAE,QAAQ,GAAG,OAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,SAAS,IAAI,OAAO;IAIpB;;;OAGG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyCzC,MAAM,IAAI,YAAY;YAUR,OAAO;CAiBtB;AAID,wBAAgB,aAAa,IAAI,UAAU,CAG1C;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
@@ -0,0 +1,137 @@
1
+ // src/brain/air-gap.ts — Air-Gap Mode
2
+ // v6.0.0 — Hive Mind Edition
3
+ //
4
+ // Opt-in strict mode: block all outbound network from Shadow Brain. Only
5
+ // localhost targets (Ollama, dashboard) are allowed. Enterprise/government
6
+ // friendly — "the brain never leaves this machine."
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import * as os from 'os';
10
+ const STATUS_PATH = path.join(os.homedir(), '.shadow-brain', 'air-gap.json');
11
+ export class AirGapMode {
12
+ constructor() {
13
+ this.enabled = false;
14
+ this.policy = 'strict';
15
+ this.blockedOutbound = 0;
16
+ this.allowedLocal = 0;
17
+ this.lastAttempt = null;
18
+ this.initialized = false;
19
+ }
20
+ async init() {
21
+ if (this.initialized)
22
+ return;
23
+ fs.mkdirSync(path.dirname(STATUS_PATH), { recursive: true });
24
+ if (fs.existsSync(STATUS_PATH)) {
25
+ try {
26
+ const parsed = JSON.parse(fs.readFileSync(STATUS_PATH, 'utf-8'));
27
+ this.enabled = parsed.enabled ?? false;
28
+ this.policy = parsed.policy ?? 'strict';
29
+ this.blockedOutbound = parsed.blockedOutboundCount ?? 0;
30
+ this.allowedLocal = parsed.allowedLocalCount ?? 0;
31
+ this.lastAttempt = parsed.lastAttempt ? new Date(parsed.lastAttempt) : null;
32
+ }
33
+ catch {
34
+ /* skip */
35
+ }
36
+ }
37
+ if (this.enabled)
38
+ process.env.SHADOW_BRAIN_AIR_GAP = '1';
39
+ this.initialized = true;
40
+ }
41
+ async enable(policy = 'strict') {
42
+ await this.init();
43
+ this.enabled = true;
44
+ this.policy = policy;
45
+ process.env.SHADOW_BRAIN_AIR_GAP = '1';
46
+ await this.persist();
47
+ }
48
+ async disable() {
49
+ await this.init();
50
+ this.enabled = false;
51
+ delete process.env.SHADOW_BRAIN_AIR_GAP;
52
+ await this.persist();
53
+ }
54
+ isEnabled() {
55
+ return this.enabled;
56
+ }
57
+ /**
58
+ * Check if a URL is allowed. Call this before any fetch/http from Shadow Brain.
59
+ * Returns false if air-gap is on and the URL is not localhost.
60
+ */
61
+ async gate(url) {
62
+ await this.init();
63
+ this.lastAttempt = new Date();
64
+ if (!this.enabled) {
65
+ this.allowedLocal++;
66
+ await this.persist();
67
+ return true;
68
+ }
69
+ try {
70
+ const u = new URL(url);
71
+ const host = u.hostname;
72
+ const isLocal = host === 'localhost'
73
+ || host === '127.0.0.1'
74
+ || host === '::1'
75
+ || host === '0.0.0.0'
76
+ || /^10\./.test(host)
77
+ || /^192\.168\./.test(host)
78
+ || /^172\.(1[6-9]|2\d|3[01])\./.test(host);
79
+ // Strict policy: refuse RFC1918 private ranges too (they may leave network)
80
+ if (this.policy === 'strict' && !['localhost', '127.0.0.1', '::1'].includes(host)) {
81
+ this.blockedOutbound++;
82
+ await this.persist();
83
+ return false;
84
+ }
85
+ if (!isLocal) {
86
+ this.blockedOutbound++;
87
+ await this.persist();
88
+ return false;
89
+ }
90
+ this.allowedLocal++;
91
+ await this.persist();
92
+ return true;
93
+ }
94
+ catch {
95
+ this.blockedOutbound++;
96
+ await this.persist();
97
+ return false;
98
+ }
99
+ }
100
+ status() {
101
+ return {
102
+ enabled: this.enabled,
103
+ blockedOutboundCount: this.blockedOutbound,
104
+ allowedLocalCount: this.allowedLocal,
105
+ lastAttempt: this.lastAttempt,
106
+ policy: this.policy,
107
+ };
108
+ }
109
+ async persist() {
110
+ try {
111
+ const payload = {
112
+ schemaVersion: 1,
113
+ enabled: this.enabled,
114
+ policy: this.policy,
115
+ blockedOutboundCount: this.blockedOutbound,
116
+ allowedLocalCount: this.allowedLocal,
117
+ lastAttempt: this.lastAttempt ? this.lastAttempt.toISOString() : null,
118
+ };
119
+ const tmp = STATUS_PATH + '.tmp';
120
+ fs.writeFileSync(tmp, JSON.stringify(payload, null, 2));
121
+ fs.renameSync(tmp, STATUS_PATH);
122
+ }
123
+ catch {
124
+ /* non-fatal */
125
+ }
126
+ }
127
+ }
128
+ let _instance = null;
129
+ export function getAirGapMode() {
130
+ if (!_instance)
131
+ _instance = new AirGapMode();
132
+ return _instance;
133
+ }
134
+ export function resetAirGapModeForTests() {
135
+ _instance = null;
136
+ }
137
+ //# sourceMappingURL=air-gap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"air-gap.js","sourceRoot":"","sources":["../../src/brain/air-gap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { AttentionReport, AgentTool } from '../types.js';
2
+ export declare class AttentionHeatmap {
3
+ private brain;
4
+ constructor();
5
+ /**
6
+ * Compute attention for a given decision. Inputs:
7
+ * - decisionText: the AI output we're attributing
8
+ * - candidateMemoryIds: memories that were visible to the agent
9
+ */
10
+ compute(opts: {
11
+ decisionText: string;
12
+ candidateMemoryIds: string[];
13
+ agentTool: AgentTool;
14
+ }): Promise<AttentionReport>;
15
+ /** Text-based heatmap rendered as a simple ASCII bar chart. */
16
+ renderText(report: AttentionReport): string;
17
+ private genId;
18
+ private similarity;
19
+ private tokenSet;
20
+ private explain;
21
+ }
22
+ export declare function getAttentionHeatmap(): AttentionHeatmap;
23
+ export declare function resetAttentionHeatmapForTests(): void;
24
+ //# sourceMappingURL=attention-heatmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention-heatmap.d.ts","sourceRoot":"","sources":["../../src/brain/attention-heatmap.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,eAAe,EAEf,SAAS,EAEV,MAAM,aAAa,CAAC;AAGrB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAc;;IAM3B;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,SAAS,EAAE,SAAS,CAAC;KACtB,GAAG,OAAO,CAAC,eAAe,CAAC;IAwC5B,+DAA+D;IAC/D,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM;IAgB3C,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,OAAO;CAGhB;AAID,wBAAgB,mBAAmB,IAAI,gBAAgB,CAGtD;AAED,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD"}
@@ -0,0 +1,108 @@
1
+ // src/brain/attention-heatmap.ts — Mechanistic interpretability for brain decisions
2
+ // v6.0.0 — Hive Mind Edition
3
+ //
4
+ // After any AI decision is made with brain input, show which memories influenced
5
+ // the output, with weighted attribution.
6
+ //
7
+ // Not a gradient-based attention (we don't have the model internals) — instead
8
+ // it's a RETRIEVAL-WEIGHTED attribution that approximates mechanistic attention
9
+ // via semantic similarity + explicit citation tracking.
10
+ import * as crypto from 'crypto';
11
+ import { getGlobalBrain } from './global-brain.js';
12
+ export class AttentionHeatmap {
13
+ constructor() {
14
+ this.brain = getGlobalBrain();
15
+ }
16
+ /**
17
+ * Compute attention for a given decision. Inputs:
18
+ * - decisionText: the AI output we're attributing
19
+ * - candidateMemoryIds: memories that were visible to the agent
20
+ */
21
+ async compute(opts) {
22
+ await this.brain.init();
23
+ const candidates = this.brain.recallByIds(opts.candidateMemoryIds);
24
+ if (!candidates.length) {
25
+ return {
26
+ decisionId: this.genId(opts.decisionText),
27
+ decisionText: opts.decisionText,
28
+ agentTool: opts.agentTool,
29
+ weights: [],
30
+ totalMemoriesConsidered: 0,
31
+ generatedAt: new Date(),
32
+ };
33
+ }
34
+ const rawWeights = candidates.map(mem => ({
35
+ mem,
36
+ raw: this.similarity(opts.decisionText, mem.content) + mem.importance * 0.5,
37
+ }));
38
+ const total = rawWeights.reduce((sum, w) => sum + w.raw, 0) || 1;
39
+ const weights = rawWeights
40
+ .map(({ mem, raw }) => ({
41
+ memoryId: mem.id,
42
+ memoryContent: mem.content.slice(0, 160),
43
+ weight: +(raw / total).toFixed(4),
44
+ category: mem.category,
45
+ reasoning: this.explain(opts.decisionText, mem),
46
+ }))
47
+ .sort((a, b) => b.weight - a.weight);
48
+ return {
49
+ decisionId: this.genId(opts.decisionText),
50
+ decisionText: opts.decisionText,
51
+ agentTool: opts.agentTool,
52
+ weights,
53
+ totalMemoriesConsidered: candidates.length,
54
+ generatedAt: new Date(),
55
+ };
56
+ }
57
+ /** Text-based heatmap rendered as a simple ASCII bar chart. */
58
+ renderText(report) {
59
+ const lines = [
60
+ `Decision: ${report.decisionText.slice(0, 120)}`,
61
+ `Agent: ${report.agentTool} · Memories considered: ${report.totalMemoriesConsidered}`,
62
+ ``,
63
+ ];
64
+ const top = report.weights.slice(0, 8);
65
+ for (const w of top) {
66
+ const bar = '█'.repeat(Math.min(30, Math.round(w.weight * 50)));
67
+ lines.push(`${(w.weight * 100).toFixed(1).padStart(5)}% ${bar} [${w.category}] ${w.memoryContent.slice(0, 60)}`);
68
+ }
69
+ return lines.join('\n');
70
+ }
71
+ // ── Internals ─────────────────────────────────────────────────────────────
72
+ genId(text) {
73
+ return 'dec-' + crypto.createHash('sha1').update(text).digest('hex').slice(0, 12);
74
+ }
75
+ similarity(a, b) {
76
+ // Token-set Jaccard (fast, no embedding deps)
77
+ const setA = this.tokenSet(a);
78
+ const setB = this.tokenSet(b);
79
+ if (!setA.size || !setB.size)
80
+ return 0.01;
81
+ let intersect = 0;
82
+ for (const t of setA)
83
+ if (setB.has(t))
84
+ intersect++;
85
+ const union = setA.size + setB.size - intersect;
86
+ return union ? intersect / union : 0;
87
+ }
88
+ tokenSet(s) {
89
+ const stopwords = new Set(['the', 'a', 'an', 'and', 'or', 'of', 'to', 'in', 'on', 'is', 'it', 'this', 'that']);
90
+ return new Set(s.toLowerCase()
91
+ .replace(/[^a-z0-9\s-]/g, ' ')
92
+ .split(/\s+/)
93
+ .filter(t => t.length > 2 && !stopwords.has(t)));
94
+ }
95
+ explain(_decision, mem) {
96
+ return `${mem.category} · importance ${Math.round(mem.importance * 100)}%`;
97
+ }
98
+ }
99
+ let _instance = null;
100
+ export function getAttentionHeatmap() {
101
+ if (!_instance)
102
+ _instance = new AttentionHeatmap();
103
+ return _instance;
104
+ }
105
+ export function resetAttentionHeatmapForTests() {
106
+ _instance = null;
107
+ }
108
+ //# sourceMappingURL=attention-heatmap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention-heatmap.js","sourceRoot":"","sources":["../../src/brain/attention-heatmap.ts"],"names":[],"mappings":"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"}