superlocalmemory 2.8.5 → 3.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 (434) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +9 -1
  3. package/NOTICE +63 -0
  4. package/README.md +165 -480
  5. package/bin/slm +17 -449
  6. package/bin/slm-npm +2 -2
  7. package/bin/slm.bat +4 -2
  8. package/conftest.py +5 -0
  9. package/docs/api-reference.md +284 -0
  10. package/docs/architecture.md +149 -0
  11. package/docs/auto-memory.md +150 -0
  12. package/docs/cli-reference.md +276 -0
  13. package/docs/compliance.md +191 -0
  14. package/docs/configuration.md +182 -0
  15. package/docs/getting-started.md +102 -0
  16. package/docs/ide-setup.md +261 -0
  17. package/docs/mcp-tools.md +220 -0
  18. package/docs/migration-from-v2.md +170 -0
  19. package/docs/profiles.md +173 -0
  20. package/docs/troubleshooting.md +310 -0
  21. package/{configs → ide/configs}/antigravity-mcp.json +3 -3
  22. package/ide/configs/chatgpt-desktop-mcp.json +16 -0
  23. package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
  24. package/{configs → ide/configs}/codex-mcp.toml +4 -4
  25. package/{configs → ide/configs}/continue-mcp.yaml +4 -3
  26. package/{configs → ide/configs}/continue-skills.yaml +6 -6
  27. package/ide/configs/cursor-mcp.json +15 -0
  28. package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
  29. package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
  30. package/{configs → ide/configs}/opencode-mcp.json +2 -2
  31. package/{configs → ide/configs}/perplexity-mcp.json +2 -2
  32. package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
  33. package/{configs → ide/configs}/windsurf-mcp.json +3 -3
  34. package/{configs → ide/configs}/zed-mcp.json +2 -2
  35. package/{hooks → ide/hooks}/context-hook.js +9 -20
  36. package/ide/hooks/memory-list-skill.js +70 -0
  37. package/ide/hooks/memory-profile-skill.js +101 -0
  38. package/ide/hooks/memory-recall-skill.js +62 -0
  39. package/ide/hooks/memory-remember-skill.js +68 -0
  40. package/ide/hooks/memory-reset-skill.js +160 -0
  41. package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
  42. package/ide/integrations/langchain/README.md +106 -0
  43. package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
  44. package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
  45. package/ide/integrations/langchain/pyproject.toml +38 -0
  46. package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
  47. package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
  48. package/ide/integrations/langchain/tests/test_security.py +117 -0
  49. package/ide/integrations/llamaindex/README.md +81 -0
  50. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
  51. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
  52. package/ide/integrations/llamaindex/pyproject.toml +43 -0
  53. package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
  54. package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
  55. package/ide/integrations/llamaindex/tests/test_security.py +241 -0
  56. package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
  57. package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
  58. package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
  59. package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
  60. package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
  61. package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
  62. package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
  63. package/package.json +13 -22
  64. package/pyproject.toml +85 -0
  65. package/scripts/build-dmg.sh +417 -0
  66. package/scripts/install-skills.ps1 +334 -0
  67. package/{install.ps1 → scripts/install.ps1} +36 -4
  68. package/{install.sh → scripts/install.sh} +14 -13
  69. package/scripts/postinstall.js +2 -2
  70. package/scripts/start-dashboard.ps1 +52 -0
  71. package/scripts/start-dashboard.sh +41 -0
  72. package/scripts/sync-wiki.ps1 +127 -0
  73. package/scripts/sync-wiki.sh +82 -0
  74. package/scripts/test-dmg.sh +161 -0
  75. package/scripts/test-npm-package.ps1 +252 -0
  76. package/scripts/test-npm-package.sh +207 -0
  77. package/scripts/verify-install.ps1 +294 -0
  78. package/scripts/verify-install.sh +266 -0
  79. package/src/superlocalmemory/__init__.py +0 -0
  80. package/src/superlocalmemory/attribution/__init__.py +9 -0
  81. package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
  82. package/src/superlocalmemory/attribution/signer.py +153 -0
  83. package/src/superlocalmemory/attribution/watermark.py +189 -0
  84. package/src/superlocalmemory/cli/__init__.py +5 -0
  85. package/src/superlocalmemory/cli/commands.py +245 -0
  86. package/src/superlocalmemory/cli/main.py +89 -0
  87. package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
  88. package/src/superlocalmemory/cli/post_install.py +99 -0
  89. package/src/superlocalmemory/cli/setup_wizard.py +129 -0
  90. package/src/superlocalmemory/compliance/__init__.py +0 -0
  91. package/src/superlocalmemory/compliance/abac.py +204 -0
  92. package/src/superlocalmemory/compliance/audit.py +314 -0
  93. package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
  94. package/src/superlocalmemory/compliance/gdpr.py +294 -0
  95. package/src/superlocalmemory/compliance/lifecycle.py +158 -0
  96. package/src/superlocalmemory/compliance/retention.py +232 -0
  97. package/src/superlocalmemory/compliance/scheduler.py +148 -0
  98. package/src/superlocalmemory/core/__init__.py +0 -0
  99. package/src/superlocalmemory/core/config.py +391 -0
  100. package/src/superlocalmemory/core/embeddings.py +293 -0
  101. package/src/superlocalmemory/core/engine.py +701 -0
  102. package/src/superlocalmemory/core/hooks.py +65 -0
  103. package/src/superlocalmemory/core/maintenance.py +172 -0
  104. package/src/superlocalmemory/core/modes.py +140 -0
  105. package/src/superlocalmemory/core/profiles.py +234 -0
  106. package/src/superlocalmemory/core/registry.py +117 -0
  107. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  108. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
  109. package/src/superlocalmemory/encoding/__init__.py +0 -0
  110. package/src/superlocalmemory/encoding/consolidator.py +485 -0
  111. package/src/superlocalmemory/encoding/emotional.py +125 -0
  112. package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
  113. package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
  114. package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
  115. package/src/superlocalmemory/encoding/foresight.py +91 -0
  116. package/src/superlocalmemory/encoding/graph_builder.py +302 -0
  117. package/src/superlocalmemory/encoding/observation_builder.py +160 -0
  118. package/src/superlocalmemory/encoding/scene_builder.py +183 -0
  119. package/src/superlocalmemory/encoding/signal_inference.py +90 -0
  120. package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
  121. package/src/superlocalmemory/encoding/type_router.py +235 -0
  122. package/src/superlocalmemory/hooks/__init__.py +3 -0
  123. package/src/superlocalmemory/hooks/auto_capture.py +111 -0
  124. package/src/superlocalmemory/hooks/auto_recall.py +93 -0
  125. package/src/superlocalmemory/hooks/ide_connector.py +204 -0
  126. package/src/superlocalmemory/hooks/rules_engine.py +99 -0
  127. package/src/superlocalmemory/infra/__init__.py +3 -0
  128. package/src/superlocalmemory/infra/auth_middleware.py +82 -0
  129. package/src/superlocalmemory/infra/backup.py +317 -0
  130. package/src/superlocalmemory/infra/cache_manager.py +267 -0
  131. package/src/superlocalmemory/infra/event_bus.py +381 -0
  132. package/src/superlocalmemory/infra/rate_limiter.py +135 -0
  133. package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
  134. package/src/superlocalmemory/learning/__init__.py +0 -0
  135. package/src/superlocalmemory/learning/adaptive.py +172 -0
  136. package/src/superlocalmemory/learning/behavioral.py +490 -0
  137. package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
  138. package/src/superlocalmemory/learning/bootstrap.py +298 -0
  139. package/src/superlocalmemory/learning/cross_project.py +399 -0
  140. package/src/superlocalmemory/learning/database.py +376 -0
  141. package/src/superlocalmemory/learning/engagement.py +323 -0
  142. package/src/superlocalmemory/learning/features.py +138 -0
  143. package/src/superlocalmemory/learning/feedback.py +316 -0
  144. package/src/superlocalmemory/learning/outcomes.py +255 -0
  145. package/src/superlocalmemory/learning/project_context.py +366 -0
  146. package/src/superlocalmemory/learning/ranker.py +155 -0
  147. package/src/superlocalmemory/learning/source_quality.py +303 -0
  148. package/src/superlocalmemory/learning/workflows.py +309 -0
  149. package/src/superlocalmemory/llm/__init__.py +0 -0
  150. package/src/superlocalmemory/llm/backbone.py +316 -0
  151. package/src/superlocalmemory/math/__init__.py +0 -0
  152. package/src/superlocalmemory/math/fisher.py +356 -0
  153. package/src/superlocalmemory/math/langevin.py +398 -0
  154. package/src/superlocalmemory/math/sheaf.py +257 -0
  155. package/src/superlocalmemory/mcp/__init__.py +0 -0
  156. package/src/superlocalmemory/mcp/resources.py +245 -0
  157. package/src/superlocalmemory/mcp/server.py +61 -0
  158. package/src/superlocalmemory/mcp/tools.py +18 -0
  159. package/src/superlocalmemory/mcp/tools_core.py +305 -0
  160. package/src/superlocalmemory/mcp/tools_v28.py +223 -0
  161. package/src/superlocalmemory/mcp/tools_v3.py +286 -0
  162. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  163. package/src/superlocalmemory/retrieval/agentic.py +295 -0
  164. package/src/superlocalmemory/retrieval/ann_index.py +223 -0
  165. package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
  166. package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
  167. package/src/superlocalmemory/retrieval/engine.py +390 -0
  168. package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
  169. package/src/superlocalmemory/retrieval/fusion.py +78 -0
  170. package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
  171. package/src/superlocalmemory/retrieval/reranker.py +154 -0
  172. package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
  173. package/src/superlocalmemory/retrieval/strategy.py +96 -0
  174. package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
  175. package/src/superlocalmemory/server/__init__.py +1 -0
  176. package/src/superlocalmemory/server/api.py +248 -0
  177. package/src/superlocalmemory/server/routes/__init__.py +4 -0
  178. package/src/superlocalmemory/server/routes/agents.py +107 -0
  179. package/src/superlocalmemory/server/routes/backup.py +91 -0
  180. package/src/superlocalmemory/server/routes/behavioral.py +127 -0
  181. package/src/superlocalmemory/server/routes/compliance.py +160 -0
  182. package/src/superlocalmemory/server/routes/data_io.py +188 -0
  183. package/src/superlocalmemory/server/routes/events.py +183 -0
  184. package/src/superlocalmemory/server/routes/helpers.py +85 -0
  185. package/src/superlocalmemory/server/routes/learning.py +273 -0
  186. package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
  187. package/src/superlocalmemory/server/routes/memories.py +399 -0
  188. package/src/superlocalmemory/server/routes/profiles.py +219 -0
  189. package/src/superlocalmemory/server/routes/stats.py +346 -0
  190. package/src/superlocalmemory/server/routes/v3_api.py +365 -0
  191. package/src/superlocalmemory/server/routes/ws.py +82 -0
  192. package/src/superlocalmemory/server/security_middleware.py +57 -0
  193. package/src/superlocalmemory/server/ui.py +245 -0
  194. package/src/superlocalmemory/storage/__init__.py +0 -0
  195. package/src/superlocalmemory/storage/access_control.py +182 -0
  196. package/src/superlocalmemory/storage/database.py +594 -0
  197. package/src/superlocalmemory/storage/migrations.py +303 -0
  198. package/src/superlocalmemory/storage/models.py +406 -0
  199. package/src/superlocalmemory/storage/schema.py +726 -0
  200. package/src/superlocalmemory/storage/v2_migrator.py +317 -0
  201. package/src/superlocalmemory/trust/__init__.py +0 -0
  202. package/src/superlocalmemory/trust/gate.py +130 -0
  203. package/src/superlocalmemory/trust/provenance.py +124 -0
  204. package/src/superlocalmemory/trust/scorer.py +347 -0
  205. package/src/superlocalmemory/trust/signals.py +153 -0
  206. package/ui/index.html +278 -5
  207. package/ui/js/auto-settings.js +70 -0
  208. package/ui/js/dashboard.js +90 -0
  209. package/ui/js/fact-detail.js +92 -0
  210. package/ui/js/feedback.js +2 -2
  211. package/ui/js/ide-status.js +102 -0
  212. package/ui/js/math-health.js +98 -0
  213. package/ui/js/recall-lab.js +127 -0
  214. package/ui/js/settings.js +2 -2
  215. package/ui/js/trust-dashboard.js +73 -0
  216. package/api_server.py +0 -724
  217. package/bin/aider-smart +0 -72
  218. package/bin/superlocalmemoryv2-learning +0 -4
  219. package/bin/superlocalmemoryv2-list +0 -3
  220. package/bin/superlocalmemoryv2-patterns +0 -4
  221. package/bin/superlocalmemoryv2-profile +0 -3
  222. package/bin/superlocalmemoryv2-recall +0 -3
  223. package/bin/superlocalmemoryv2-remember +0 -3
  224. package/bin/superlocalmemoryv2-reset +0 -3
  225. package/bin/superlocalmemoryv2-status +0 -3
  226. package/configs/chatgpt-desktop-mcp.json +0 -16
  227. package/configs/cursor-mcp.json +0 -15
  228. package/docs/SECURITY-QUICK-REFERENCE.md +0 -214
  229. package/hooks/memory-list-skill.js +0 -139
  230. package/hooks/memory-profile-skill.js +0 -273
  231. package/hooks/memory-recall-skill.js +0 -114
  232. package/hooks/memory-remember-skill.js +0 -127
  233. package/hooks/memory-reset-skill.js +0 -274
  234. package/mcp_server.py +0 -1800
  235. package/requirements-core.txt +0 -22
  236. package/requirements-learning.txt +0 -12
  237. package/requirements.txt +0 -12
  238. package/src/agent_registry.py +0 -411
  239. package/src/auth_middleware.py +0 -61
  240. package/src/auto_backup.py +0 -459
  241. package/src/behavioral/__init__.py +0 -49
  242. package/src/behavioral/behavioral_listener.py +0 -203
  243. package/src/behavioral/behavioral_patterns.py +0 -275
  244. package/src/behavioral/cross_project_transfer.py +0 -206
  245. package/src/behavioral/outcome_inference.py +0 -194
  246. package/src/behavioral/outcome_tracker.py +0 -193
  247. package/src/behavioral/tests/__init__.py +0 -4
  248. package/src/behavioral/tests/test_behavioral_integration.py +0 -108
  249. package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
  250. package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
  251. package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
  252. package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
  253. package/src/behavioral/tests/test_outcome_inference.py +0 -107
  254. package/src/behavioral/tests/test_outcome_tracker.py +0 -96
  255. package/src/cache_manager.py +0 -518
  256. package/src/compliance/__init__.py +0 -48
  257. package/src/compliance/abac_engine.py +0 -149
  258. package/src/compliance/abac_middleware.py +0 -116
  259. package/src/compliance/audit_db.py +0 -215
  260. package/src/compliance/audit_logger.py +0 -148
  261. package/src/compliance/retention_manager.py +0 -289
  262. package/src/compliance/retention_scheduler.py +0 -186
  263. package/src/compliance/tests/__init__.py +0 -4
  264. package/src/compliance/tests/test_abac_enforcement.py +0 -95
  265. package/src/compliance/tests/test_abac_engine.py +0 -124
  266. package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
  267. package/src/compliance/tests/test_audit_db.py +0 -123
  268. package/src/compliance/tests/test_audit_logger.py +0 -98
  269. package/src/compliance/tests/test_mcp_audit.py +0 -128
  270. package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
  271. package/src/compliance/tests/test_retention_manager.py +0 -131
  272. package/src/compliance/tests/test_retention_scheduler.py +0 -99
  273. package/src/compression/__init__.py +0 -25
  274. package/src/compression/cli.py +0 -150
  275. package/src/compression/cold_storage.py +0 -217
  276. package/src/compression/config.py +0 -72
  277. package/src/compression/orchestrator.py +0 -133
  278. package/src/compression/tier2_compressor.py +0 -228
  279. package/src/compression/tier3_compressor.py +0 -153
  280. package/src/compression/tier_classifier.py +0 -148
  281. package/src/db_connection_manager.py +0 -536
  282. package/src/embedding_engine.py +0 -63
  283. package/src/embeddings/__init__.py +0 -47
  284. package/src/embeddings/cache.py +0 -70
  285. package/src/embeddings/cli.py +0 -113
  286. package/src/embeddings/constants.py +0 -47
  287. package/src/embeddings/database.py +0 -91
  288. package/src/embeddings/engine.py +0 -247
  289. package/src/embeddings/model_loader.py +0 -145
  290. package/src/event_bus.py +0 -562
  291. package/src/graph/__init__.py +0 -36
  292. package/src/graph/build_helpers.py +0 -74
  293. package/src/graph/cli.py +0 -87
  294. package/src/graph/cluster_builder.py +0 -188
  295. package/src/graph/cluster_summary.py +0 -148
  296. package/src/graph/constants.py +0 -47
  297. package/src/graph/edge_builder.py +0 -162
  298. package/src/graph/entity_extractor.py +0 -95
  299. package/src/graph/graph_core.py +0 -226
  300. package/src/graph/graph_search.py +0 -231
  301. package/src/graph/hierarchical.py +0 -207
  302. package/src/graph/schema.py +0 -99
  303. package/src/graph_engine.py +0 -52
  304. package/src/hnsw_index.py +0 -628
  305. package/src/hybrid_search.py +0 -46
  306. package/src/learning/__init__.py +0 -217
  307. package/src/learning/adaptive_ranker.py +0 -682
  308. package/src/learning/bootstrap/__init__.py +0 -69
  309. package/src/learning/bootstrap/constants.py +0 -93
  310. package/src/learning/bootstrap/db_queries.py +0 -316
  311. package/src/learning/bootstrap/sampling.py +0 -82
  312. package/src/learning/bootstrap/text_utils.py +0 -71
  313. package/src/learning/cross_project_aggregator.py +0 -857
  314. package/src/learning/db/__init__.py +0 -40
  315. package/src/learning/db/constants.py +0 -44
  316. package/src/learning/db/schema.py +0 -279
  317. package/src/learning/engagement_tracker.py +0 -628
  318. package/src/learning/feature_extractor.py +0 -708
  319. package/src/learning/feedback_collector.py +0 -806
  320. package/src/learning/learning_db.py +0 -915
  321. package/src/learning/project_context_manager.py +0 -572
  322. package/src/learning/ranking/__init__.py +0 -33
  323. package/src/learning/ranking/constants.py +0 -84
  324. package/src/learning/ranking/helpers.py +0 -278
  325. package/src/learning/source_quality_scorer.py +0 -676
  326. package/src/learning/synthetic_bootstrap.py +0 -755
  327. package/src/learning/tests/test_adaptive_ranker.py +0 -325
  328. package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
  329. package/src/learning/tests/test_aggregator.py +0 -306
  330. package/src/learning/tests/test_auto_retrain_v28.py +0 -35
  331. package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
  332. package/src/learning/tests/test_feature_extractor_v28.py +0 -93
  333. package/src/learning/tests/test_feedback_collector.py +0 -294
  334. package/src/learning/tests/test_learning_db.py +0 -602
  335. package/src/learning/tests/test_learning_db_v28.py +0 -110
  336. package/src/learning/tests/test_learning_init_v28.py +0 -48
  337. package/src/learning/tests/test_outcome_signals.py +0 -48
  338. package/src/learning/tests/test_project_context.py +0 -292
  339. package/src/learning/tests/test_schema_migration.py +0 -319
  340. package/src/learning/tests/test_signal_inference.py +0 -397
  341. package/src/learning/tests/test_source_quality.py +0 -351
  342. package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
  343. package/src/learning/tests/test_workflow_miner.py +0 -318
  344. package/src/learning/workflow_pattern_miner.py +0 -655
  345. package/src/lifecycle/__init__.py +0 -54
  346. package/src/lifecycle/bounded_growth.py +0 -239
  347. package/src/lifecycle/compaction_engine.py +0 -226
  348. package/src/lifecycle/lifecycle_engine.py +0 -355
  349. package/src/lifecycle/lifecycle_evaluator.py +0 -257
  350. package/src/lifecycle/lifecycle_scheduler.py +0 -130
  351. package/src/lifecycle/retention_policy.py +0 -285
  352. package/src/lifecycle/tests/test_bounded_growth.py +0 -193
  353. package/src/lifecycle/tests/test_compaction.py +0 -179
  354. package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
  355. package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
  356. package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
  357. package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
  358. package/src/lifecycle/tests/test_mcp_compact.py +0 -149
  359. package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
  360. package/src/lifecycle/tests/test_retention_policy.py +0 -162
  361. package/src/mcp_tools_v28.py +0 -281
  362. package/src/memory/__init__.py +0 -36
  363. package/src/memory/cli.py +0 -205
  364. package/src/memory/constants.py +0 -39
  365. package/src/memory/helpers.py +0 -28
  366. package/src/memory/schema.py +0 -166
  367. package/src/memory-profiles.py +0 -595
  368. package/src/memory-reset.py +0 -491
  369. package/src/memory_compression.py +0 -989
  370. package/src/memory_store_v2.py +0 -1155
  371. package/src/migrate_v1_to_v2.py +0 -629
  372. package/src/pattern_learner.py +0 -34
  373. package/src/patterns/__init__.py +0 -24
  374. package/src/patterns/analyzers.py +0 -251
  375. package/src/patterns/learner.py +0 -271
  376. package/src/patterns/scoring.py +0 -171
  377. package/src/patterns/store.py +0 -225
  378. package/src/patterns/terminology.py +0 -140
  379. package/src/provenance_tracker.py +0 -312
  380. package/src/qualixar_attribution.py +0 -139
  381. package/src/qualixar_watermark.py +0 -78
  382. package/src/query_optimizer.py +0 -511
  383. package/src/rate_limiter.py +0 -83
  384. package/src/search/__init__.py +0 -20
  385. package/src/search/cli.py +0 -77
  386. package/src/search/constants.py +0 -26
  387. package/src/search/engine.py +0 -241
  388. package/src/search/fusion.py +0 -122
  389. package/src/search/index_loader.py +0 -114
  390. package/src/search/methods.py +0 -162
  391. package/src/search_engine_v2.py +0 -401
  392. package/src/setup_validator.py +0 -482
  393. package/src/subscription_manager.py +0 -391
  394. package/src/tree/__init__.py +0 -59
  395. package/src/tree/builder.py +0 -185
  396. package/src/tree/nodes.py +0 -202
  397. package/src/tree/queries.py +0 -257
  398. package/src/tree/schema.py +0 -80
  399. package/src/tree_manager.py +0 -19
  400. package/src/trust/__init__.py +0 -45
  401. package/src/trust/constants.py +0 -66
  402. package/src/trust/queries.py +0 -157
  403. package/src/trust/schema.py +0 -95
  404. package/src/trust/scorer.py +0 -299
  405. package/src/trust/signals.py +0 -95
  406. package/src/trust_scorer.py +0 -44
  407. package/ui/app.js +0 -1588
  408. package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
  409. package/ui/js/graph-cytoscape.js +0 -1168
  410. package/ui/js/graph-d3-backup.js +0 -32
  411. package/ui/js/graph.js +0 -32
  412. package/ui_server.py +0 -266
  413. /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
  414. /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
  415. /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
  416. /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
  417. /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
  418. /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
  419. /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
  420. /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
  421. /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
  422. /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
  423. /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
  424. /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
  425. /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
  426. /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
  427. /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
  428. /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
  429. /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
  430. /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
  431. /package/{completions → ide/completions}/slm.bash +0 -0
  432. /package/{completions → ide/completions}/slm.zsh +0 -0
  433. /package/{configs → ide/configs}/cody-commands.json +0 -0
  434. /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
@@ -1,36 +0,0 @@
1
- # SPDX-License-Identifier: MIT
2
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
3
- """graph package - Knowledge Graph Clustering for SuperLocalMemory V2
4
-
5
- Re-exports all public classes, constants, and functions so that
6
- ``from graph import GraphEngine`` (or any other symbol) works.
7
- """
8
- from graph.constants import (
9
- MAX_MEMORIES_FOR_GRAPH,
10
- SKLEARN_AVAILABLE,
11
- IGRAPH_AVAILABLE,
12
- MEMORY_DIR,
13
- DB_PATH,
14
- )
15
- from graph.entity_extractor import EntityExtractor, ClusterNamer
16
- from graph.edge_builder import EdgeBuilder
17
- from graph.cluster_builder import ClusterBuilder
18
- from graph.graph_core import GraphEngine
19
- from graph.cli import main
20
-
21
- __all__ = [
22
- # Constants
23
- "MAX_MEMORIES_FOR_GRAPH",
24
- "SKLEARN_AVAILABLE",
25
- "IGRAPH_AVAILABLE",
26
- "MEMORY_DIR",
27
- "DB_PATH",
28
- # Classes
29
- "EntityExtractor",
30
- "ClusterNamer",
31
- "EdgeBuilder",
32
- "ClusterBuilder",
33
- "GraphEngine",
34
- # Functions
35
- "main",
36
- ]
@@ -1,74 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- """Helper functions for the graph build process.
5
-
6
- Provides sampling and cleanup utilities used during full graph builds.
7
- """
8
- from graph.constants import logger, MAX_MEMORIES_FOR_GRAPH
9
-
10
-
11
- def apply_sampling(cursor, memories, active_profile):
12
- """Apply intelligent sampling if memory count exceeds cap.
13
-
14
- Returns a (possibly truncated) list of memory tuples.
15
- """
16
- if len(memories) > MAX_MEMORIES_FOR_GRAPH:
17
- logger.warning(
18
- "Memory count (%d) exceeds graph cap (%d). Using intelligent sampling.",
19
- len(memories), MAX_MEMORIES_FOR_GRAPH
20
- )
21
- recent_count = int(MAX_MEMORIES_FOR_GRAPH * 0.6)
22
- important_count = int(MAX_MEMORIES_FOR_GRAPH * 0.4)
23
-
24
- recent_memories = cursor.execute('''
25
- SELECT id, content, summary FROM memories
26
- WHERE profile = ? ORDER BY created_at DESC LIMIT ?
27
- ''', (active_profile, recent_count)).fetchall()
28
-
29
- important_memories = cursor.execute('''
30
- SELECT id, content, summary FROM memories
31
- WHERE profile = ? ORDER BY importance DESC, access_count DESC LIMIT ?
32
- ''', (active_profile, important_count)).fetchall()
33
-
34
- seen_ids = set()
35
- sampled = []
36
- for m in recent_memories + important_memories:
37
- if m[0] not in seen_ids:
38
- seen_ids.add(m[0])
39
- sampled.append(m)
40
- memories = sampled[:MAX_MEMORIES_FOR_GRAPH]
41
- logger.info("Sampled %d memories for graph build", len(memories))
42
-
43
- elif len(memories) > MAX_MEMORIES_FOR_GRAPH * 0.8:
44
- logger.warning(
45
- "Approaching graph cap: %d/%d memories (%.0f%%). "
46
- "Consider running memory compression.",
47
- len(memories), MAX_MEMORIES_FOR_GRAPH,
48
- len(memories) / MAX_MEMORIES_FOR_GRAPH * 100
49
- )
50
- return memories
51
-
52
-
53
- def clear_profile_graph_data(cursor, conn, memories, active_profile):
54
- """Clear existing graph data for a profile's memories."""
55
- profile_memory_ids = [m[0] for m in memories]
56
- if profile_memory_ids:
57
- placeholders = ','.join('?' * len(profile_memory_ids))
58
- cursor.execute(f'''
59
- DELETE FROM graph_edges
60
- WHERE source_memory_id IN ({placeholders})
61
- OR target_memory_id IN ({placeholders})
62
- ''', profile_memory_ids + profile_memory_ids)
63
- cursor.execute(f'''
64
- DELETE FROM graph_nodes WHERE memory_id IN ({placeholders})
65
- ''', profile_memory_ids)
66
- cursor.execute('''
67
- DELETE FROM graph_clusters
68
- WHERE id NOT IN (
69
- SELECT DISTINCT cluster_id FROM memories WHERE cluster_id IS NOT NULL
70
- )
71
- ''')
72
- cursor.execute('UPDATE memories SET cluster_id = NULL WHERE profile = ?',
73
- (active_profile,))
74
- conn.commit()
package/src/graph/cli.py DELETED
@@ -1,87 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- """CLI interface for manual graph operations.
5
-
6
- Provides a command-line interface for building graphs, viewing stats,
7
- finding related memories, inspecting clusters, and generating summaries.
8
- """
9
- import json
10
-
11
-
12
- def main():
13
- """CLI interface for manual graph operations."""
14
- import argparse
15
- from graph.graph_core import GraphEngine
16
- from graph.cluster_builder import ClusterBuilder
17
-
18
- parser = argparse.ArgumentParser(description='GraphEngine - Knowledge Graph Management')
19
- parser.add_argument('command', choices=['build', 'stats', 'related', 'cluster', 'hierarchical', 'summaries'],
20
- help='Command to execute')
21
- parser.add_argument('--memory-id', type=int, help='Memory ID for related/add commands')
22
- parser.add_argument('--cluster-id', type=int, help='Cluster ID for cluster command')
23
- parser.add_argument('--min-similarity', type=float, default=0.3,
24
- help='Minimum similarity for edges (default: 0.3)')
25
- parser.add_argument('--hops', type=int, default=2, help='Max hops for related (default: 2)')
26
-
27
- args = parser.parse_args()
28
-
29
- engine = GraphEngine()
30
-
31
- if args.command == 'build':
32
- print("Building knowledge graph...")
33
- stats = engine.build_graph(min_similarity=args.min_similarity)
34
- print(json.dumps(stats, indent=2))
35
-
36
- elif args.command == 'stats':
37
- print("Graph Statistics:")
38
- stats = engine.get_stats()
39
- print(json.dumps(stats, indent=2))
40
-
41
- elif args.command == 'related':
42
- if not args.memory_id:
43
- print("Error: --memory-id required for 'related' command")
44
- return
45
-
46
- print(f"Finding memories related to #{args.memory_id}...")
47
- related = engine.get_related(args.memory_id, max_hops=args.hops)
48
-
49
- if not related:
50
- print("No related memories found")
51
- else:
52
- for idx, mem in enumerate(related, 1):
53
- print(f"\n{idx}. Memory #{mem['id']} ({mem['hops']}-hop, weight={mem['weight']:.3f})")
54
- print(f" Relationship: {mem['relationship']}")
55
- summary = mem['summary'] or '[No summary]'
56
- print(f" Summary: {summary[:100]}...")
57
- if mem['shared_entities']:
58
- print(f" Shared: {', '.join(mem['shared_entities'][:5])}")
59
-
60
- elif args.command == 'cluster':
61
- if not args.cluster_id:
62
- print("Error: --cluster-id required for 'cluster' command")
63
- return
64
-
65
- print(f"Cluster #{args.cluster_id} members:")
66
- members = engine.get_cluster_members(args.cluster_id)
67
-
68
- for idx, mem in enumerate(members, 1):
69
- print(f"\n{idx}. Memory #{mem['id']} (importance={mem['importance']})")
70
- summary = mem['summary'] or '[No summary]'
71
- print(f" {summary[:100]}...")
72
-
73
- elif args.command == 'hierarchical':
74
- print("Running hierarchical sub-clustering...")
75
- cluster_builder = ClusterBuilder(engine.db_path)
76
- stats = cluster_builder.hierarchical_cluster()
77
- print(json.dumps(stats, indent=2))
78
-
79
- elif args.command == 'summaries':
80
- print("Generating cluster summaries...")
81
- cluster_builder = ClusterBuilder(engine.db_path)
82
- count = cluster_builder.generate_cluster_summaries()
83
- print(f"Generated summaries for {count} clusters")
84
-
85
-
86
- if __name__ == '__main__':
87
- main()
@@ -1,188 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- """Community detection and cluster management for the graph engine.
5
-
6
- Implements Leiden algorithm based community detection. Hierarchical
7
- sub-clustering is delegated to the ``hierarchical`` module.
8
- """
9
- import sqlite3
10
- import json
11
- from typing import List, Dict
12
- from collections import Counter
13
-
14
- from graph.constants import logger, IGRAPH_AVAILABLE, MEMORY_DIR
15
- from graph.cluster_summary import generate_cluster_summaries as _generate_summaries
16
- from graph.hierarchical import hierarchical_cluster as _hierarchical_cluster
17
-
18
-
19
- class ClusterBuilder:
20
- """Detect memory communities using Leiden algorithm."""
21
-
22
- def __init__(self, db_path):
23
- """Initialize cluster builder."""
24
- self.db_path = db_path
25
-
26
- def _get_active_profile(self) -> str:
27
- """Get the currently active profile name from config."""
28
- config_file = MEMORY_DIR / "profiles.json"
29
- if config_file.exists():
30
- try:
31
- with open(config_file, 'r') as f:
32
- config = json.load(f)
33
- return config.get('active_profile', 'default')
34
- except (json.JSONDecodeError, IOError):
35
- pass
36
- return 'default'
37
-
38
- def detect_communities(self) -> int:
39
- """
40
- Run Leiden algorithm to find memory clusters (active profile only).
41
-
42
- Returns:
43
- Number of clusters created
44
- """
45
- if not IGRAPH_AVAILABLE:
46
- logger.warning("igraph/leidenalg not installed. Graph clustering disabled. Install with: pip3 install python-igraph leidenalg")
47
- return 0
48
- import igraph as ig
49
- import leidenalg
50
-
51
- conn = sqlite3.connect(self.db_path)
52
- cursor = conn.cursor()
53
- active_profile = self._get_active_profile()
54
-
55
- try:
56
- # Load edges for active profile's memories only
57
- edges = cursor.execute('''
58
- SELECT ge.source_memory_id, ge.target_memory_id, ge.weight
59
- FROM graph_edges ge
60
- WHERE ge.source_memory_id IN (SELECT id FROM memories WHERE profile = ?)
61
- AND ge.target_memory_id IN (SELECT id FROM memories WHERE profile = ?)
62
- ''', (active_profile, active_profile)).fetchall()
63
-
64
- if not edges:
65
- logger.warning("No edges found - cannot build clusters")
66
- return 0
67
-
68
- # Build memory ID mapping
69
- memory_ids = set()
70
- for source, target, _ in edges:
71
- memory_ids.add(source)
72
- memory_ids.add(target)
73
-
74
- memory_ids = sorted(list(memory_ids))
75
- memory_id_to_vertex = {mid: idx for idx, mid in enumerate(memory_ids)}
76
- vertex_to_memory_id = {idx: mid for mid, idx in memory_id_to_vertex.items()}
77
-
78
- # Create igraph graph
79
- g = ig.Graph()
80
- g.add_vertices(len(memory_ids))
81
-
82
- edge_list = []
83
- edge_weights = []
84
- for source, target, weight in edges:
85
- edge_list.append((memory_id_to_vertex[source], memory_id_to_vertex[target]))
86
- edge_weights.append(weight)
87
-
88
- g.add_edges(edge_list)
89
-
90
- # Run Leiden algorithm
91
- logger.info(f"Running Leiden on {len(memory_ids)} nodes, {len(edges)} edges")
92
- partition = leidenalg.find_partition(
93
- g, leidenalg.ModularityVertexPartition,
94
- weights=edge_weights, n_iterations=100, seed=42
95
- )
96
-
97
- clusters_created = 0
98
- for cluster_idx, community in enumerate(partition):
99
- if len(community) < 2:
100
- continue
101
-
102
- cluster_memory_ids = [vertex_to_memory_id[v] for v in community]
103
- avg_importance = self._get_avg_importance(cursor, cluster_memory_ids)
104
- cluster_name = self._generate_cluster_name(cursor, cluster_memory_ids)
105
-
106
- result = cursor.execute('''
107
- INSERT INTO graph_clusters (name, member_count, avg_importance)
108
- VALUES (?, ?, ?)
109
- ''', (cluster_name, len(cluster_memory_ids), avg_importance))
110
-
111
- cluster_id = result.lastrowid
112
- cursor.executemany('''
113
- UPDATE memories SET cluster_id = ? WHERE id = ?
114
- ''', [(cluster_id, mid) for mid in cluster_memory_ids])
115
-
116
- clusters_created += 1
117
- logger.info(f"Cluster {cluster_id}: '{cluster_name}' ({len(cluster_memory_ids)} members)")
118
-
119
- conn.commit()
120
- logger.info(f"Created {clusters_created} clusters")
121
- return clusters_created
122
-
123
- except Exception as e:
124
- logger.error(f"Community detection failed: {e}")
125
- conn.rollback()
126
- return 0
127
- finally:
128
- conn.close()
129
-
130
- def _get_avg_importance(self, cursor, memory_ids: List[int]) -> float:
131
- """Calculate average importance for cluster."""
132
- placeholders = ','.join('?' * len(memory_ids))
133
- result = cursor.execute(f'''
134
- SELECT AVG(importance) FROM memories WHERE id IN ({placeholders})
135
- ''', memory_ids).fetchone()
136
- return result[0] if result and result[0] else 5.0
137
-
138
- def _generate_cluster_name(self, cursor, memory_ids: List[int]) -> str:
139
- """Generate cluster name from member entities (TF-IDF approach)."""
140
- placeholders = ','.join('?' * len(memory_ids))
141
- nodes = cursor.execute(f'''
142
- SELECT entities FROM graph_nodes WHERE memory_id IN ({placeholders})
143
- ''', memory_ids).fetchall()
144
-
145
- all_entities = []
146
- for node in nodes:
147
- if node[0]:
148
- all_entities.extend(json.loads(node[0]))
149
-
150
- if not all_entities:
151
- return f"Cluster (ID auto-assigned)"
152
-
153
- entity_counts = Counter(all_entities)
154
- top_entities = [e for e, _ in entity_counts.most_common(3)]
155
-
156
- if len(top_entities) >= 2:
157
- name = f"{top_entities[0].title()} & {top_entities[1].title()}"
158
- elif len(top_entities) == 1:
159
- name = f"{top_entities[0].title()} Contexts"
160
- else:
161
- name = "Mixed Contexts"
162
-
163
- return name[:100]
164
-
165
- def hierarchical_cluster(self, min_subcluster_size: int = 5, max_depth: int = 3) -> Dict[str, any]:
166
- """
167
- Run recursive Leiden clustering -- cluster the clusters.
168
-
169
- Delegates to the hierarchical module.
170
-
171
- Args:
172
- min_subcluster_size: Minimum members to attempt sub-clustering (default 5)
173
- max_depth: Maximum recursion depth (default 3)
174
-
175
- Returns:
176
- Dictionary with hierarchical clustering statistics
177
- """
178
- return _hierarchical_cluster(
179
- self.db_path,
180
- get_avg_importance_fn=self._get_avg_importance,
181
- generate_cluster_name_fn=self._generate_cluster_name,
182
- min_subcluster_size=min_subcluster_size,
183
- max_depth=max_depth,
184
- )
185
-
186
- def generate_cluster_summaries(self) -> int:
187
- """Generate TF-IDF structured summaries for all clusters."""
188
- return _generate_summaries(self.db_path)
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- """Cluster summary generation for the graph engine.
5
-
6
- Generates TF-IDF structured summaries for graph clusters,
7
- analyzing member content to produce human-readable descriptions
8
- of each cluster's theme, key topics, and scope.
9
- """
10
- import sqlite3
11
- import json
12
- from pathlib import Path
13
- from collections import Counter
14
-
15
- from graph.constants import logger, MEMORY_DIR
16
-
17
-
18
- def _get_active_profile() -> str:
19
- """Get the currently active profile name from config."""
20
- config_file = MEMORY_DIR / "profiles.json"
21
- if config_file.exists():
22
- try:
23
- with open(config_file, 'r') as f:
24
- config = json.load(f)
25
- return config.get('active_profile', 'default')
26
- except (json.JSONDecodeError, IOError):
27
- pass
28
- return 'default'
29
-
30
-
31
- def generate_cluster_summaries(db_path: Path) -> int:
32
- """
33
- Generate TF-IDF structured summaries for all clusters.
34
-
35
- For each cluster, analyzes member content to produce a human-readable
36
- summary describing the cluster's theme, key topics, and scope.
37
-
38
- Returns:
39
- Number of clusters with summaries generated
40
- """
41
- conn = sqlite3.connect(db_path)
42
- cursor = conn.cursor()
43
- active_profile = _get_active_profile()
44
-
45
- try:
46
- # Get all clusters for this profile
47
- cursor.execute('''
48
- SELECT DISTINCT gc.id, gc.name, gc.member_count
49
- FROM graph_clusters gc
50
- JOIN memories m ON m.cluster_id = gc.id
51
- WHERE m.profile = ?
52
- ''', (active_profile,))
53
- clusters = cursor.fetchall()
54
-
55
- if not clusters:
56
- return 0
57
-
58
- summaries_generated = 0
59
-
60
- for cluster_id, cluster_name, member_count in clusters:
61
- summary = _build_cluster_summary(cursor, cluster_id, active_profile)
62
- if summary:
63
- cursor.execute('''
64
- UPDATE graph_clusters SET summary = ?, updated_at = CURRENT_TIMESTAMP
65
- WHERE id = ?
66
- ''', (summary, cluster_id))
67
- summaries_generated += 1
68
- logger.info(f"Summary for cluster {cluster_id} ({cluster_name}): {summary[:80]}...")
69
-
70
- conn.commit()
71
- logger.info(f"Generated {summaries_generated} cluster summaries")
72
- return summaries_generated
73
-
74
- except Exception as e:
75
- logger.error(f"Summary generation failed: {e}")
76
- conn.rollback()
77
- return 0
78
- finally:
79
- conn.close()
80
-
81
-
82
- def _build_cluster_summary(cursor, cluster_id: int, profile: str) -> str:
83
- """Build a TF-IDF structured summary for a single cluster."""
84
- # Get member content
85
- cursor.execute('''
86
- SELECT m.content, m.summary, m.tags, m.category, m.project_name
87
- FROM memories m
88
- WHERE m.cluster_id = ? AND m.profile = ?
89
- ''', (cluster_id, profile))
90
- members = cursor.fetchall()
91
-
92
- if not members:
93
- return ""
94
-
95
- # Collect entities from graph nodes
96
- cursor.execute('''
97
- SELECT gn.entities
98
- FROM graph_nodes gn
99
- JOIN memories m ON gn.memory_id = m.id
100
- WHERE m.cluster_id = ? AND m.profile = ?
101
- ''', (cluster_id, profile))
102
- all_entities = []
103
- for row in cursor.fetchall():
104
- if row[0]:
105
- try:
106
- all_entities.extend(json.loads(row[0]))
107
- except (json.JSONDecodeError, TypeError):
108
- pass
109
-
110
- # Top entities by frequency (TF-IDF already extracted these)
111
- entity_counts = Counter(all_entities)
112
- top_entities = [e for e, _ in entity_counts.most_common(5)]
113
-
114
- # Collect unique projects and categories
115
- projects = set()
116
- categories = set()
117
- for m in members:
118
- if m[3]: # category
119
- categories.add(m[3])
120
- if m[4]: # project_name
121
- projects.add(m[4])
122
-
123
- # Build structured summary
124
- parts = []
125
-
126
- # Theme from top entities
127
- if top_entities:
128
- parts.append(f"Key topics: {', '.join(top_entities[:5])}")
129
-
130
- # Scope
131
- if projects:
132
- parts.append(f"Projects: {', '.join(sorted(projects)[:3])}")
133
- if categories:
134
- parts.append(f"Categories: {', '.join(sorted(categories)[:3])}")
135
-
136
- # Size context
137
- parts.append(f"{len(members)} memories")
138
-
139
- # Check for hierarchical context
140
- cursor.execute('SELECT parent_cluster_id FROM graph_clusters WHERE id = ?', (cluster_id,))
141
- parent_row = cursor.fetchone()
142
- if parent_row and parent_row[0]:
143
- cursor.execute('SELECT name FROM graph_clusters WHERE id = ?', (parent_row[0],))
144
- parent_name_row = cursor.fetchone()
145
- if parent_name_row:
146
- parts.append(f"Sub-cluster of: {parent_name_row[0]}")
147
-
148
- return " | ".join(parts)
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- """Shared constants, imports, and configuration for the graph engine modules.
5
- """
6
- # SECURITY: Graph build limits to prevent resource exhaustion
7
- MAX_MEMORIES_FOR_GRAPH = 10000
8
-
9
- import sqlite3
10
- import json
11
- import time
12
- import logging
13
- from datetime import datetime
14
- from pathlib import Path
15
- from typing import List, Dict, Optional, Tuple, Set
16
- from collections import Counter
17
-
18
- # Core dependencies
19
- try:
20
- from sklearn.feature_extraction.text import TfidfVectorizer
21
- from sklearn.metrics.pairwise import cosine_similarity
22
- import numpy as np
23
- SKLEARN_AVAILABLE = True
24
- except ImportError:
25
- SKLEARN_AVAILABLE = False
26
- raise ImportError("scikit-learn is required. Install: pip install scikit-learn")
27
-
28
- # Graph dependencies - lazy import to avoid conflicts with compression module
29
- IGRAPH_AVAILABLE = False
30
- try:
31
- # Import only when needed to avoid module conflicts
32
- import importlib
33
- ig_module = importlib.import_module('igraph')
34
- leiden_module = importlib.import_module('leidenalg')
35
- IGRAPH_AVAILABLE = True
36
- except ImportError:
37
- pass # Will raise error when building clusters if not available
38
-
39
- # Setup logging
40
- logging.basicConfig(
41
- level=logging.INFO,
42
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
43
- )
44
- logger = logging.getLogger('graph_engine')
45
-
46
- MEMORY_DIR = Path.home() / ".claude-memory"
47
- DB_PATH = MEMORY_DIR / "memory.db"