superlocalmemory 2.8.6 → 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 (431) hide show
  1. package/LICENSE +9 -1
  2. package/NOTICE +63 -0
  3. package/README.md +165 -480
  4. package/bin/slm +17 -449
  5. package/bin/slm-npm +1 -1
  6. package/conftest.py +5 -0
  7. package/docs/api-reference.md +284 -0
  8. package/docs/architecture.md +149 -0
  9. package/docs/auto-memory.md +150 -0
  10. package/docs/cli-reference.md +276 -0
  11. package/docs/compliance.md +191 -0
  12. package/docs/configuration.md +182 -0
  13. package/docs/getting-started.md +102 -0
  14. package/docs/ide-setup.md +261 -0
  15. package/docs/mcp-tools.md +220 -0
  16. package/docs/migration-from-v2.md +170 -0
  17. package/docs/profiles.md +173 -0
  18. package/docs/troubleshooting.md +310 -0
  19. package/{configs → ide/configs}/antigravity-mcp.json +3 -3
  20. package/ide/configs/chatgpt-desktop-mcp.json +16 -0
  21. package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
  22. package/{configs → ide/configs}/codex-mcp.toml +4 -4
  23. package/{configs → ide/configs}/continue-mcp.yaml +4 -3
  24. package/{configs → ide/configs}/continue-skills.yaml +6 -6
  25. package/ide/configs/cursor-mcp.json +15 -0
  26. package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
  27. package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
  28. package/{configs → ide/configs}/opencode-mcp.json +2 -2
  29. package/{configs → ide/configs}/perplexity-mcp.json +2 -2
  30. package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
  31. package/{configs → ide/configs}/windsurf-mcp.json +3 -3
  32. package/{configs → ide/configs}/zed-mcp.json +2 -2
  33. package/{hooks → ide/hooks}/context-hook.js +9 -20
  34. package/ide/hooks/memory-list-skill.js +70 -0
  35. package/ide/hooks/memory-profile-skill.js +101 -0
  36. package/ide/hooks/memory-recall-skill.js +62 -0
  37. package/ide/hooks/memory-remember-skill.js +68 -0
  38. package/ide/hooks/memory-reset-skill.js +160 -0
  39. package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
  40. package/ide/integrations/langchain/README.md +106 -0
  41. package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
  42. package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
  43. package/ide/integrations/langchain/pyproject.toml +38 -0
  44. package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
  45. package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
  46. package/ide/integrations/langchain/tests/test_security.py +117 -0
  47. package/ide/integrations/llamaindex/README.md +81 -0
  48. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
  49. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
  50. package/ide/integrations/llamaindex/pyproject.toml +43 -0
  51. package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
  52. package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
  53. package/ide/integrations/llamaindex/tests/test_security.py +241 -0
  54. package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
  55. package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
  56. package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
  57. package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
  58. package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
  59. package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
  60. package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
  61. package/package.json +13 -22
  62. package/pyproject.toml +85 -0
  63. package/scripts/build-dmg.sh +417 -0
  64. package/scripts/install-skills.ps1 +334 -0
  65. package/scripts/postinstall.js +2 -2
  66. package/scripts/start-dashboard.ps1 +52 -0
  67. package/scripts/start-dashboard.sh +41 -0
  68. package/scripts/sync-wiki.ps1 +127 -0
  69. package/scripts/sync-wiki.sh +82 -0
  70. package/scripts/test-dmg.sh +161 -0
  71. package/scripts/test-npm-package.ps1 +252 -0
  72. package/scripts/test-npm-package.sh +207 -0
  73. package/scripts/verify-install.ps1 +294 -0
  74. package/scripts/verify-install.sh +266 -0
  75. package/src/superlocalmemory/__init__.py +0 -0
  76. package/src/superlocalmemory/attribution/__init__.py +9 -0
  77. package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
  78. package/src/superlocalmemory/attribution/signer.py +153 -0
  79. package/src/superlocalmemory/attribution/watermark.py +189 -0
  80. package/src/superlocalmemory/cli/__init__.py +5 -0
  81. package/src/superlocalmemory/cli/commands.py +245 -0
  82. package/src/superlocalmemory/cli/main.py +89 -0
  83. package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
  84. package/src/superlocalmemory/cli/post_install.py +99 -0
  85. package/src/superlocalmemory/cli/setup_wizard.py +129 -0
  86. package/src/superlocalmemory/compliance/__init__.py +0 -0
  87. package/src/superlocalmemory/compliance/abac.py +204 -0
  88. package/src/superlocalmemory/compliance/audit.py +314 -0
  89. package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
  90. package/src/superlocalmemory/compliance/gdpr.py +294 -0
  91. package/src/superlocalmemory/compliance/lifecycle.py +158 -0
  92. package/src/superlocalmemory/compliance/retention.py +232 -0
  93. package/src/superlocalmemory/compliance/scheduler.py +148 -0
  94. package/src/superlocalmemory/core/__init__.py +0 -0
  95. package/src/superlocalmemory/core/config.py +391 -0
  96. package/src/superlocalmemory/core/embeddings.py +293 -0
  97. package/src/superlocalmemory/core/engine.py +701 -0
  98. package/src/superlocalmemory/core/hooks.py +65 -0
  99. package/src/superlocalmemory/core/maintenance.py +172 -0
  100. package/src/superlocalmemory/core/modes.py +140 -0
  101. package/src/superlocalmemory/core/profiles.py +234 -0
  102. package/src/superlocalmemory/core/registry.py +117 -0
  103. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  104. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
  105. package/src/superlocalmemory/encoding/__init__.py +0 -0
  106. package/src/superlocalmemory/encoding/consolidator.py +485 -0
  107. package/src/superlocalmemory/encoding/emotional.py +125 -0
  108. package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
  109. package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
  110. package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
  111. package/src/superlocalmemory/encoding/foresight.py +91 -0
  112. package/src/superlocalmemory/encoding/graph_builder.py +302 -0
  113. package/src/superlocalmemory/encoding/observation_builder.py +160 -0
  114. package/src/superlocalmemory/encoding/scene_builder.py +183 -0
  115. package/src/superlocalmemory/encoding/signal_inference.py +90 -0
  116. package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
  117. package/src/superlocalmemory/encoding/type_router.py +235 -0
  118. package/src/superlocalmemory/hooks/__init__.py +3 -0
  119. package/src/superlocalmemory/hooks/auto_capture.py +111 -0
  120. package/src/superlocalmemory/hooks/auto_recall.py +93 -0
  121. package/src/superlocalmemory/hooks/ide_connector.py +204 -0
  122. package/src/superlocalmemory/hooks/rules_engine.py +99 -0
  123. package/src/superlocalmemory/infra/__init__.py +3 -0
  124. package/src/superlocalmemory/infra/auth_middleware.py +82 -0
  125. package/src/superlocalmemory/infra/backup.py +317 -0
  126. package/src/superlocalmemory/infra/cache_manager.py +267 -0
  127. package/src/superlocalmemory/infra/event_bus.py +381 -0
  128. package/src/superlocalmemory/infra/rate_limiter.py +135 -0
  129. package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
  130. package/src/superlocalmemory/learning/__init__.py +0 -0
  131. package/src/superlocalmemory/learning/adaptive.py +172 -0
  132. package/src/superlocalmemory/learning/behavioral.py +490 -0
  133. package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
  134. package/src/superlocalmemory/learning/bootstrap.py +298 -0
  135. package/src/superlocalmemory/learning/cross_project.py +399 -0
  136. package/src/superlocalmemory/learning/database.py +376 -0
  137. package/src/superlocalmemory/learning/engagement.py +323 -0
  138. package/src/superlocalmemory/learning/features.py +138 -0
  139. package/src/superlocalmemory/learning/feedback.py +316 -0
  140. package/src/superlocalmemory/learning/outcomes.py +255 -0
  141. package/src/superlocalmemory/learning/project_context.py +366 -0
  142. package/src/superlocalmemory/learning/ranker.py +155 -0
  143. package/src/superlocalmemory/learning/source_quality.py +303 -0
  144. package/src/superlocalmemory/learning/workflows.py +309 -0
  145. package/src/superlocalmemory/llm/__init__.py +0 -0
  146. package/src/superlocalmemory/llm/backbone.py +316 -0
  147. package/src/superlocalmemory/math/__init__.py +0 -0
  148. package/src/superlocalmemory/math/fisher.py +356 -0
  149. package/src/superlocalmemory/math/langevin.py +398 -0
  150. package/src/superlocalmemory/math/sheaf.py +257 -0
  151. package/src/superlocalmemory/mcp/__init__.py +0 -0
  152. package/src/superlocalmemory/mcp/resources.py +245 -0
  153. package/src/superlocalmemory/mcp/server.py +61 -0
  154. package/src/superlocalmemory/mcp/tools.py +18 -0
  155. package/src/superlocalmemory/mcp/tools_core.py +305 -0
  156. package/src/superlocalmemory/mcp/tools_v28.py +223 -0
  157. package/src/superlocalmemory/mcp/tools_v3.py +286 -0
  158. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  159. package/src/superlocalmemory/retrieval/agentic.py +295 -0
  160. package/src/superlocalmemory/retrieval/ann_index.py +223 -0
  161. package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
  162. package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
  163. package/src/superlocalmemory/retrieval/engine.py +390 -0
  164. package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
  165. package/src/superlocalmemory/retrieval/fusion.py +78 -0
  166. package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
  167. package/src/superlocalmemory/retrieval/reranker.py +154 -0
  168. package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
  169. package/src/superlocalmemory/retrieval/strategy.py +96 -0
  170. package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
  171. package/src/superlocalmemory/server/__init__.py +1 -0
  172. package/src/superlocalmemory/server/api.py +248 -0
  173. package/src/superlocalmemory/server/routes/__init__.py +4 -0
  174. package/src/superlocalmemory/server/routes/agents.py +107 -0
  175. package/src/superlocalmemory/server/routes/backup.py +91 -0
  176. package/src/superlocalmemory/server/routes/behavioral.py +127 -0
  177. package/src/superlocalmemory/server/routes/compliance.py +160 -0
  178. package/src/superlocalmemory/server/routes/data_io.py +188 -0
  179. package/src/superlocalmemory/server/routes/events.py +183 -0
  180. package/src/superlocalmemory/server/routes/helpers.py +85 -0
  181. package/src/superlocalmemory/server/routes/learning.py +273 -0
  182. package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
  183. package/src/superlocalmemory/server/routes/memories.py +399 -0
  184. package/src/superlocalmemory/server/routes/profiles.py +219 -0
  185. package/src/superlocalmemory/server/routes/stats.py +346 -0
  186. package/src/superlocalmemory/server/routes/v3_api.py +365 -0
  187. package/src/superlocalmemory/server/routes/ws.py +82 -0
  188. package/src/superlocalmemory/server/security_middleware.py +57 -0
  189. package/src/superlocalmemory/server/ui.py +245 -0
  190. package/src/superlocalmemory/storage/__init__.py +0 -0
  191. package/src/superlocalmemory/storage/access_control.py +182 -0
  192. package/src/superlocalmemory/storage/database.py +594 -0
  193. package/src/superlocalmemory/storage/migrations.py +303 -0
  194. package/src/superlocalmemory/storage/models.py +406 -0
  195. package/src/superlocalmemory/storage/schema.py +726 -0
  196. package/src/superlocalmemory/storage/v2_migrator.py +317 -0
  197. package/src/superlocalmemory/trust/__init__.py +0 -0
  198. package/src/superlocalmemory/trust/gate.py +130 -0
  199. package/src/superlocalmemory/trust/provenance.py +124 -0
  200. package/src/superlocalmemory/trust/scorer.py +347 -0
  201. package/src/superlocalmemory/trust/signals.py +153 -0
  202. package/ui/index.html +278 -5
  203. package/ui/js/auto-settings.js +70 -0
  204. package/ui/js/dashboard.js +90 -0
  205. package/ui/js/fact-detail.js +92 -0
  206. package/ui/js/feedback.js +2 -2
  207. package/ui/js/ide-status.js +102 -0
  208. package/ui/js/math-health.js +98 -0
  209. package/ui/js/recall-lab.js +127 -0
  210. package/ui/js/settings.js +2 -2
  211. package/ui/js/trust-dashboard.js +73 -0
  212. package/api_server.py +0 -724
  213. package/bin/aider-smart +0 -72
  214. package/bin/superlocalmemoryv2-learning +0 -4
  215. package/bin/superlocalmemoryv2-list +0 -3
  216. package/bin/superlocalmemoryv2-patterns +0 -4
  217. package/bin/superlocalmemoryv2-profile +0 -3
  218. package/bin/superlocalmemoryv2-recall +0 -3
  219. package/bin/superlocalmemoryv2-remember +0 -3
  220. package/bin/superlocalmemoryv2-reset +0 -3
  221. package/bin/superlocalmemoryv2-status +0 -3
  222. package/configs/chatgpt-desktop-mcp.json +0 -16
  223. package/configs/cursor-mcp.json +0 -15
  224. package/hooks/memory-list-skill.js +0 -139
  225. package/hooks/memory-profile-skill.js +0 -273
  226. package/hooks/memory-recall-skill.js +0 -114
  227. package/hooks/memory-remember-skill.js +0 -127
  228. package/hooks/memory-reset-skill.js +0 -274
  229. package/mcp_server.py +0 -1808
  230. package/requirements-core.txt +0 -22
  231. package/requirements-learning.txt +0 -12
  232. package/requirements.txt +0 -12
  233. package/src/agent_registry.py +0 -411
  234. package/src/auth_middleware.py +0 -61
  235. package/src/auto_backup.py +0 -459
  236. package/src/behavioral/__init__.py +0 -49
  237. package/src/behavioral/behavioral_listener.py +0 -203
  238. package/src/behavioral/behavioral_patterns.py +0 -275
  239. package/src/behavioral/cross_project_transfer.py +0 -206
  240. package/src/behavioral/outcome_inference.py +0 -194
  241. package/src/behavioral/outcome_tracker.py +0 -193
  242. package/src/behavioral/tests/__init__.py +0 -4
  243. package/src/behavioral/tests/test_behavioral_integration.py +0 -108
  244. package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
  245. package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
  246. package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
  247. package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
  248. package/src/behavioral/tests/test_outcome_inference.py +0 -107
  249. package/src/behavioral/tests/test_outcome_tracker.py +0 -96
  250. package/src/cache_manager.py +0 -518
  251. package/src/compliance/__init__.py +0 -48
  252. package/src/compliance/abac_engine.py +0 -149
  253. package/src/compliance/abac_middleware.py +0 -116
  254. package/src/compliance/audit_db.py +0 -215
  255. package/src/compliance/audit_logger.py +0 -148
  256. package/src/compliance/retention_manager.py +0 -289
  257. package/src/compliance/retention_scheduler.py +0 -186
  258. package/src/compliance/tests/__init__.py +0 -4
  259. package/src/compliance/tests/test_abac_enforcement.py +0 -95
  260. package/src/compliance/tests/test_abac_engine.py +0 -124
  261. package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
  262. package/src/compliance/tests/test_audit_db.py +0 -123
  263. package/src/compliance/tests/test_audit_logger.py +0 -98
  264. package/src/compliance/tests/test_mcp_audit.py +0 -128
  265. package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
  266. package/src/compliance/tests/test_retention_manager.py +0 -131
  267. package/src/compliance/tests/test_retention_scheduler.py +0 -99
  268. package/src/compression/__init__.py +0 -25
  269. package/src/compression/cli.py +0 -150
  270. package/src/compression/cold_storage.py +0 -217
  271. package/src/compression/config.py +0 -72
  272. package/src/compression/orchestrator.py +0 -133
  273. package/src/compression/tier2_compressor.py +0 -228
  274. package/src/compression/tier3_compressor.py +0 -153
  275. package/src/compression/tier_classifier.py +0 -148
  276. package/src/db_connection_manager.py +0 -536
  277. package/src/embedding_engine.py +0 -63
  278. package/src/embeddings/__init__.py +0 -47
  279. package/src/embeddings/cache.py +0 -70
  280. package/src/embeddings/cli.py +0 -113
  281. package/src/embeddings/constants.py +0 -47
  282. package/src/embeddings/database.py +0 -91
  283. package/src/embeddings/engine.py +0 -247
  284. package/src/embeddings/model_loader.py +0 -145
  285. package/src/event_bus.py +0 -562
  286. package/src/graph/__init__.py +0 -36
  287. package/src/graph/build_helpers.py +0 -74
  288. package/src/graph/cli.py +0 -87
  289. package/src/graph/cluster_builder.py +0 -188
  290. package/src/graph/cluster_summary.py +0 -148
  291. package/src/graph/constants.py +0 -47
  292. package/src/graph/edge_builder.py +0 -162
  293. package/src/graph/entity_extractor.py +0 -95
  294. package/src/graph/graph_core.py +0 -226
  295. package/src/graph/graph_search.py +0 -231
  296. package/src/graph/hierarchical.py +0 -207
  297. package/src/graph/schema.py +0 -99
  298. package/src/graph_engine.py +0 -52
  299. package/src/hnsw_index.py +0 -628
  300. package/src/hybrid_search.py +0 -46
  301. package/src/learning/__init__.py +0 -217
  302. package/src/learning/adaptive_ranker.py +0 -682
  303. package/src/learning/bootstrap/__init__.py +0 -69
  304. package/src/learning/bootstrap/constants.py +0 -93
  305. package/src/learning/bootstrap/db_queries.py +0 -316
  306. package/src/learning/bootstrap/sampling.py +0 -82
  307. package/src/learning/bootstrap/text_utils.py +0 -71
  308. package/src/learning/cross_project_aggregator.py +0 -857
  309. package/src/learning/db/__init__.py +0 -40
  310. package/src/learning/db/constants.py +0 -44
  311. package/src/learning/db/schema.py +0 -279
  312. package/src/learning/engagement_tracker.py +0 -628
  313. package/src/learning/feature_extractor.py +0 -708
  314. package/src/learning/feedback_collector.py +0 -806
  315. package/src/learning/learning_db.py +0 -915
  316. package/src/learning/project_context_manager.py +0 -572
  317. package/src/learning/ranking/__init__.py +0 -33
  318. package/src/learning/ranking/constants.py +0 -84
  319. package/src/learning/ranking/helpers.py +0 -278
  320. package/src/learning/source_quality_scorer.py +0 -676
  321. package/src/learning/synthetic_bootstrap.py +0 -755
  322. package/src/learning/tests/test_adaptive_ranker.py +0 -325
  323. package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
  324. package/src/learning/tests/test_aggregator.py +0 -306
  325. package/src/learning/tests/test_auto_retrain_v28.py +0 -35
  326. package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
  327. package/src/learning/tests/test_feature_extractor_v28.py +0 -93
  328. package/src/learning/tests/test_feedback_collector.py +0 -294
  329. package/src/learning/tests/test_learning_db.py +0 -602
  330. package/src/learning/tests/test_learning_db_v28.py +0 -110
  331. package/src/learning/tests/test_learning_init_v28.py +0 -48
  332. package/src/learning/tests/test_outcome_signals.py +0 -48
  333. package/src/learning/tests/test_project_context.py +0 -292
  334. package/src/learning/tests/test_schema_migration.py +0 -319
  335. package/src/learning/tests/test_signal_inference.py +0 -397
  336. package/src/learning/tests/test_source_quality.py +0 -351
  337. package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
  338. package/src/learning/tests/test_workflow_miner.py +0 -318
  339. package/src/learning/workflow_pattern_miner.py +0 -655
  340. package/src/lifecycle/__init__.py +0 -54
  341. package/src/lifecycle/bounded_growth.py +0 -239
  342. package/src/lifecycle/compaction_engine.py +0 -226
  343. package/src/lifecycle/lifecycle_engine.py +0 -355
  344. package/src/lifecycle/lifecycle_evaluator.py +0 -257
  345. package/src/lifecycle/lifecycle_scheduler.py +0 -130
  346. package/src/lifecycle/retention_policy.py +0 -285
  347. package/src/lifecycle/tests/test_bounded_growth.py +0 -193
  348. package/src/lifecycle/tests/test_compaction.py +0 -179
  349. package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
  350. package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
  351. package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
  352. package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
  353. package/src/lifecycle/tests/test_mcp_compact.py +0 -149
  354. package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
  355. package/src/lifecycle/tests/test_retention_policy.py +0 -162
  356. package/src/mcp_tools_v28.py +0 -281
  357. package/src/memory/__init__.py +0 -36
  358. package/src/memory/cli.py +0 -205
  359. package/src/memory/constants.py +0 -39
  360. package/src/memory/helpers.py +0 -28
  361. package/src/memory/schema.py +0 -166
  362. package/src/memory-profiles.py +0 -595
  363. package/src/memory-reset.py +0 -491
  364. package/src/memory_compression.py +0 -989
  365. package/src/memory_store_v2.py +0 -1155
  366. package/src/migrate_v1_to_v2.py +0 -629
  367. package/src/pattern_learner.py +0 -34
  368. package/src/patterns/__init__.py +0 -24
  369. package/src/patterns/analyzers.py +0 -251
  370. package/src/patterns/learner.py +0 -271
  371. package/src/patterns/scoring.py +0 -171
  372. package/src/patterns/store.py +0 -225
  373. package/src/patterns/terminology.py +0 -140
  374. package/src/provenance_tracker.py +0 -312
  375. package/src/qualixar_attribution.py +0 -139
  376. package/src/qualixar_watermark.py +0 -78
  377. package/src/query_optimizer.py +0 -511
  378. package/src/rate_limiter.py +0 -83
  379. package/src/search/__init__.py +0 -20
  380. package/src/search/cli.py +0 -77
  381. package/src/search/constants.py +0 -26
  382. package/src/search/engine.py +0 -241
  383. package/src/search/fusion.py +0 -122
  384. package/src/search/index_loader.py +0 -114
  385. package/src/search/methods.py +0 -162
  386. package/src/search_engine_v2.py +0 -401
  387. package/src/setup_validator.py +0 -482
  388. package/src/subscription_manager.py +0 -391
  389. package/src/tree/__init__.py +0 -59
  390. package/src/tree/builder.py +0 -185
  391. package/src/tree/nodes.py +0 -202
  392. package/src/tree/queries.py +0 -257
  393. package/src/tree/schema.py +0 -80
  394. package/src/tree_manager.py +0 -19
  395. package/src/trust/__init__.py +0 -45
  396. package/src/trust/constants.py +0 -66
  397. package/src/trust/queries.py +0 -157
  398. package/src/trust/schema.py +0 -95
  399. package/src/trust/scorer.py +0 -299
  400. package/src/trust/signals.py +0 -95
  401. package/src/trust_scorer.py +0 -44
  402. package/ui/app.js +0 -1588
  403. package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
  404. package/ui/js/graph-cytoscape.js +0 -1168
  405. package/ui/js/graph-d3-backup.js +0 -32
  406. package/ui/js/graph.js +0 -32
  407. package/ui_server.py +0 -286
  408. /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
  409. /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
  410. /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
  411. /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
  412. /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
  413. /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
  414. /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
  415. /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
  416. /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
  417. /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
  418. /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
  419. /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
  420. /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
  421. /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
  422. /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
  423. /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
  424. /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
  425. /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
  426. /package/{completions → ide/completions}/slm.bash +0 -0
  427. /package/{completions → ide/completions}/slm.zsh +0 -0
  428. /package/{configs → ide/configs}/cody-commands.json +0 -0
  429. /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
  430. /package/{install.ps1 → scripts/install.ps1} +0 -0
  431. /package/{install.sh → scripts/install.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)