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,429 +0,0 @@
1
- #!/usr/bin/env python3
2
- # SPDX-License-Identifier: MIT
3
- # Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
4
- import sqlite3
5
- from pathlib import Path
6
-
7
- import pytest
8
-
9
- # Detect optional dependencies at import time
10
- try:
11
- import lightgbm
12
- HAS_LIGHTGBM = True
13
- except ImportError:
14
- HAS_LIGHTGBM = False
15
-
16
- try:
17
- import numpy as np
18
- HAS_NUMPY = True
19
- except ImportError:
20
- np = None
21
- HAS_NUMPY = False
22
-
23
-
24
- # ---------------------------------------------------------------------------
25
- # Fixtures
26
- # ---------------------------------------------------------------------------
27
-
28
- @pytest.fixture(autouse=True)
29
- def reset_singleton():
30
- from src.learning.learning_db import LearningDB
31
- LearningDB.reset_instance()
32
- yield
33
- LearningDB.reset_instance()
34
-
35
-
36
- @pytest.fixture
37
- def learning_db(tmp_path):
38
- from src.learning.learning_db import LearningDB
39
- db_path = tmp_path / "learning.db"
40
- return LearningDB(db_path=db_path)
41
-
42
-
43
- @pytest.fixture
44
- def memory_db(tmp_path):
45
- """Create a memory.db with FTS5 and identity_patterns tables."""
46
- db_path = tmp_path / "memory.db"
47
- conn = sqlite3.connect(str(db_path))
48
- cursor = conn.cursor()
49
- cursor.execute('''
50
- CREATE TABLE IF NOT EXISTS memories (
51
- id INTEGER PRIMARY KEY AUTOINCREMENT,
52
- content TEXT NOT NULL,
53
- summary TEXT,
54
- project_path TEXT,
55
- project_name TEXT,
56
- tags TEXT DEFAULT '[]',
57
- category TEXT,
58
- parent_id INTEGER,
59
- tree_path TEXT DEFAULT '/',
60
- depth INTEGER DEFAULT 0,
61
- memory_type TEXT DEFAULT 'session',
62
- importance INTEGER DEFAULT 5,
63
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
64
- last_accessed TIMESTAMP,
65
- access_count INTEGER DEFAULT 0,
66
- content_hash TEXT,
67
- cluster_id INTEGER,
68
- profile TEXT DEFAULT 'default',
69
- created_by TEXT,
70
- source_protocol TEXT,
71
- trust_score REAL DEFAULT 1.0
72
- )
73
- ''')
74
- cursor.execute('''
75
- CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
76
- USING fts5(content, summary, tags, content='memories', content_rowid='id')
77
- ''')
78
- cursor.execute('''
79
- CREATE TABLE IF NOT EXISTS identity_patterns (
80
- id INTEGER PRIMARY KEY,
81
- pattern_type TEXT,
82
- pattern_key TEXT,
83
- pattern_value TEXT,
84
- confidence REAL DEFAULT 0.0,
85
- frequency INTEGER DEFAULT 1,
86
- last_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
87
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
88
- )
89
- ''')
90
- conn.commit()
91
- conn.close()
92
- return db_path
93
-
94
-
95
- def _insert_memories(db_path, memories):
96
- conn = sqlite3.connect(str(db_path))
97
- cursor = conn.cursor()
98
- for m in memories:
99
- cursor.execute('''
100
- INSERT INTO memories (content, tags, project_name, project_path,
101
- importance, access_count, profile, created_by,
102
- source_protocol, created_at, category)
103
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
104
- ''', (
105
- m.get('content', 'test'),
106
- m.get('tags', '[]'),
107
- m.get('project_name'),
108
- m.get('project_path'),
109
- m.get('importance', 5),
110
- m.get('access_count', 0),
111
- m.get('profile', 'default'),
112
- m.get('created_by'),
113
- m.get('source_protocol'),
114
- m.get('created_at', '2026-02-16 10:00:00'),
115
- m.get('category'),
116
- ))
117
- conn.commit()
118
- conn.close()
119
-
120
-
121
- def _insert_patterns(db_path, patterns):
122
- conn = sqlite3.connect(str(db_path))
123
- cursor = conn.cursor()
124
- for p in patterns:
125
- cursor.execute('''
126
- INSERT INTO identity_patterns (pattern_type, pattern_key,
127
- pattern_value, confidence)
128
- VALUES (?, ?, ?, ?)
129
- ''', (
130
- p.get('pattern_type', 'tech'),
131
- p.get('key', 'unknown'),
132
- p.get('value', 'unknown'),
133
- p.get('confidence', 0.8),
134
- ))
135
- conn.commit()
136
- conn.close()
137
-
138
-
139
- @pytest.fixture
140
- def bootstrapper(memory_db, learning_db):
141
- from src.learning.synthetic_bootstrap import SyntheticBootstrapper
142
- return SyntheticBootstrapper(
143
- memory_db_path=memory_db,
144
- learning_db=learning_db,
145
- )
146
-
147
-
148
- @pytest.fixture
149
- def bootstrapper_with_data(memory_db, learning_db):
150
- """Bootstrapper with 60 memories (above MIN_MEMORIES_FOR_BOOTSTRAP=50)."""
151
- memories = []
152
- for i in range(60):
153
- memories.append({
154
- "content": f"Memory about python fastapi development topic {i} implementing features",
155
- "tags": '["python", "fastapi"]',
156
- "project_name": "TestProject" if i % 3 == 0 else "OtherProject",
157
- "importance": 8 if i % 5 == 0 else 5,
158
- "access_count": 10 if i % 4 == 0 else 1,
159
- "created_at": f"2026-02-{(i % 28) + 1:02d} 10:00:00",
160
- "category": "development" if i % 2 == 0 else "architecture",
161
- })
162
- _insert_memories(memory_db, memories)
163
-
164
- from src.learning.synthetic_bootstrap import SyntheticBootstrapper
165
- return SyntheticBootstrapper(
166
- memory_db_path=memory_db,
167
- learning_db=learning_db,
168
- )
169
-
170
-
171
- # ---------------------------------------------------------------------------
172
- # should_bootstrap
173
- # ---------------------------------------------------------------------------
174
-
175
- class TestShouldBootstrap:
176
- def test_returns_false_below_50_memories(self, bootstrapper, memory_db):
177
- """With fewer than 50 memories, bootstrap should not run."""
178
- _insert_memories(memory_db, [
179
- {"content": f"Memory {i}"} for i in range(10)
180
- ])
181
- assert bootstrapper.should_bootstrap() is False
182
-
183
- @pytest.mark.skipif(not HAS_LIGHTGBM or not HAS_NUMPY,
184
- reason="LightGBM/NumPy required")
185
- def test_returns_true_above_50(self, bootstrapper_with_data, tmp_path):
186
- """With 50+ memories, LightGBM, and no existing model, should be True."""
187
- # Ensure no model file exists
188
- from src.learning.synthetic_bootstrap import MODEL_PATH
189
- if MODEL_PATH.exists():
190
- MODEL_PATH.unlink()
191
- assert bootstrapper_with_data.should_bootstrap() is True
192
-
193
- def test_returns_false_without_lightgbm(self, bootstrapper_with_data):
194
- """Without LightGBM, bootstrap should be False."""
195
- from src.learning import synthetic_bootstrap as sb_module
196
- original = sb_module.HAS_LIGHTGBM
197
- sb_module.HAS_LIGHTGBM = False
198
- try:
199
- assert bootstrapper_with_data.should_bootstrap() is False
200
- finally:
201
- sb_module.HAS_LIGHTGBM = original
202
-
203
- def test_returns_false_with_existing_model(self, bootstrapper_with_data, tmp_path):
204
- """If a model file exists, bootstrap should be False."""
205
- from src.learning.synthetic_bootstrap import MODEL_PATH
206
- MODEL_PATH.parent.mkdir(parents=True, exist_ok=True)
207
- MODEL_PATH.write_text("dummy model")
208
- try:
209
- assert bootstrapper_with_data.should_bootstrap() is False
210
- finally:
211
- if MODEL_PATH.exists():
212
- MODEL_PATH.unlink()
213
-
214
-
215
- # ---------------------------------------------------------------------------
216
- # get_tier
217
- # ---------------------------------------------------------------------------
218
-
219
- class TestGetTier:
220
- def test_none_below_50(self, bootstrapper, memory_db):
221
- _insert_memories(memory_db, [{"content": f"m{i}"} for i in range(10)])
222
- assert bootstrapper.get_tier() is None
223
-
224
- def test_small_tier(self, bootstrapper, memory_db):
225
- _insert_memories(memory_db, [{"content": f"m{i}"} for i in range(60)])
226
- assert bootstrapper.get_tier() == "small"
227
-
228
- def test_medium_tier(self, bootstrapper, memory_db):
229
- _insert_memories(memory_db, [{"content": f"m{i}"} for i in range(600)])
230
- assert bootstrapper.get_tier() == "medium"
231
-
232
- def test_large_tier(self, bootstrapper, memory_db):
233
- _insert_memories(memory_db, [{"content": f"m{i}"} for i in range(5100)])
234
- assert bootstrapper.get_tier() == "large"
235
-
236
-
237
- # ---------------------------------------------------------------------------
238
- # Synthetic Data Generation
239
- # ---------------------------------------------------------------------------
240
-
241
- class TestGenerateSyntheticData:
242
- def test_generates_records(self, bootstrapper_with_data):
243
- """Should produce non-empty list of training records."""
244
- records = bootstrapper_with_data.generate_synthetic_training_data()
245
- assert len(records) > 0
246
-
247
- def test_record_structure(self, bootstrapper_with_data):
248
- records = bootstrapper_with_data.generate_synthetic_training_data()
249
- if records:
250
- r = records[0]
251
- assert "query" in r
252
- assert "query_hash" in r
253
- assert "memory_id" in r
254
- assert "label" in r
255
- assert "source" in r
256
- assert "features" in r
257
- assert len(r["features"]) == 20 # 20-dimensional feature vector (v2.8)
258
-
259
- def test_labels_in_range(self, bootstrapper_with_data):
260
- records = bootstrapper_with_data.generate_synthetic_training_data()
261
- for r in records:
262
- assert 0.0 <= r["label"] <= 1.0, f"Label out of range: {r['label']}"
263
-
264
- def test_multiple_sources(self, bootstrapper_with_data):
265
- """Data should come from multiple strategies."""
266
- records = bootstrapper_with_data.generate_synthetic_training_data()
267
- sources = {r["source"] for r in records}
268
- # At least 2 different source strategies should contribute
269
- assert len(sources) >= 1 # access_based or importance_based at minimum
270
-
271
- def test_with_identity_patterns(self, memory_db, learning_db):
272
- """Pattern-based strategy should use identity_patterns."""
273
- _insert_memories(memory_db, [
274
- {
275
- "content": f"Using python and fastapi for backend development {i}",
276
- "importance": 8 if i % 3 == 0 else 5,
277
- "access_count": 6 if i % 4 == 0 else 1,
278
- }
279
- for i in range(60)
280
- ])
281
- _insert_patterns(memory_db, [
282
- {"pattern_type": "tech", "key": "language", "value": "python",
283
- "confidence": 0.9},
284
- {"pattern_type": "tech", "key": "framework", "value": "fastapi",
285
- "confidence": 0.85},
286
- ])
287
-
288
- from src.learning.synthetic_bootstrap import SyntheticBootstrapper
289
- bs = SyntheticBootstrapper(
290
- memory_db_path=memory_db,
291
- learning_db=learning_db,
292
- )
293
- records = bs.generate_synthetic_training_data()
294
- pattern_records = [r for r in records if r["source"] == "pattern"]
295
- # Pattern-based records may or may not be generated depending on FTS5
296
- # The important thing is no crash
297
- assert isinstance(pattern_records, list)
298
-
299
-
300
- # ---------------------------------------------------------------------------
301
- # Keyword Extraction
302
- # ---------------------------------------------------------------------------
303
-
304
- class TestExtractKeywords:
305
- def test_basic_extraction(self, bootstrapper):
306
- kws = bootstrapper._extract_keywords("python fastapi deployment docker")
307
- assert len(kws) <= 3
308
- assert len(kws) > 0
309
- assert all(isinstance(k, str) for k in kws)
310
-
311
- def test_stopword_removal(self, bootstrapper):
312
- kws = bootstrapper._extract_keywords("the and or but python")
313
- assert "the" not in kws
314
- assert "and" not in kws
315
- assert "python" in kws
316
-
317
- def test_empty_content(self, bootstrapper):
318
- assert bootstrapper._extract_keywords("") == []
319
-
320
- def test_only_stopwords(self, bootstrapper):
321
- assert bootstrapper._extract_keywords("the and or but is are") == []
322
-
323
- def test_short_words_filtered(self, bootstrapper):
324
- """Words shorter than MIN_KEYWORD_LENGTH (3) should be filtered."""
325
- kws = bootstrapper._extract_keywords("a by python")
326
- assert "a" not in kws
327
- assert "by" not in kws
328
-
329
- def test_frequency_based(self, bootstrapper):
330
- """Most frequent word should appear first."""
331
- kws = bootstrapper._extract_keywords(
332
- "python python python fastapi fastapi docker"
333
- )
334
- assert kws[0] == "python"
335
-
336
-
337
- # ---------------------------------------------------------------------------
338
- # bootstrap_model (LightGBM required)
339
- # ---------------------------------------------------------------------------
340
-
341
- class TestBootstrapModel:
342
- @pytest.mark.skipif(not HAS_LIGHTGBM or not HAS_NUMPY,
343
- reason="LightGBM/NumPy required for bootstrap training")
344
- def test_bootstrap_with_sufficient_data(self, bootstrapper_with_data, tmp_path):
345
- """Full bootstrap should produce a model file and return metadata."""
346
- from src.learning.synthetic_bootstrap import MODEL_PATH, MODELS_DIR
347
- # Clean up any existing model
348
- if MODEL_PATH.exists():
349
- MODEL_PATH.unlink()
350
-
351
- result = bootstrapper_with_data.bootstrap_model()
352
- if result is not None:
353
- assert "model_version" in result
354
- assert "training_samples" in result
355
- assert result["training_samples"] > 0
356
- assert "bootstrap" in result["model_version"]
357
- assert "tier" in result
358
- assert result["tier"] == "small" # 60 memories = small tier
359
-
360
- # Clean up
361
- if MODEL_PATH.exists():
362
- MODEL_PATH.unlink()
363
-
364
- def test_bootstrap_without_lightgbm(self, bootstrapper_with_data):
365
- """Should return None gracefully when LightGBM not available."""
366
- from src.learning import synthetic_bootstrap as sb_module
367
- original_lgb = sb_module.HAS_LIGHTGBM
368
- sb_module.HAS_LIGHTGBM = False
369
- try:
370
- result = bootstrapper_with_data.bootstrap_model()
371
- assert result is None
372
- finally:
373
- sb_module.HAS_LIGHTGBM = original_lgb
374
-
375
- def test_bootstrap_below_minimum(self, bootstrapper, memory_db):
376
- """Should return None with too few memories."""
377
- _insert_memories(memory_db, [{"content": f"m{i}"} for i in range(10)])
378
- result = bootstrapper.bootstrap_model()
379
- assert result is None
380
-
381
-
382
- # ---------------------------------------------------------------------------
383
- # Diverse Sample
384
- # ---------------------------------------------------------------------------
385
-
386
- class TestDiverseSample:
387
- def test_under_target(self, bootstrapper):
388
- records = [{"source": "a", "query_hash": "q1", "memory_id": 1}] * 5
389
- result = bootstrapper._diverse_sample(records, 10)
390
- assert len(result) == 5
391
-
392
- def test_over_target_proportional(self, bootstrapper):
393
- records = (
394
- [{"source": "a", "query_hash": f"qa{i}", "memory_id": i} for i in range(50)]
395
- + [{"source": "b", "query_hash": f"qb{i}", "memory_id": i + 50} for i in range(50)]
396
- )
397
- result = bootstrapper._diverse_sample(records, 20)
398
- assert len(result) == 20
399
- sources = {r["source"] for r in result}
400
- assert len(sources) == 2 # Both sources represented
401
-
402
-
403
- # ---------------------------------------------------------------------------
404
- # Count Sources
405
- # ---------------------------------------------------------------------------
406
-
407
- class TestCountSources:
408
- def test_count(self, bootstrapper):
409
- records = [
410
- {"source": "access_positive"},
411
- {"source": "access_positive"},
412
- {"source": "importance_positive"},
413
- {"source": "recency_positive"},
414
- ]
415
- counts = bootstrapper._count_sources(records)
416
- assert counts["access_positive"] == 2
417
- assert counts["importance_positive"] == 1
418
- assert counts["recency_positive"] == 1
419
-
420
-
421
- # ---------------------------------------------------------------------------
422
- # Module-level convenience
423
- # ---------------------------------------------------------------------------
424
-
425
- class TestModuleLevel:
426
- def test_should_bootstrap_function(self, memory_db):
427
- from src.learning.synthetic_bootstrap import should_bootstrap
428
- result = should_bootstrap(memory_db_path=memory_db)
429
- assert isinstance(result, bool)