shieldcortex 2.0.0

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 (377) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +282 -0
  3. package/dashboard/components.json +22 -0
  4. package/dashboard/eslint.config.mjs +42 -0
  5. package/dashboard/next.config.ts +7 -0
  6. package/dashboard/package-lock.json +8053 -0
  7. package/dashboard/package.json +44 -0
  8. package/dashboard/postcss.config.mjs +7 -0
  9. package/dashboard/public/file.svg +1 -0
  10. package/dashboard/public/globe.svg +1 -0
  11. package/dashboard/public/next.svg +1 -0
  12. package/dashboard/public/vercel.svg +1 -0
  13. package/dashboard/public/window.svg +1 -0
  14. package/dashboard/scripts/ensure-api.mjs +76 -0
  15. package/dashboard/src/app/error.tsx +49 -0
  16. package/dashboard/src/app/favicon.ico +0 -0
  17. package/dashboard/src/app/globals.css +130 -0
  18. package/dashboard/src/app/layout.tsx +35 -0
  19. package/dashboard/src/app/page.tsx +364 -0
  20. package/dashboard/src/components/Providers.tsx +27 -0
  21. package/dashboard/src/components/brain/ActivityPulseSystem.tsx +229 -0
  22. package/dashboard/src/components/brain/BrainMesh.tsx +133 -0
  23. package/dashboard/src/components/brain/BrainRegions.tsx +254 -0
  24. package/dashboard/src/components/brain/BrainScene.tsx +255 -0
  25. package/dashboard/src/components/brain/CategoryLabels.tsx +103 -0
  26. package/dashboard/src/components/brain/CoreSphere.tsx +215 -0
  27. package/dashboard/src/components/brain/DataFlowParticles.tsx +123 -0
  28. package/dashboard/src/components/brain/DataStreamRings.tsx +161 -0
  29. package/dashboard/src/components/brain/ElectronFlow.tsx +323 -0
  30. package/dashboard/src/components/brain/HolographicGrid.tsx +235 -0
  31. package/dashboard/src/components/brain/MemoryLinks.tsx +271 -0
  32. package/dashboard/src/components/brain/MemoryNode.tsx +245 -0
  33. package/dashboard/src/components/brain/NeuralPathways.tsx +441 -0
  34. package/dashboard/src/components/brain/SynapseNodes.tsx +312 -0
  35. package/dashboard/src/components/brain/TimelineControls.tsx +205 -0
  36. package/dashboard/src/components/chip/ChipScene.tsx +497 -0
  37. package/dashboard/src/components/chip/ChipSubstrate.tsx +238 -0
  38. package/dashboard/src/components/chip/CortexCore.tsx +210 -0
  39. package/dashboard/src/components/chip/DataBus.tsx +416 -0
  40. package/dashboard/src/components/chip/MemoryCell.tsx +225 -0
  41. package/dashboard/src/components/chip/MemoryGrid.tsx +328 -0
  42. package/dashboard/src/components/chip/QuantumCell.tsx +316 -0
  43. package/dashboard/src/components/chip/SectionLabel.tsx +113 -0
  44. package/dashboard/src/components/chip/index.ts +14 -0
  45. package/dashboard/src/components/controls/ControlPanel.tsx +106 -0
  46. package/dashboard/src/components/controls/VersionPanel.tsx +185 -0
  47. package/dashboard/src/components/dashboard/StatsPanel.tsx +164 -0
  48. package/dashboard/src/components/debug/ActivityLog.tsx +250 -0
  49. package/dashboard/src/components/debug/DebugPanel.tsx +101 -0
  50. package/dashboard/src/components/debug/QueryTester.tsx +192 -0
  51. package/dashboard/src/components/debug/RelationshipGraph.tsx +403 -0
  52. package/dashboard/src/components/debug/SqlConsole.tsx +319 -0
  53. package/dashboard/src/components/graph/KnowledgeGraph.tsx +230 -0
  54. package/dashboard/src/components/graph/OntologyGraph.tsx +631 -0
  55. package/dashboard/src/components/insights/ActivityHeatmap.tsx +131 -0
  56. package/dashboard/src/components/insights/InsightsView.tsx +46 -0
  57. package/dashboard/src/components/insights/KnowledgeMapPanel.tsx +80 -0
  58. package/dashboard/src/components/insights/QualityPanel.tsx +116 -0
  59. package/dashboard/src/components/memories/MemoriesView.tsx +150 -0
  60. package/dashboard/src/components/memories/MemoryCard.tsx +103 -0
  61. package/dashboard/src/components/memory/MemoryDetail.tsx +325 -0
  62. package/dashboard/src/components/nav/NavRail.tsx +54 -0
  63. package/dashboard/src/components/ui/button.tsx +62 -0
  64. package/dashboard/src/components/ui/card.tsx +92 -0
  65. package/dashboard/src/components/ui/input.tsx +21 -0
  66. package/dashboard/src/hooks/useDebouncedValue.ts +24 -0
  67. package/dashboard/src/hooks/useMemories.ts +458 -0
  68. package/dashboard/src/hooks/useSuggestions.ts +46 -0
  69. package/dashboard/src/lib/category-colors.ts +84 -0
  70. package/dashboard/src/lib/position-algorithm.ts +177 -0
  71. package/dashboard/src/lib/simplex-noise.ts +217 -0
  72. package/dashboard/src/lib/store.ts +88 -0
  73. package/dashboard/src/lib/utils.ts +6 -0
  74. package/dashboard/src/lib/websocket.ts +249 -0
  75. package/dashboard/src/types/memory.ts +73 -0
  76. package/dashboard/tsconfig.json +34 -0
  77. package/dist/__tests__/consolidation-merge.test.d.ts +9 -0
  78. package/dist/__tests__/consolidation-merge.test.d.ts.map +1 -0
  79. package/dist/__tests__/consolidation-merge.test.js +137 -0
  80. package/dist/__tests__/consolidation-merge.test.js.map +1 -0
  81. package/dist/__tests__/contradictions.test.d.ts +8 -0
  82. package/dist/__tests__/contradictions.test.d.ts.map +1 -0
  83. package/dist/__tests__/contradictions.test.js +78 -0
  84. package/dist/__tests__/contradictions.test.js.map +1 -0
  85. package/dist/__tests__/salience-evolution.test.d.ts +7 -0
  86. package/dist/__tests__/salience-evolution.test.d.ts.map +1 -0
  87. package/dist/__tests__/salience-evolution.test.js +151 -0
  88. package/dist/__tests__/salience-evolution.test.js.map +1 -0
  89. package/dist/__tests__/store.test.d.ts +7 -0
  90. package/dist/__tests__/store.test.d.ts.map +1 -0
  91. package/dist/__tests__/store.test.js +582 -0
  92. package/dist/__tests__/store.test.js.map +1 -0
  93. package/dist/api/control.d.ts +27 -0
  94. package/dist/api/control.d.ts.map +1 -0
  95. package/dist/api/control.js +60 -0
  96. package/dist/api/control.js.map +1 -0
  97. package/dist/api/events.d.ts +159 -0
  98. package/dist/api/events.d.ts.map +1 -0
  99. package/dist/api/events.js +155 -0
  100. package/dist/api/events.js.map +1 -0
  101. package/dist/api/version.d.ts +36 -0
  102. package/dist/api/version.d.ts.map +1 -0
  103. package/dist/api/version.js +146 -0
  104. package/dist/api/version.js.map +1 -0
  105. package/dist/api/visualization-server.d.ts +11 -0
  106. package/dist/api/visualization-server.d.ts.map +1 -0
  107. package/dist/api/visualization-server.js +1186 -0
  108. package/dist/api/visualization-server.js.map +1 -0
  109. package/dist/context/project-context.d.ts +57 -0
  110. package/dist/context/project-context.d.ts.map +1 -0
  111. package/dist/context/project-context.js +135 -0
  112. package/dist/context/project-context.js.map +1 -0
  113. package/dist/database/init.d.ts +49 -0
  114. package/dist/database/init.d.ts.map +1 -0
  115. package/dist/database/init.js +567 -0
  116. package/dist/database/init.js.map +1 -0
  117. package/dist/defence/__tests__/firewall.test.d.ts +8 -0
  118. package/dist/defence/__tests__/firewall.test.d.ts.map +1 -0
  119. package/dist/defence/__tests__/firewall.test.js +123 -0
  120. package/dist/defence/__tests__/firewall.test.js.map +1 -0
  121. package/dist/defence/__tests__/fragmentation.test.d.ts +7 -0
  122. package/dist/defence/__tests__/fragmentation.test.d.ts.map +1 -0
  123. package/dist/defence/__tests__/fragmentation.test.js +51 -0
  124. package/dist/defence/__tests__/fragmentation.test.js.map +1 -0
  125. package/dist/defence/__tests__/pipeline.test.d.ts +8 -0
  126. package/dist/defence/__tests__/pipeline.test.d.ts.map +1 -0
  127. package/dist/defence/__tests__/pipeline.test.js +61 -0
  128. package/dist/defence/__tests__/pipeline.test.js.map +1 -0
  129. package/dist/defence/__tests__/sensitivity.test.d.ts +7 -0
  130. package/dist/defence/__tests__/sensitivity.test.d.ts.map +1 -0
  131. package/dist/defence/__tests__/sensitivity.test.js +61 -0
  132. package/dist/defence/__tests__/sensitivity.test.js.map +1 -0
  133. package/dist/defence/__tests__/trust.test.d.ts +7 -0
  134. package/dist/defence/__tests__/trust.test.d.ts.map +1 -0
  135. package/dist/defence/__tests__/trust.test.js +49 -0
  136. package/dist/defence/__tests__/trust.test.js.map +1 -0
  137. package/dist/defence/audit/index.d.ts +4 -0
  138. package/dist/defence/audit/index.d.ts.map +1 -0
  139. package/dist/defence/audit/index.js +3 -0
  140. package/dist/defence/audit/index.js.map +1 -0
  141. package/dist/defence/audit/logger.d.ts +14 -0
  142. package/dist/defence/audit/logger.d.ts.map +1 -0
  143. package/dist/defence/audit/logger.js +54 -0
  144. package/dist/defence/audit/logger.js.map +1 -0
  145. package/dist/defence/audit/queries.d.ts +33 -0
  146. package/dist/defence/audit/queries.d.ts.map +1 -0
  147. package/dist/defence/audit/queries.js +103 -0
  148. package/dist/defence/audit/queries.js.map +1 -0
  149. package/dist/defence/firewall/anomaly-scorer.d.ts +8 -0
  150. package/dist/defence/firewall/anomaly-scorer.d.ts.map +1 -0
  151. package/dist/defence/firewall/anomaly-scorer.js +58 -0
  152. package/dist/defence/firewall/anomaly-scorer.js.map +1 -0
  153. package/dist/defence/firewall/encoding-detector.d.ts +13 -0
  154. package/dist/defence/firewall/encoding-detector.d.ts.map +1 -0
  155. package/dist/defence/firewall/encoding-detector.js +120 -0
  156. package/dist/defence/firewall/encoding-detector.js.map +1 -0
  157. package/dist/defence/firewall/index.d.ts +21 -0
  158. package/dist/defence/firewall/index.d.ts.map +1 -0
  159. package/dist/defence/firewall/index.js +133 -0
  160. package/dist/defence/firewall/index.js.map +1 -0
  161. package/dist/defence/firewall/instruction-detector.d.ts +12 -0
  162. package/dist/defence/firewall/instruction-detector.d.ts.map +1 -0
  163. package/dist/defence/firewall/instruction-detector.js +99 -0
  164. package/dist/defence/firewall/instruction-detector.js.map +1 -0
  165. package/dist/defence/firewall/privilege-detector.d.ts +13 -0
  166. package/dist/defence/firewall/privilege-detector.d.ts.map +1 -0
  167. package/dist/defence/firewall/privilege-detector.js +89 -0
  168. package/dist/defence/firewall/privilege-detector.js.map +1 -0
  169. package/dist/defence/fragmentation/assembly-detector.d.ts +18 -0
  170. package/dist/defence/fragmentation/assembly-detector.d.ts.map +1 -0
  171. package/dist/defence/fragmentation/assembly-detector.js +72 -0
  172. package/dist/defence/fragmentation/assembly-detector.js.map +1 -0
  173. package/dist/defence/fragmentation/entity-extractor.d.ts +19 -0
  174. package/dist/defence/fragmentation/entity-extractor.d.ts.map +1 -0
  175. package/dist/defence/fragmentation/entity-extractor.js +86 -0
  176. package/dist/defence/fragmentation/entity-extractor.js.map +1 -0
  177. package/dist/defence/fragmentation/index.d.ts +23 -0
  178. package/dist/defence/fragmentation/index.d.ts.map +1 -0
  179. package/dist/defence/fragmentation/index.js +49 -0
  180. package/dist/defence/fragmentation/index.js.map +1 -0
  181. package/dist/defence/fragmentation/temporal-analyzer.d.ts +28 -0
  182. package/dist/defence/fragmentation/temporal-analyzer.d.ts.map +1 -0
  183. package/dist/defence/fragmentation/temporal-analyzer.js +41 -0
  184. package/dist/defence/fragmentation/temporal-analyzer.js.map +1 -0
  185. package/dist/defence/index.d.ts +12 -0
  186. package/dist/defence/index.d.ts.map +1 -0
  187. package/dist/defence/index.js +18 -0
  188. package/dist/defence/index.js.map +1 -0
  189. package/dist/defence/pipeline.d.ts +9 -0
  190. package/dist/defence/pipeline.d.ts.map +1 -0
  191. package/dist/defence/pipeline.js +115 -0
  192. package/dist/defence/pipeline.js.map +1 -0
  193. package/dist/defence/scanner/index.d.ts +5 -0
  194. package/dist/defence/scanner/index.d.ts.map +1 -0
  195. package/dist/defence/scanner/index.js +5 -0
  196. package/dist/defence/scanner/index.js.map +1 -0
  197. package/dist/defence/scanner/scan-existing.d.ts +34 -0
  198. package/dist/defence/scanner/scan-existing.d.ts.map +1 -0
  199. package/dist/defence/scanner/scan-existing.js +136 -0
  200. package/dist/defence/scanner/scan-existing.js.map +1 -0
  201. package/dist/defence/sensitivity/classifier.d.ts +6 -0
  202. package/dist/defence/sensitivity/classifier.d.ts.map +1 -0
  203. package/dist/defence/sensitivity/classifier.js +50 -0
  204. package/dist/defence/sensitivity/classifier.js.map +1 -0
  205. package/dist/defence/sensitivity/index.d.ts +11 -0
  206. package/dist/defence/sensitivity/index.d.ts.map +1 -0
  207. package/dist/defence/sensitivity/index.js +13 -0
  208. package/dist/defence/sensitivity/index.js.map +1 -0
  209. package/dist/defence/sensitivity/patterns.d.ts +14 -0
  210. package/dist/defence/sensitivity/patterns.d.ts.map +1 -0
  211. package/dist/defence/sensitivity/patterns.js +67 -0
  212. package/dist/defence/sensitivity/patterns.js.map +1 -0
  213. package/dist/defence/sensitivity/redaction.d.ts +17 -0
  214. package/dist/defence/sensitivity/redaction.d.ts.map +1 -0
  215. package/dist/defence/sensitivity/redaction.js +47 -0
  216. package/dist/defence/sensitivity/redaction.js.map +1 -0
  217. package/dist/defence/trust/index.d.ts +3 -0
  218. package/dist/defence/trust/index.d.ts.map +1 -0
  219. package/dist/defence/trust/index.js +3 -0
  220. package/dist/defence/trust/index.js.map +1 -0
  221. package/dist/defence/trust/recall-filter.d.ts +10 -0
  222. package/dist/defence/trust/recall-filter.d.ts.map +1 -0
  223. package/dist/defence/trust/recall-filter.js +38 -0
  224. package/dist/defence/trust/recall-filter.js.map +1 -0
  225. package/dist/defence/trust/source-scorer.d.ts +6 -0
  226. package/dist/defence/trust/source-scorer.d.ts.map +1 -0
  227. package/dist/defence/trust/source-scorer.js +34 -0
  228. package/dist/defence/trust/source-scorer.js.map +1 -0
  229. package/dist/defence/types.d.ts +88 -0
  230. package/dist/defence/types.d.ts.map +1 -0
  231. package/dist/defence/types.js +15 -0
  232. package/dist/defence/types.js.map +1 -0
  233. package/dist/embeddings/generator.d.ts +20 -0
  234. package/dist/embeddings/generator.d.ts.map +1 -0
  235. package/dist/embeddings/generator.js +83 -0
  236. package/dist/embeddings/generator.js.map +1 -0
  237. package/dist/embeddings/index.d.ts +2 -0
  238. package/dist/embeddings/index.d.ts.map +1 -0
  239. package/dist/embeddings/index.js +2 -0
  240. package/dist/embeddings/index.js.map +1 -0
  241. package/dist/errors.d.ts +74 -0
  242. package/dist/errors.d.ts.map +1 -0
  243. package/dist/errors.js +131 -0
  244. package/dist/errors.js.map +1 -0
  245. package/dist/graph/backfill.d.ts +6 -0
  246. package/dist/graph/backfill.d.ts.map +1 -0
  247. package/dist/graph/backfill.js +33 -0
  248. package/dist/graph/backfill.js.map +1 -0
  249. package/dist/graph/extract.d.ts +21 -0
  250. package/dist/graph/extract.d.ts.map +1 -0
  251. package/dist/graph/extract.js +231 -0
  252. package/dist/graph/extract.js.map +1 -0
  253. package/dist/graph/resolve.d.ts +6 -0
  254. package/dist/graph/resolve.d.ts.map +1 -0
  255. package/dist/graph/resolve.js +126 -0
  256. package/dist/graph/resolve.js.map +1 -0
  257. package/dist/index.d.ts +31 -0
  258. package/dist/index.d.ts.map +1 -0
  259. package/dist/index.js +248 -0
  260. package/dist/index.js.map +1 -0
  261. package/dist/memory/activation.d.ts +69 -0
  262. package/dist/memory/activation.d.ts.map +1 -0
  263. package/dist/memory/activation.js +168 -0
  264. package/dist/memory/activation.js.map +1 -0
  265. package/dist/memory/consolidate.d.ts +98 -0
  266. package/dist/memory/consolidate.d.ts.map +1 -0
  267. package/dist/memory/consolidate.js +511 -0
  268. package/dist/memory/consolidate.js.map +1 -0
  269. package/dist/memory/contradiction.d.ts +69 -0
  270. package/dist/memory/contradiction.d.ts.map +1 -0
  271. package/dist/memory/contradiction.js +286 -0
  272. package/dist/memory/contradiction.js.map +1 -0
  273. package/dist/memory/decay.d.ts +62 -0
  274. package/dist/memory/decay.d.ts.map +1 -0
  275. package/dist/memory/decay.js +184 -0
  276. package/dist/memory/decay.js.map +1 -0
  277. package/dist/memory/salience.d.ts +36 -0
  278. package/dist/memory/salience.d.ts.map +1 -0
  279. package/dist/memory/salience.js +216 -0
  280. package/dist/memory/salience.js.map +1 -0
  281. package/dist/memory/similarity.d.ts +57 -0
  282. package/dist/memory/similarity.d.ts.map +1 -0
  283. package/dist/memory/similarity.js +114 -0
  284. package/dist/memory/similarity.js.map +1 -0
  285. package/dist/memory/store.d.ts +179 -0
  286. package/dist/memory/store.d.ts.map +1 -0
  287. package/dist/memory/store.js +1184 -0
  288. package/dist/memory/store.js.map +1 -0
  289. package/dist/memory/types.d.ts +97 -0
  290. package/dist/memory/types.d.ts.map +1 -0
  291. package/dist/memory/types.js +30 -0
  292. package/dist/memory/types.js.map +1 -0
  293. package/dist/server.d.ts +12 -0
  294. package/dist/server.d.ts.map +1 -0
  295. package/dist/server.js +568 -0
  296. package/dist/server.js.map +1 -0
  297. package/dist/service/install.d.ts +15 -0
  298. package/dist/service/install.d.ts.map +1 -0
  299. package/dist/service/install.js +178 -0
  300. package/dist/service/install.js.map +1 -0
  301. package/dist/service/templates.d.ts +13 -0
  302. package/dist/service/templates.d.ts.map +1 -0
  303. package/dist/service/templates.js +58 -0
  304. package/dist/service/templates.js.map +1 -0
  305. package/dist/setup/claude-md.d.ts +12 -0
  306. package/dist/setup/claude-md.d.ts.map +1 -0
  307. package/dist/setup/claude-md.js +68 -0
  308. package/dist/setup/claude-md.js.map +1 -0
  309. package/dist/setup/clawdbot.d.ts +15 -0
  310. package/dist/setup/clawdbot.d.ts.map +1 -0
  311. package/dist/setup/clawdbot.js +118 -0
  312. package/dist/setup/clawdbot.js.map +1 -0
  313. package/dist/setup/doctor.d.ts +5 -0
  314. package/dist/setup/doctor.d.ts.map +1 -0
  315. package/dist/setup/doctor.js +141 -0
  316. package/dist/setup/doctor.js.map +1 -0
  317. package/dist/setup/hooks.d.ts +6 -0
  318. package/dist/setup/hooks.d.ts.map +1 -0
  319. package/dist/setup/hooks.js +36 -0
  320. package/dist/setup/hooks.js.map +1 -0
  321. package/dist/setup/migrate.d.ts +16 -0
  322. package/dist/setup/migrate.d.ts.map +1 -0
  323. package/dist/setup/migrate.js +164 -0
  324. package/dist/setup/migrate.js.map +1 -0
  325. package/dist/setup/settings-hooks.d.ts +7 -0
  326. package/dist/setup/settings-hooks.d.ts.map +1 -0
  327. package/dist/setup/settings-hooks.js +83 -0
  328. package/dist/setup/settings-hooks.js.map +1 -0
  329. package/dist/setup/uninstall.d.ts +12 -0
  330. package/dist/setup/uninstall.d.ts.map +1 -0
  331. package/dist/setup/uninstall.js +125 -0
  332. package/dist/setup/uninstall.js.map +1 -0
  333. package/dist/tools/context.d.ts +135 -0
  334. package/dist/tools/context.d.ts.map +1 -0
  335. package/dist/tools/context.js +273 -0
  336. package/dist/tools/context.js.map +1 -0
  337. package/dist/tools/forget.d.ts +53 -0
  338. package/dist/tools/forget.d.ts.map +1 -0
  339. package/dist/tools/forget.js +179 -0
  340. package/dist/tools/forget.js.map +1 -0
  341. package/dist/tools/graph.d.ts +46 -0
  342. package/dist/tools/graph.d.ts.map +1 -0
  343. package/dist/tools/graph.js +206 -0
  344. package/dist/tools/graph.js.map +1 -0
  345. package/dist/tools/recall.d.ts +79 -0
  346. package/dist/tools/recall.d.ts.map +1 -0
  347. package/dist/tools/recall.js +156 -0
  348. package/dist/tools/recall.js.map +1 -0
  349. package/dist/tools/remember.d.ts +83 -0
  350. package/dist/tools/remember.d.ts.map +1 -0
  351. package/dist/tools/remember.js +151 -0
  352. package/dist/tools/remember.js.map +1 -0
  353. package/dist/worker/brain-worker.d.ts +100 -0
  354. package/dist/worker/brain-worker.d.ts.map +1 -0
  355. package/dist/worker/brain-worker.js +283 -0
  356. package/dist/worker/brain-worker.js.map +1 -0
  357. package/dist/worker/link-discovery.d.ts +47 -0
  358. package/dist/worker/link-discovery.d.ts.map +1 -0
  359. package/dist/worker/link-discovery.js +103 -0
  360. package/dist/worker/link-discovery.js.map +1 -0
  361. package/dist/worker/predictive-consolidation.d.ts +46 -0
  362. package/dist/worker/predictive-consolidation.d.ts.map +1 -0
  363. package/dist/worker/predictive-consolidation.js +110 -0
  364. package/dist/worker/predictive-consolidation.js.map +1 -0
  365. package/dist/worker/types.d.ts +91 -0
  366. package/dist/worker/types.d.ts.map +1 -0
  367. package/dist/worker/types.js +22 -0
  368. package/dist/worker/types.js.map +1 -0
  369. package/hooks/clawdbot/cortex-memory/HOOK.md +71 -0
  370. package/hooks/clawdbot/cortex-memory/handler.js +279 -0
  371. package/package.json +73 -0
  372. package/scripts/pre-compact-hook.mjs +716 -0
  373. package/scripts/session-end-hook.mjs +548 -0
  374. package/scripts/session-start-hook.mjs +221 -0
  375. package/scripts/start-dashboard.sh +41 -0
  376. package/scripts/stop-dashboard.sh +21 -0
  377. package/scripts/stop-hook.mjs +163 -0
@@ -0,0 +1,403 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Relationship Graph Component - Focus Mode
5
+ *
6
+ * Clean visualization: click a memory to see its direct connections.
7
+ * Unselected state shows all nodes dimmed, selected shows focus view.
8
+ */
9
+
10
+ import { useEffect, useRef, useState, useMemo } from 'react';
11
+ import { useMemoryLinks, useMemories } from '@/hooks/useMemories';
12
+ // Memory and MemoryLink types used implicitly via hooks
13
+
14
+ interface Node {
15
+ id: number;
16
+ title: string;
17
+ category: string;
18
+ salience: number;
19
+ x: number;
20
+ y: number;
21
+ }
22
+
23
+ interface Edge {
24
+ source: number;
25
+ target: number;
26
+ relationship: string;
27
+ strength: number;
28
+ }
29
+
30
+ const RELATIONSHIP_COLORS: Record<string, string> = {
31
+ related: '#6366f1',
32
+ extends: '#22c55e',
33
+ references: '#3b82f6',
34
+ contradicts: '#ef4444',
35
+ };
36
+
37
+ const CATEGORY_COLORS: Record<string, string> = {
38
+ architecture: '#8b5cf6',
39
+ pattern: '#3b82f6',
40
+ error: '#ef4444',
41
+ learning: '#22c55e',
42
+ preference: '#f59e0b',
43
+ context: '#6366f1',
44
+ todo: '#ec4899',
45
+ note: '#64748b',
46
+ relationship: '#14b8a6',
47
+ custom: '#64748b',
48
+ };
49
+
50
+ export function RelationshipGraph() {
51
+ const canvasRef = useRef<HTMLCanvasElement>(null);
52
+ const [selectedNodeId, setSelectedNodeId] = useState<number | null>(null);
53
+ const [hoveredNodeId, setHoveredNodeId] = useState<number | null>(null);
54
+ const [relationshipFilter, setRelationshipFilter] = useState<string | null>(null);
55
+
56
+ const { data: links = [] } = useMemoryLinks();
57
+ const { data: memories = [] } = useMemories({ limit: 200 });
58
+
59
+ // Build graph data with stable positions
60
+ const { nodes, edges, nodeMap } = useMemo(() => {
61
+ const linkedIds = new Set<number>();
62
+ for (const link of links) {
63
+ linkedIds.add(link.source_id);
64
+ linkedIds.add(link.target_id);
65
+ }
66
+
67
+ const linkedMemories = memories.filter((m) => linkedIds.has(m.id));
68
+
69
+ // Create stable grid layout
70
+ const cols = Math.ceil(Math.sqrt(linkedMemories.length));
71
+ const cellWidth = 100;
72
+ const cellHeight = 80;
73
+
74
+ const nodes: Node[] = linkedMemories.map((m, i) => ({
75
+ id: m.id,
76
+ title: m.title,
77
+ category: m.category,
78
+ salience: m.salience,
79
+ x: (i % cols) * cellWidth + cellWidth / 2 + 50,
80
+ y: Math.floor(i / cols) * cellHeight + cellHeight / 2 + 50,
81
+ }));
82
+
83
+ const edges: Edge[] = links.map((l) => ({
84
+ source: l.source_id,
85
+ target: l.target_id,
86
+ relationship: l.relationship,
87
+ strength: l.strength,
88
+ }));
89
+
90
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
91
+
92
+ return { nodes, edges, nodeMap };
93
+ }, [memories, links]);
94
+
95
+ // Filter edges
96
+ const filteredEdges = relationshipFilter
97
+ ? edges.filter((e) => e.relationship === relationshipFilter)
98
+ : edges;
99
+
100
+ // Get connections for selected node
101
+ const selectedConnections = useMemo(() => {
102
+ if (!selectedNodeId) return { connectedIds: new Set<number>(), connectedEdges: [] };
103
+
104
+ const connectedIds = new Set<number>();
105
+ const connectedEdges: Edge[] = [];
106
+
107
+ for (const edge of filteredEdges) {
108
+ if (edge.source === selectedNodeId) {
109
+ connectedIds.add(edge.target);
110
+ connectedEdges.push(edge);
111
+ } else if (edge.target === selectedNodeId) {
112
+ connectedIds.add(edge.source);
113
+ connectedEdges.push(edge);
114
+ }
115
+ }
116
+
117
+ return { connectedIds, connectedEdges };
118
+ }, [selectedNodeId, filteredEdges]);
119
+
120
+ // Get unique relationship types
121
+ const relationshipTypes = [...new Set(edges.map((e) => e.relationship))];
122
+
123
+ // Get selected node details
124
+ const selectedNode = selectedNodeId ? nodeMap.get(selectedNodeId) : null;
125
+
126
+ // Canvas rendering
127
+ useEffect(() => {
128
+ const canvas = canvasRef.current;
129
+ if (!canvas) return;
130
+
131
+ const ctx = canvas.getContext('2d');
132
+ if (!ctx) return;
133
+
134
+ const rect = canvas.getBoundingClientRect();
135
+ canvas.width = rect.width * window.devicePixelRatio;
136
+ canvas.height = rect.height * window.devicePixelRatio;
137
+ ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
138
+
139
+ const width = rect.width;
140
+ const height = rect.height;
141
+
142
+ // Clear
143
+ ctx.fillStyle = '#0f172a';
144
+ ctx.fillRect(0, 0, width, height);
145
+
146
+ if (nodes.length === 0) return;
147
+
148
+ // Calculate layout to fit in canvas
149
+ const padding = 60;
150
+ const cols = Math.ceil(Math.sqrt(nodes.length));
151
+ const rows = Math.ceil(nodes.length / cols);
152
+ const cellWidth = (width - padding * 2) / cols;
153
+ const cellHeight = (height - padding * 2) / rows;
154
+
155
+ // Update positions to fit canvas
156
+ nodes.forEach((node, i) => {
157
+ node.x = (i % cols) * cellWidth + cellWidth / 2 + padding;
158
+ node.y = Math.floor(i / cols) * cellHeight + cellHeight / 2 + padding;
159
+ });
160
+
161
+ const { connectedIds, connectedEdges } = selectedConnections;
162
+
163
+ // Draw edges (only for selected node, or all dimmed if none selected)
164
+ if (selectedNodeId) {
165
+ // Draw connected edges prominently
166
+ ctx.lineWidth = 2;
167
+ for (const edge of connectedEdges) {
168
+ const source = nodeMap.get(edge.source);
169
+ const target = nodeMap.get(edge.target);
170
+ if (!source || !target) continue;
171
+
172
+ ctx.strokeStyle = RELATIONSHIP_COLORS[edge.relationship] || '#475569';
173
+ ctx.globalAlpha = 0.8;
174
+ ctx.beginPath();
175
+ ctx.moveTo(source.x, source.y);
176
+ ctx.lineTo(target.x, target.y);
177
+ ctx.stroke();
178
+
179
+ // Draw relationship label at midpoint
180
+ const midX = (source.x + target.x) / 2;
181
+ const midY = (source.y + target.y) / 2;
182
+ ctx.font = '10px system-ui';
183
+ ctx.fillStyle = RELATIONSHIP_COLORS[edge.relationship] || '#94a3b8';
184
+ ctx.globalAlpha = 1;
185
+ ctx.textAlign = 'center';
186
+ ctx.fillText(edge.relationship, midX, midY - 4);
187
+ }
188
+ } else {
189
+ // Show all edges very dimmed when nothing selected
190
+ ctx.lineWidth = 1;
191
+ ctx.globalAlpha = 0.15;
192
+ for (const edge of filteredEdges) {
193
+ const source = nodeMap.get(edge.source);
194
+ const target = nodeMap.get(edge.target);
195
+ if (!source || !target) continue;
196
+
197
+ ctx.strokeStyle = RELATIONSHIP_COLORS[edge.relationship] || '#475569';
198
+ ctx.beginPath();
199
+ ctx.moveTo(source.x, source.y);
200
+ ctx.lineTo(target.x, target.y);
201
+ ctx.stroke();
202
+ }
203
+ }
204
+ ctx.globalAlpha = 1;
205
+
206
+ // Draw nodes
207
+ for (const node of nodes) {
208
+ const isSelected = node.id === selectedNodeId;
209
+ const isConnected = connectedIds.has(node.id);
210
+ const isHovered = node.id === hoveredNodeId;
211
+ const isHighlighted = isSelected || isConnected || !selectedNodeId;
212
+
213
+ const baseRadius = 6 + node.salience * 6;
214
+ const radius = isSelected ? baseRadius + 4 : isHovered ? baseRadius + 2 : baseRadius;
215
+
216
+ // Determine opacity
217
+ const opacity = isHighlighted ? 1 : 0.2;
218
+
219
+ // Draw node
220
+ ctx.beginPath();
221
+ ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
222
+ ctx.fillStyle = CATEGORY_COLORS[node.category] || '#64748b';
223
+ ctx.globalAlpha = opacity;
224
+ ctx.fill();
225
+
226
+ // Selection/hover ring
227
+ if (isSelected || isHovered) {
228
+ ctx.strokeStyle = isSelected ? '#f472b6' : '#94a3b8';
229
+ ctx.lineWidth = isSelected ? 3 : 2;
230
+ ctx.globalAlpha = 1;
231
+ ctx.stroke();
232
+ }
233
+
234
+ // Draw label for highlighted nodes
235
+ if (isHighlighted && (isSelected || isConnected || isHovered || node.salience > 0.5)) {
236
+ ctx.globalAlpha = opacity;
237
+ const label = node.title.length > 20 ? node.title.slice(0, 20) + '...' : node.title;
238
+ ctx.font = isSelected ? 'bold 11px system-ui' : '10px system-ui';
239
+ ctx.textAlign = 'center';
240
+
241
+ // Background
242
+ const textWidth = ctx.measureText(label).width;
243
+ ctx.fillStyle = 'rgba(15, 23, 42, 0.9)';
244
+ ctx.fillRect(node.x - textWidth / 2 - 4, node.y + radius + 4, textWidth + 8, 16);
245
+
246
+ // Text
247
+ ctx.fillStyle = isSelected ? '#f472b6' : isConnected ? '#e2e8f0' : '#94a3b8';
248
+ ctx.fillText(label, node.x, node.y + radius + 16);
249
+ }
250
+ }
251
+
252
+ ctx.globalAlpha = 1;
253
+ }, [nodes, nodeMap, filteredEdges, selectedNodeId, hoveredNodeId, selectedConnections]);
254
+
255
+ // Mouse handling
256
+ useEffect(() => {
257
+ const canvas = canvasRef.current;
258
+ if (!canvas) return;
259
+
260
+ const getNodeAt = (x: number, y: number): Node | null => {
261
+ for (const node of nodes) {
262
+ const radius = 6 + node.salience * 6 + 4;
263
+ const dx = node.x - x;
264
+ const dy = node.y - y;
265
+ if (dx * dx + dy * dy < radius * radius) {
266
+ return node;
267
+ }
268
+ }
269
+ return null;
270
+ };
271
+
272
+ const handleClick = (e: MouseEvent) => {
273
+ const rect = canvas.getBoundingClientRect();
274
+ const x = e.clientX - rect.left;
275
+ const y = e.clientY - rect.top;
276
+ const node = getNodeAt(x, y);
277
+
278
+ if (node) {
279
+ setSelectedNodeId(node.id === selectedNodeId ? null : node.id);
280
+ } else {
281
+ setSelectedNodeId(null);
282
+ }
283
+ };
284
+
285
+ const handleMouseMove = (e: MouseEvent) => {
286
+ const rect = canvas.getBoundingClientRect();
287
+ const x = e.clientX - rect.left;
288
+ const y = e.clientY - rect.top;
289
+ const node = getNodeAt(x, y);
290
+ setHoveredNodeId(node?.id || null);
291
+ canvas.style.cursor = node ? 'pointer' : 'default';
292
+ };
293
+
294
+ canvas.addEventListener('click', handleClick);
295
+ canvas.addEventListener('mousemove', handleMouseMove);
296
+
297
+ return () => {
298
+ canvas.removeEventListener('click', handleClick);
299
+ canvas.removeEventListener('mousemove', handleMouseMove);
300
+ };
301
+ }, [nodes, selectedNodeId]);
302
+
303
+ return (
304
+ <div className="h-full flex flex-col">
305
+ {/* Controls */}
306
+ <div className="p-2 border-b border-slate-700 flex items-center gap-3">
307
+ <span className="text-xs text-slate-400">Filter:</span>
308
+ <button
309
+ onClick={() => setRelationshipFilter(null)}
310
+ className={`px-2 py-0.5 text-xs rounded ${
311
+ relationshipFilter === null
312
+ ? 'bg-slate-600 text-white'
313
+ : 'text-slate-400 hover:text-white'
314
+ }`}
315
+ >
316
+ All
317
+ </button>
318
+ {relationshipTypes.map((type) => (
319
+ <button
320
+ key={type}
321
+ onClick={() => setRelationshipFilter(type)}
322
+ className={`px-2 py-0.5 text-xs rounded ${
323
+ relationshipFilter === type ? 'text-white' : 'text-slate-400 hover:text-white'
324
+ }`}
325
+ style={{
326
+ backgroundColor: relationshipFilter === type ? RELATIONSHIP_COLORS[type] : 'transparent',
327
+ }}
328
+ >
329
+ {type}
330
+ </button>
331
+ ))}
332
+
333
+ <div className="flex-1" />
334
+
335
+ {/* Instructions */}
336
+ <span className="text-xs text-slate-500">
337
+ {selectedNodeId ? 'Click elsewhere to deselect' : 'Click a node to focus'}
338
+ </span>
339
+
340
+ {/* Legend */}
341
+ <div className="flex items-center gap-2 text-xs border-l border-slate-700 pl-3">
342
+ {Object.entries(RELATIONSHIP_COLORS).map(([type, color]) => (
343
+ <div key={type} className="flex items-center gap-1">
344
+ <div className="w-3 h-0.5" style={{ backgroundColor: color }} />
345
+ <span className="text-slate-500">{type}</span>
346
+ </div>
347
+ ))}
348
+ </div>
349
+ </div>
350
+
351
+ {/* Graph */}
352
+ <div className="flex-1 relative min-h-0">
353
+ <canvas ref={canvasRef} className="absolute inset-0 w-full h-full" />
354
+
355
+ {/* Selected Node Details */}
356
+ {selectedNode && (
357
+ <div className="absolute top-3 left-3 p-3 bg-slate-800/95 border border-slate-700 rounded-lg max-w-xs">
358
+ <div className="flex items-center gap-2 mb-2">
359
+ <div
360
+ className="w-3 h-3 rounded-full"
361
+ style={{ backgroundColor: CATEGORY_COLORS[selectedNode.category] }}
362
+ />
363
+ <span className="text-white font-medium text-sm">{selectedNode.title}</span>
364
+ </div>
365
+ <div className="text-xs text-slate-400 space-y-1">
366
+ <div>Category: {selectedNode.category}</div>
367
+ <div>Salience: {(selectedNode.salience * 100).toFixed(0)}%</div>
368
+ <div>Connections: {selectedConnections.connectedIds.size}</div>
369
+ </div>
370
+ {selectedConnections.connectedEdges.length > 0 && (
371
+ <div className="mt-2 pt-2 border-t border-slate-700">
372
+ <div className="text-xs text-slate-500 mb-1">Connected to:</div>
373
+ <div className="space-y-1 max-h-24 overflow-y-auto">
374
+ {selectedConnections.connectedEdges.map((edge, i) => {
375
+ const otherId = edge.source === selectedNodeId ? edge.target : edge.source;
376
+ const other = nodeMap.get(otherId);
377
+ return (
378
+ <div key={i} className="text-xs flex items-center gap-1">
379
+ <span
380
+ className="w-2 h-2 rounded-full shrink-0"
381
+ style={{ backgroundColor: RELATIONSHIP_COLORS[edge.relationship] }}
382
+ />
383
+ <span className="text-slate-400">{edge.relationship}:</span>
384
+ <span className="text-slate-300 truncate">{other?.title || 'Unknown'}</span>
385
+ </div>
386
+ );
387
+ })}
388
+ </div>
389
+ </div>
390
+ )}
391
+ </div>
392
+ )}
393
+
394
+ {/* Empty state */}
395
+ {nodes.length === 0 && (
396
+ <div className="absolute inset-0 flex items-center justify-center text-slate-500">
397
+ No relationships to display
398
+ </div>
399
+ )}
400
+ </div>
401
+ </div>
402
+ );
403
+ }