superlocalmemory 2.8.6 → 3.0.1

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 +62 -48
  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
@@ -0,0 +1,245 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """CLI command implementations.
6
+
7
+ Each function handles one CLI command. Dispatch routes by name.
8
+
9
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import sys
15
+ from argparse import Namespace
16
+
17
+
18
+ def dispatch(args: Namespace) -> None:
19
+ """Route CLI command to the appropriate handler."""
20
+ handlers = {
21
+ "setup": cmd_setup,
22
+ "mode": cmd_mode,
23
+ "provider": cmd_provider,
24
+ "connect": cmd_connect,
25
+ "migrate": cmd_migrate,
26
+ "remember": cmd_remember,
27
+ "recall": cmd_recall,
28
+ "forget": cmd_forget,
29
+ "status": cmd_status,
30
+ "health": cmd_health,
31
+ "trace": cmd_trace,
32
+ "profile": cmd_profile,
33
+ }
34
+ handler = handlers.get(args.command)
35
+ if handler:
36
+ handler(args)
37
+ else:
38
+ print(f"Unknown command: {args.command}")
39
+ sys.exit(1)
40
+
41
+
42
+ def cmd_setup(_args: Namespace) -> None:
43
+ """Run the interactive setup wizard."""
44
+ from superlocalmemory.cli.setup_wizard import run_wizard
45
+
46
+ run_wizard()
47
+
48
+
49
+ def cmd_mode(args: Namespace) -> None:
50
+ """Get or set the operating mode."""
51
+ from superlocalmemory.core.config import SLMConfig
52
+ from superlocalmemory.storage.models import Mode
53
+
54
+ config = SLMConfig.load()
55
+
56
+ if args.value:
57
+ updated = SLMConfig.for_mode(
58
+ Mode(args.value),
59
+ llm_provider=config.llm.provider,
60
+ llm_model=config.llm.model,
61
+ llm_api_key=config.llm.api_key,
62
+ llm_api_base=config.llm.api_base,
63
+ )
64
+ updated.save()
65
+ print(f"Mode set to: {args.value.upper()}")
66
+ else:
67
+ print(f"Current mode: {config.mode.value.upper()}")
68
+
69
+
70
+ def cmd_provider(args: Namespace) -> None:
71
+ """Get or set the LLM provider."""
72
+ from superlocalmemory.core.config import SLMConfig
73
+
74
+ config = SLMConfig.load()
75
+
76
+ if args.action == "set":
77
+ from superlocalmemory.cli.setup_wizard import configure_provider
78
+
79
+ configure_provider(config)
80
+ else:
81
+ print(f"Provider: {config.llm.provider or 'none (Mode A)'}")
82
+ if config.llm.model:
83
+ print(f"Model: {config.llm.model}")
84
+
85
+
86
+ def cmd_connect(args: Namespace) -> None:
87
+ """Configure IDE integrations."""
88
+ from superlocalmemory.hooks.ide_connector import IDEConnector
89
+
90
+ connector = IDEConnector()
91
+ if getattr(args, "list", False):
92
+ status = connector.get_status()
93
+ for s in status:
94
+ mark = "[+]" if s["installed"] else "[-]"
95
+ print(f" {mark} {s['name']:20s} {s['config_path']}")
96
+ return
97
+ if getattr(args, "ide", None):
98
+ success = connector.connect(args.ide)
99
+ print(f"{'Connected' if success else 'Failed'}: {args.ide}")
100
+ else:
101
+ results = connector.connect_all()
102
+ for ide_id, ide_status in results.items():
103
+ print(f" {ide_id}: {ide_status}")
104
+
105
+
106
+ def cmd_migrate(args: Namespace) -> None:
107
+ """Run V2 to V3 migration."""
108
+ from superlocalmemory.cli.migrate_cmd import cmd_migrate as _migrate
109
+
110
+ _migrate(args)
111
+
112
+
113
+ def cmd_remember(args: Namespace) -> None:
114
+ """Store a memory via the engine."""
115
+ from superlocalmemory.core.config import SLMConfig
116
+ from superlocalmemory.core.engine import MemoryEngine
117
+
118
+ config = SLMConfig.load()
119
+ engine = MemoryEngine(config)
120
+ engine.initialize()
121
+
122
+ metadata = {"tags": args.tags} if args.tags else {}
123
+ fact_ids = engine.store(args.content, metadata=metadata)
124
+ print(f"Stored {len(fact_ids)} facts.")
125
+
126
+
127
+ def cmd_recall(args: Namespace) -> None:
128
+ """Search memories via the engine."""
129
+ from superlocalmemory.core.config import SLMConfig
130
+ from superlocalmemory.core.engine import MemoryEngine
131
+
132
+ config = SLMConfig.load()
133
+ engine = MemoryEngine(config)
134
+ engine.initialize()
135
+
136
+ response = engine.recall(args.query, limit=args.limit)
137
+ if not response.results:
138
+ print("No memories found.")
139
+ return
140
+ for i, r in enumerate(response.results, 1):
141
+ print(f" {i}. [{r.score:.2f}] {r.fact.content[:120]}")
142
+
143
+
144
+ def cmd_forget(args: Namespace) -> None:
145
+ """Delete memories matching a query."""
146
+ from superlocalmemory.core.engine import MemoryEngine
147
+ from superlocalmemory.core.config import SLMConfig
148
+
149
+ config = SLMConfig.load()
150
+ engine = MemoryEngine(config)
151
+ facts = engine._db.get_all_facts(engine.profile_id)
152
+ query_lower = args.query.lower()
153
+ matches = [f for f in facts if query_lower in f.content.lower()]
154
+ if not matches:
155
+ print(f"No memories matching '{args.query}'")
156
+ return
157
+ print(f"Found {len(matches)} matching memories:")
158
+ for f in matches[:10]:
159
+ print(f" - {f.fact_id[:8]}... {f.content[:80]}")
160
+ confirm = input(f"Delete {len(matches)} memories? [y/N] ").strip().lower()
161
+ if confirm in ("y", "yes"):
162
+ for f in matches:
163
+ engine._db.delete_fact(f.fact_id)
164
+ print(f"Deleted {len(matches)} memories.")
165
+ else:
166
+ print("Cancelled.")
167
+
168
+
169
+ def cmd_status(_args: Namespace) -> None:
170
+ """Show system status."""
171
+ from superlocalmemory.core.config import SLMConfig
172
+
173
+ config = SLMConfig.load()
174
+ print("SuperLocalMemory V3")
175
+ print(f" Mode: {config.mode.value.upper()}")
176
+ print(f" Provider: {config.llm.provider or 'none'}")
177
+ print(f" Base dir: {config.base_dir}")
178
+ print(f" Database: {config.db_path}")
179
+ if config.db_path.exists():
180
+ size_mb = round(config.db_path.stat().st_size / 1024 / 1024, 2)
181
+ print(f" DB size: {size_mb} MB")
182
+
183
+
184
+ def cmd_health(_args: Namespace) -> None:
185
+ """Show math layer health status."""
186
+ from superlocalmemory.core.engine import MemoryEngine
187
+ from superlocalmemory.core.config import SLMConfig
188
+
189
+ config = SLMConfig.load()
190
+ engine = MemoryEngine(config)
191
+ facts = engine._db.get_all_facts(engine.profile_id)
192
+ fisher_count = sum(1 for f in facts if f.fisher_mean is not None)
193
+ langevin_count = sum(1 for f in facts if f.langevin_position is not None)
194
+ print("Math Layer Health:")
195
+ print(f" Total facts: {len(facts)}")
196
+ print(f" Fisher-Rao indexed: {fisher_count}/{len(facts)}")
197
+ print(f" Langevin positioned: {langevin_count}/{len(facts)}")
198
+ print(f" Mode: {config.mode.value.upper()}")
199
+
200
+
201
+ def cmd_trace(args: Namespace) -> None:
202
+ """Recall with per-channel score breakdown."""
203
+ from superlocalmemory.core.engine import MemoryEngine
204
+ from superlocalmemory.core.config import SLMConfig
205
+
206
+ config = SLMConfig.load()
207
+ engine = MemoryEngine(config)
208
+ response = engine.recall(args.query, limit=5)
209
+ print(f"Query: {args.query}")
210
+ print(f"Type: {response.query_type} | Time: {response.retrieval_time_ms:.0f}ms")
211
+ print(f"Results: {len(response.results)}")
212
+ for i, r in enumerate(response.results, 1):
213
+ print(f"\n {i}. [{r.score:.3f}] {r.fact.content[:100]}")
214
+ if hasattr(r, "channel_scores") and r.channel_scores:
215
+ for ch, sc in r.channel_scores.items():
216
+ print(f" {ch}: {sc:.3f}")
217
+
218
+
219
+ def cmd_profile(args: Namespace) -> None:
220
+ """Profile management (list, switch, create)."""
221
+ from superlocalmemory.core.config import SLMConfig
222
+ from superlocalmemory.storage.database import DatabaseManager
223
+ from superlocalmemory.storage import schema
224
+
225
+ config = SLMConfig.load()
226
+ db = DatabaseManager(config.db_path)
227
+ db.initialize(schema)
228
+
229
+ if args.action == "list":
230
+ rows = db.execute("SELECT profile_id, name FROM profiles")
231
+ print("Profiles:")
232
+ for r in rows:
233
+ d = dict(r)
234
+ print(f" - {d['profile_id']}: {d.get('name', '')}")
235
+ elif args.action == "switch":
236
+ config.active_profile = args.name
237
+ config.save()
238
+ print(f"Switched to profile: {args.name}")
239
+ elif args.action == "create":
240
+ from superlocalmemory.storage.models import _new_id
241
+ db.execute(
242
+ "INSERT OR IGNORE INTO profiles (profile_id, name) VALUES (?, ?)",
243
+ (args.name, args.name),
244
+ )
245
+ print(f"Created profile: {args.name}")
@@ -0,0 +1,89 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3 — CLI entry point.
6
+
7
+ Usage: slm <command> [options]
8
+
9
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import argparse
15
+ import sys
16
+
17
+
18
+ def main() -> None:
19
+ """Parse CLI arguments and dispatch to command handlers."""
20
+ parser = argparse.ArgumentParser(prog="slm", description="SuperLocalMemory V3")
21
+ sub = parser.add_subparsers(dest="command")
22
+
23
+ # Setup
24
+ sub.add_parser("setup", help="Run setup wizard")
25
+
26
+ # Mode
27
+ mode_p = sub.add_parser("mode", help="Get or set operating mode")
28
+ mode_p.add_argument(
29
+ "value", nargs="?", choices=["a", "b", "c"], help="Mode to set",
30
+ )
31
+
32
+ # Provider
33
+ provider_p = sub.add_parser("provider", help="Get or set LLM provider")
34
+ provider_p.add_argument(
35
+ "action", nargs="?", choices=["set"], help="Action",
36
+ )
37
+
38
+ # Connect
39
+ connect_p = sub.add_parser("connect", help="Configure IDE integrations")
40
+ connect_p.add_argument("ide", nargs="?", help="Specific IDE to configure")
41
+ connect_p.add_argument(
42
+ "--list", action="store_true", help="List all supported IDEs",
43
+ )
44
+
45
+ # Migrate
46
+ migrate_p = sub.add_parser("migrate", help="Migrate from V2")
47
+ migrate_p.add_argument(
48
+ "--rollback", action="store_true", help="Rollback migration",
49
+ )
50
+
51
+ # Memory ops
52
+ remember_p = sub.add_parser("remember", help="Store a memory")
53
+ remember_p.add_argument("content", help="Content to remember")
54
+ remember_p.add_argument("--tags", default="", help="Comma-separated tags")
55
+
56
+ recall_p = sub.add_parser("recall", help="Search memories")
57
+ recall_p.add_argument("query", help="Search query")
58
+ recall_p.add_argument("--limit", type=int, default=10, help="Max results")
59
+
60
+ forget_p = sub.add_parser("forget", help="Delete memories matching query")
61
+ forget_p.add_argument("query", help="Query to match")
62
+
63
+ # Status & diagnostics
64
+ sub.add_parser("status", help="System status")
65
+ sub.add_parser("health", help="Math layer health")
66
+
67
+ trace_p = sub.add_parser("trace", help="Recall with channel breakdown")
68
+ trace_p.add_argument("query", help="Search query")
69
+
70
+ # Profiles
71
+ profile_p = sub.add_parser("profile", help="Profile management")
72
+ profile_p.add_argument(
73
+ "action", choices=["list", "switch", "create"], help="Action",
74
+ )
75
+ profile_p.add_argument("name", nargs="?", help="Profile name")
76
+
77
+ args = parser.parse_args()
78
+
79
+ if not args.command:
80
+ parser.print_help()
81
+ sys.exit(0)
82
+
83
+ from superlocalmemory.cli.commands import dispatch
84
+
85
+ dispatch(args)
86
+
87
+
88
+ if __name__ == "__main__":
89
+ main()
@@ -0,0 +1,55 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """Migration CLI command implementation."""
6
+
7
+ from __future__ import annotations
8
+
9
+
10
+ def cmd_migrate(args):
11
+ """Run V2 to V3 migration or rollback."""
12
+ from superlocalmemory.storage.v2_migrator import V2Migrator
13
+
14
+ migrator = V2Migrator()
15
+
16
+ if getattr(args, "rollback", False):
17
+ print("Rolling back V3 migration...")
18
+ result = migrator.rollback()
19
+ if result.get("success"):
20
+ for step in result.get("steps", []):
21
+ print(f" [ok] {step}")
22
+ print("Rollback complete. V2 restored.")
23
+ else:
24
+ print(f"Rollback failed: {result.get('error', 'unknown')}")
25
+ return
26
+
27
+ if not migrator.detect_v2():
28
+ print("No V2 installation found. Nothing to migrate.")
29
+ return
30
+
31
+ if migrator.is_already_migrated():
32
+ print("Already migrated to V3.")
33
+ return
34
+
35
+ stats = migrator.get_v2_stats()
36
+ print("V2 installation found:")
37
+ print(f" Memories: {stats.get('memory_count', 'unknown')}")
38
+ print(f" Size: {stats.get('db_size_mb', '?')} MB")
39
+ print()
40
+
41
+ import sys
42
+ if sys.stdin.isatty():
43
+ confirm = input("Proceed with migration? [Y/n] ").strip().lower()
44
+ if confirm not in ("", "y", "yes"):
45
+ print("Migration cancelled.")
46
+ return
47
+
48
+ result = migrator.migrate()
49
+ if result.get("success"):
50
+ for step in result.get("steps", []):
51
+ print(f" [ok] {step}")
52
+ print()
53
+ print("Migration complete!")
54
+ else:
55
+ print(f"Migration failed: {result.get('error', 'unknown')}")
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """Post-install script for npm package.
6
+
7
+ Runs after `npm install -g superlocalmemory`. Detects V2 installations,
8
+ prompts for migration, and runs the setup wizard for new users.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import sys
14
+ from pathlib import Path
15
+
16
+
17
+ def run_post_install():
18
+ """Main post-install entry point."""
19
+ print()
20
+ print("SuperLocalMemory V3")
21
+ print("=" * 30)
22
+ print()
23
+
24
+ # Step 1: Check for V2 installation
25
+ from superlocalmemory.storage.v2_migrator import V2Migrator
26
+
27
+ migrator = V2Migrator()
28
+
29
+ if migrator.detect_v2() and not migrator.is_already_migrated():
30
+ _handle_v2_upgrade(migrator)
31
+ else:
32
+ _handle_fresh_install()
33
+
34
+
35
+ def _handle_v2_upgrade(migrator):
36
+ """Handle upgrade from V2."""
37
+ stats = migrator.get_v2_stats()
38
+
39
+ print("Existing V2 installation detected!")
40
+ print(f" Database: {stats.get('db_path', '~/.claude-memory/memory.db')}")
41
+ print(f" Memories: {stats.get('memory_count', 'unknown')}")
42
+ print(f" Profiles: {stats.get('profile_count', 1)}")
43
+ print()
44
+ print("V3 requires a one-time migration to upgrade your database.")
45
+ print("Your data will be preserved. A backup is created automatically.")
46
+ print("You can rollback anytime within 30 days.")
47
+ print()
48
+
49
+ choice = input("Run migration now? [Y/n]: ").strip().lower()
50
+
51
+ if choice in ("", "y", "yes"):
52
+ print()
53
+ print("Migrating...")
54
+ result = migrator.migrate()
55
+
56
+ if result.get("success"):
57
+ print()
58
+ for step in result.get("steps", []):
59
+ print(f" [ok] {step}")
60
+ print()
61
+ print("Migration complete!")
62
+ print(f" V3 database: {result.get('v3_db', '')}")
63
+ print(f" Backup: {result.get('backup_db', '')}")
64
+ print()
65
+ # Run setup wizard after migration
66
+ _run_setup()
67
+ else:
68
+ print(f"Migration failed: {result.get('error', 'unknown')}")
69
+ print("Your V2 data is untouched. Run `slm migrate` to try again.")
70
+ sys.exit(1)
71
+ else:
72
+ print()
73
+ print("Migration skipped. Run `slm migrate` when ready.")
74
+ print("Note: V3 features are unavailable until you migrate.")
75
+
76
+
77
+ def _handle_fresh_install():
78
+ """Handle fresh install (no V2 detected)."""
79
+ from superlocalmemory.storage.v2_migrator import V2Migrator
80
+
81
+ migrator = V2Migrator()
82
+
83
+ if migrator.is_already_migrated():
84
+ print("V3 already configured. Run `slm setup` to reconfigure.")
85
+ return
86
+
87
+ print("Welcome! Let's set up SuperLocalMemory V3.")
88
+ _run_setup()
89
+
90
+
91
+ def _run_setup():
92
+ """Run the interactive setup wizard."""
93
+ from superlocalmemory.cli.setup_wizard import run_wizard
94
+
95
+ run_wizard()
96
+
97
+
98
+ if __name__ == "__main__":
99
+ run_post_install()
@@ -0,0 +1,129 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """Interactive setup wizard for first-time configuration.
6
+
7
+ Guides new users through mode selection and provider setup.
8
+
9
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import os
15
+ import shutil
16
+
17
+
18
+ def run_wizard() -> None:
19
+ """Run the interactive setup wizard."""
20
+ print()
21
+ print("SuperLocalMemory V3 — First Time Setup")
22
+ print("=" * 40)
23
+ print()
24
+ print("Choose your operating mode:")
25
+ print()
26
+ print(" [A] Local Guardian (default)")
27
+ print(" Zero cloud. Zero LLM. Your data never leaves your machine.")
28
+ print(" EU AI Act compliant. Works immediately.")
29
+ print()
30
+ print(" [B] Smart Local")
31
+ print(" Local LLM via Ollama for answer synthesis.")
32
+ print(" Still private — nothing leaves your machine.")
33
+ print()
34
+ print(" [C] Full Power")
35
+ print(" Cloud LLM for best accuracy (~78% on LoCoMo).")
36
+ print(" Requires: API key from a supported provider.")
37
+ print()
38
+
39
+ choice = input("Select mode [A/B/C] (default: A): ").strip().lower() or "a"
40
+
41
+ if choice not in ("a", "b", "c"):
42
+ print(f"Invalid choice: {choice}. Using Mode A.")
43
+ choice = "a"
44
+
45
+ from superlocalmemory.core.config import SLMConfig
46
+ from superlocalmemory.storage.models import Mode
47
+
48
+ if choice == "a":
49
+ config = SLMConfig.for_mode(Mode.A)
50
+ config.save()
51
+ print()
52
+ print("Mode A configured. Zero cloud, zero LLM.")
53
+ print(f"Config saved to: {config.base_dir / 'config.json'}")
54
+
55
+ elif choice == "b":
56
+ config = SLMConfig.for_mode(Mode.B)
57
+ print()
58
+ print("Checking for Ollama...")
59
+ if shutil.which("ollama"):
60
+ print(" Ollama found!")
61
+ else:
62
+ print(" Ollama not found. Install it from https://ollama.ai")
63
+ print(" After installing, run: ollama pull llama3.2")
64
+ config.save()
65
+ print(f"Config saved to: {config.base_dir / 'config.json'}")
66
+
67
+ elif choice == "c":
68
+ config = SLMConfig.for_mode(Mode.C)
69
+ configure_provider(config)
70
+
71
+ print()
72
+ print("Ready! Your AI now remembers you.")
73
+ print()
74
+
75
+
76
+ def configure_provider(config: object) -> None:
77
+ """Configure LLM provider for Mode C.
78
+
79
+ Args:
80
+ config: An SLMConfig instance (typed as object to avoid circular import
81
+ at module level; actual type checked at runtime).
82
+ """
83
+ from superlocalmemory.core.config import SLMConfig
84
+ from superlocalmemory.storage.models import Mode
85
+
86
+ presets = SLMConfig.provider_presets()
87
+
88
+ print()
89
+ print("Choose your LLM provider:")
90
+ print()
91
+ providers = list(presets.keys())
92
+ for i, name in enumerate(providers, 1):
93
+ preset = presets[name]
94
+ print(f" [{i}] {name.capitalize()} — {preset['model']}")
95
+ print()
96
+
97
+ idx = input(f"Select provider [1-{len(providers)}]: ").strip()
98
+ try:
99
+ provider_name = providers[int(idx) - 1]
100
+ except (ValueError, IndexError):
101
+ print("Invalid choice. Using OpenAI.")
102
+ provider_name = "openai"
103
+
104
+ preset = presets[provider_name]
105
+
106
+ # Resolve API key from environment or prompt
107
+ env_key = preset.get("env_key", "")
108
+ api_key = ""
109
+ if env_key:
110
+ existing = os.environ.get(env_key, "")
111
+ if existing:
112
+ print(f" Found {env_key} in environment.")
113
+ api_key = existing
114
+ else:
115
+ api_key = input(
116
+ f" Enter your {provider_name.capitalize()} API key: ",
117
+ ).strip()
118
+
119
+ updated = SLMConfig.for_mode(
120
+ Mode.C,
121
+ llm_provider=provider_name,
122
+ llm_model=preset["model"],
123
+ llm_api_key=api_key,
124
+ llm_api_base=preset["base_url"],
125
+ )
126
+ updated.save()
127
+ print(f" Provider: {provider_name}")
128
+ print(f" Model: {preset['model']}")
129
+ print(f"Config saved to: {updated.base_dir / 'config.json'}")
File without changes