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.
- package/LICENSE +9 -1
- package/NOTICE +63 -0
- package/README.md +165 -480
- package/bin/slm +17 -449
- package/bin/slm-npm +1 -1
- package/conftest.py +5 -0
- package/docs/api-reference.md +284 -0
- package/docs/architecture.md +149 -0
- package/docs/auto-memory.md +150 -0
- package/docs/cli-reference.md +276 -0
- package/docs/compliance.md +191 -0
- package/docs/configuration.md +182 -0
- package/docs/getting-started.md +102 -0
- package/docs/ide-setup.md +261 -0
- package/docs/mcp-tools.md +220 -0
- package/docs/migration-from-v2.md +170 -0
- package/docs/profiles.md +173 -0
- package/docs/troubleshooting.md +310 -0
- package/{configs → ide/configs}/antigravity-mcp.json +3 -3
- package/ide/configs/chatgpt-desktop-mcp.json +16 -0
- package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
- package/{configs → ide/configs}/codex-mcp.toml +4 -4
- package/{configs → ide/configs}/continue-mcp.yaml +4 -3
- package/{configs → ide/configs}/continue-skills.yaml +6 -6
- package/ide/configs/cursor-mcp.json +15 -0
- package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
- package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
- package/{configs → ide/configs}/opencode-mcp.json +2 -2
- package/{configs → ide/configs}/perplexity-mcp.json +2 -2
- package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
- package/{configs → ide/configs}/windsurf-mcp.json +3 -3
- package/{configs → ide/configs}/zed-mcp.json +2 -2
- package/{hooks → ide/hooks}/context-hook.js +9 -20
- package/ide/hooks/memory-list-skill.js +70 -0
- package/ide/hooks/memory-profile-skill.js +101 -0
- package/ide/hooks/memory-recall-skill.js +62 -0
- package/ide/hooks/memory-remember-skill.js +68 -0
- package/ide/hooks/memory-reset-skill.js +160 -0
- package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
- package/ide/integrations/langchain/README.md +106 -0
- package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
- package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
- package/ide/integrations/langchain/pyproject.toml +38 -0
- package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
- package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
- package/ide/integrations/langchain/tests/test_security.py +117 -0
- package/ide/integrations/llamaindex/README.md +81 -0
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
- package/ide/integrations/llamaindex/pyproject.toml +43 -0
- package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
- package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
- package/ide/integrations/llamaindex/tests/test_security.py +241 -0
- package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
- package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
- package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
- package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
- package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
- package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
- package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
- package/package.json +13 -22
- package/pyproject.toml +85 -0
- package/scripts/build-dmg.sh +417 -0
- package/scripts/install-skills.ps1 +334 -0
- package/scripts/postinstall.js +2 -2
- package/scripts/start-dashboard.ps1 +52 -0
- package/scripts/start-dashboard.sh +41 -0
- package/scripts/sync-wiki.ps1 +127 -0
- package/scripts/sync-wiki.sh +82 -0
- package/scripts/test-dmg.sh +161 -0
- package/scripts/test-npm-package.ps1 +252 -0
- package/scripts/test-npm-package.sh +207 -0
- package/scripts/verify-install.ps1 +294 -0
- package/scripts/verify-install.sh +266 -0
- package/src/superlocalmemory/__init__.py +0 -0
- package/src/superlocalmemory/attribution/__init__.py +9 -0
- package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
- package/src/superlocalmemory/attribution/signer.py +153 -0
- package/src/superlocalmemory/attribution/watermark.py +189 -0
- package/src/superlocalmemory/cli/__init__.py +5 -0
- package/src/superlocalmemory/cli/commands.py +245 -0
- package/src/superlocalmemory/cli/main.py +89 -0
- package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
- package/src/superlocalmemory/cli/post_install.py +99 -0
- package/src/superlocalmemory/cli/setup_wizard.py +129 -0
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +204 -0
- package/src/superlocalmemory/compliance/audit.py +314 -0
- package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
- package/src/superlocalmemory/compliance/gdpr.py +294 -0
- package/src/superlocalmemory/compliance/lifecycle.py +158 -0
- package/src/superlocalmemory/compliance/retention.py +232 -0
- package/src/superlocalmemory/compliance/scheduler.py +148 -0
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/config.py +391 -0
- package/src/superlocalmemory/core/embeddings.py +293 -0
- package/src/superlocalmemory/core/engine.py +701 -0
- package/src/superlocalmemory/core/hooks.py +65 -0
- package/src/superlocalmemory/core/maintenance.py +172 -0
- package/src/superlocalmemory/core/modes.py +140 -0
- package/src/superlocalmemory/core/profiles.py +234 -0
- package/src/superlocalmemory/core/registry.py +117 -0
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/consolidator.py +485 -0
- package/src/superlocalmemory/encoding/emotional.py +125 -0
- package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
- package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
- package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
- package/src/superlocalmemory/encoding/foresight.py +91 -0
- package/src/superlocalmemory/encoding/graph_builder.py +302 -0
- package/src/superlocalmemory/encoding/observation_builder.py +160 -0
- package/src/superlocalmemory/encoding/scene_builder.py +183 -0
- package/src/superlocalmemory/encoding/signal_inference.py +90 -0
- package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
- package/src/superlocalmemory/encoding/type_router.py +235 -0
- package/src/superlocalmemory/hooks/__init__.py +3 -0
- package/src/superlocalmemory/hooks/auto_capture.py +111 -0
- package/src/superlocalmemory/hooks/auto_recall.py +93 -0
- package/src/superlocalmemory/hooks/ide_connector.py +204 -0
- package/src/superlocalmemory/hooks/rules_engine.py +99 -0
- package/src/superlocalmemory/infra/__init__.py +3 -0
- package/src/superlocalmemory/infra/auth_middleware.py +82 -0
- package/src/superlocalmemory/infra/backup.py +317 -0
- package/src/superlocalmemory/infra/cache_manager.py +267 -0
- package/src/superlocalmemory/infra/event_bus.py +381 -0
- package/src/superlocalmemory/infra/rate_limiter.py +135 -0
- package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +172 -0
- package/src/superlocalmemory/learning/behavioral.py +490 -0
- package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
- package/src/superlocalmemory/learning/bootstrap.py +298 -0
- package/src/superlocalmemory/learning/cross_project.py +399 -0
- package/src/superlocalmemory/learning/database.py +376 -0
- package/src/superlocalmemory/learning/engagement.py +323 -0
- package/src/superlocalmemory/learning/features.py +138 -0
- package/src/superlocalmemory/learning/feedback.py +316 -0
- package/src/superlocalmemory/learning/outcomes.py +255 -0
- package/src/superlocalmemory/learning/project_context.py +366 -0
- package/src/superlocalmemory/learning/ranker.py +155 -0
- package/src/superlocalmemory/learning/source_quality.py +303 -0
- package/src/superlocalmemory/learning/workflows.py +309 -0
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +316 -0
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/fisher.py +356 -0
- package/src/superlocalmemory/math/langevin.py +398 -0
- package/src/superlocalmemory/math/sheaf.py +257 -0
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/resources.py +245 -0
- package/src/superlocalmemory/mcp/server.py +61 -0
- package/src/superlocalmemory/mcp/tools.py +18 -0
- package/src/superlocalmemory/mcp/tools_core.py +305 -0
- package/src/superlocalmemory/mcp/tools_v28.py +223 -0
- package/src/superlocalmemory/mcp/tools_v3.py +286 -0
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +295 -0
- package/src/superlocalmemory/retrieval/ann_index.py +223 -0
- package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
- package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
- package/src/superlocalmemory/retrieval/engine.py +390 -0
- package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
- package/src/superlocalmemory/retrieval/fusion.py +78 -0
- package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
- package/src/superlocalmemory/retrieval/reranker.py +154 -0
- package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
- package/src/superlocalmemory/retrieval/strategy.py +96 -0
- package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
- package/src/superlocalmemory/server/__init__.py +1 -0
- package/src/superlocalmemory/server/api.py +248 -0
- package/src/superlocalmemory/server/routes/__init__.py +4 -0
- package/src/superlocalmemory/server/routes/agents.py +107 -0
- package/src/superlocalmemory/server/routes/backup.py +91 -0
- package/src/superlocalmemory/server/routes/behavioral.py +127 -0
- package/src/superlocalmemory/server/routes/compliance.py +160 -0
- package/src/superlocalmemory/server/routes/data_io.py +188 -0
- package/src/superlocalmemory/server/routes/events.py +183 -0
- package/src/superlocalmemory/server/routes/helpers.py +85 -0
- package/src/superlocalmemory/server/routes/learning.py +273 -0
- package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
- package/src/superlocalmemory/server/routes/memories.py +399 -0
- package/src/superlocalmemory/server/routes/profiles.py +219 -0
- package/src/superlocalmemory/server/routes/stats.py +346 -0
- package/src/superlocalmemory/server/routes/v3_api.py +365 -0
- package/src/superlocalmemory/server/routes/ws.py +82 -0
- package/src/superlocalmemory/server/security_middleware.py +57 -0
- package/src/superlocalmemory/server/ui.py +245 -0
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/access_control.py +182 -0
- package/src/superlocalmemory/storage/database.py +594 -0
- package/src/superlocalmemory/storage/migrations.py +303 -0
- package/src/superlocalmemory/storage/models.py +406 -0
- package/src/superlocalmemory/storage/schema.py +726 -0
- package/src/superlocalmemory/storage/v2_migrator.py +317 -0
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +130 -0
- package/src/superlocalmemory/trust/provenance.py +124 -0
- package/src/superlocalmemory/trust/scorer.py +347 -0
- package/src/superlocalmemory/trust/signals.py +153 -0
- package/ui/index.html +278 -5
- package/ui/js/auto-settings.js +70 -0
- package/ui/js/dashboard.js +90 -0
- package/ui/js/fact-detail.js +92 -0
- package/ui/js/feedback.js +2 -2
- package/ui/js/ide-status.js +102 -0
- package/ui/js/math-health.js +98 -0
- package/ui/js/recall-lab.js +127 -0
- package/ui/js/settings.js +2 -2
- package/ui/js/trust-dashboard.js +73 -0
- package/api_server.py +0 -724
- package/bin/aider-smart +0 -72
- package/bin/superlocalmemoryv2-learning +0 -4
- package/bin/superlocalmemoryv2-list +0 -3
- package/bin/superlocalmemoryv2-patterns +0 -4
- package/bin/superlocalmemoryv2-profile +0 -3
- package/bin/superlocalmemoryv2-recall +0 -3
- package/bin/superlocalmemoryv2-remember +0 -3
- package/bin/superlocalmemoryv2-reset +0 -3
- package/bin/superlocalmemoryv2-status +0 -3
- package/configs/chatgpt-desktop-mcp.json +0 -16
- package/configs/cursor-mcp.json +0 -15
- package/hooks/memory-list-skill.js +0 -139
- package/hooks/memory-profile-skill.js +0 -273
- package/hooks/memory-recall-skill.js +0 -114
- package/hooks/memory-remember-skill.js +0 -127
- package/hooks/memory-reset-skill.js +0 -274
- package/mcp_server.py +0 -1808
- package/requirements-core.txt +0 -22
- package/requirements-learning.txt +0 -12
- package/requirements.txt +0 -12
- package/src/agent_registry.py +0 -411
- package/src/auth_middleware.py +0 -61
- package/src/auto_backup.py +0 -459
- package/src/behavioral/__init__.py +0 -49
- package/src/behavioral/behavioral_listener.py +0 -203
- package/src/behavioral/behavioral_patterns.py +0 -275
- package/src/behavioral/cross_project_transfer.py +0 -206
- package/src/behavioral/outcome_inference.py +0 -194
- package/src/behavioral/outcome_tracker.py +0 -193
- package/src/behavioral/tests/__init__.py +0 -4
- package/src/behavioral/tests/test_behavioral_integration.py +0 -108
- package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
- package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
- package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
- package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
- package/src/behavioral/tests/test_outcome_inference.py +0 -107
- package/src/behavioral/tests/test_outcome_tracker.py +0 -96
- package/src/cache_manager.py +0 -518
- package/src/compliance/__init__.py +0 -48
- package/src/compliance/abac_engine.py +0 -149
- package/src/compliance/abac_middleware.py +0 -116
- package/src/compliance/audit_db.py +0 -215
- package/src/compliance/audit_logger.py +0 -148
- package/src/compliance/retention_manager.py +0 -289
- package/src/compliance/retention_scheduler.py +0 -186
- package/src/compliance/tests/__init__.py +0 -4
- package/src/compliance/tests/test_abac_enforcement.py +0 -95
- package/src/compliance/tests/test_abac_engine.py +0 -124
- package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
- package/src/compliance/tests/test_audit_db.py +0 -123
- package/src/compliance/tests/test_audit_logger.py +0 -98
- package/src/compliance/tests/test_mcp_audit.py +0 -128
- package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
- package/src/compliance/tests/test_retention_manager.py +0 -131
- package/src/compliance/tests/test_retention_scheduler.py +0 -99
- package/src/compression/__init__.py +0 -25
- package/src/compression/cli.py +0 -150
- package/src/compression/cold_storage.py +0 -217
- package/src/compression/config.py +0 -72
- package/src/compression/orchestrator.py +0 -133
- package/src/compression/tier2_compressor.py +0 -228
- package/src/compression/tier3_compressor.py +0 -153
- package/src/compression/tier_classifier.py +0 -148
- package/src/db_connection_manager.py +0 -536
- package/src/embedding_engine.py +0 -63
- package/src/embeddings/__init__.py +0 -47
- package/src/embeddings/cache.py +0 -70
- package/src/embeddings/cli.py +0 -113
- package/src/embeddings/constants.py +0 -47
- package/src/embeddings/database.py +0 -91
- package/src/embeddings/engine.py +0 -247
- package/src/embeddings/model_loader.py +0 -145
- package/src/event_bus.py +0 -562
- package/src/graph/__init__.py +0 -36
- package/src/graph/build_helpers.py +0 -74
- package/src/graph/cli.py +0 -87
- package/src/graph/cluster_builder.py +0 -188
- package/src/graph/cluster_summary.py +0 -148
- package/src/graph/constants.py +0 -47
- package/src/graph/edge_builder.py +0 -162
- package/src/graph/entity_extractor.py +0 -95
- package/src/graph/graph_core.py +0 -226
- package/src/graph/graph_search.py +0 -231
- package/src/graph/hierarchical.py +0 -207
- package/src/graph/schema.py +0 -99
- package/src/graph_engine.py +0 -52
- package/src/hnsw_index.py +0 -628
- package/src/hybrid_search.py +0 -46
- package/src/learning/__init__.py +0 -217
- package/src/learning/adaptive_ranker.py +0 -682
- package/src/learning/bootstrap/__init__.py +0 -69
- package/src/learning/bootstrap/constants.py +0 -93
- package/src/learning/bootstrap/db_queries.py +0 -316
- package/src/learning/bootstrap/sampling.py +0 -82
- package/src/learning/bootstrap/text_utils.py +0 -71
- package/src/learning/cross_project_aggregator.py +0 -857
- package/src/learning/db/__init__.py +0 -40
- package/src/learning/db/constants.py +0 -44
- package/src/learning/db/schema.py +0 -279
- package/src/learning/engagement_tracker.py +0 -628
- package/src/learning/feature_extractor.py +0 -708
- package/src/learning/feedback_collector.py +0 -806
- package/src/learning/learning_db.py +0 -915
- package/src/learning/project_context_manager.py +0 -572
- package/src/learning/ranking/__init__.py +0 -33
- package/src/learning/ranking/constants.py +0 -84
- package/src/learning/ranking/helpers.py +0 -278
- package/src/learning/source_quality_scorer.py +0 -676
- package/src/learning/synthetic_bootstrap.py +0 -755
- package/src/learning/tests/test_adaptive_ranker.py +0 -325
- package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
- package/src/learning/tests/test_aggregator.py +0 -306
- package/src/learning/tests/test_auto_retrain_v28.py +0 -35
- package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
- package/src/learning/tests/test_feature_extractor_v28.py +0 -93
- package/src/learning/tests/test_feedback_collector.py +0 -294
- package/src/learning/tests/test_learning_db.py +0 -602
- package/src/learning/tests/test_learning_db_v28.py +0 -110
- package/src/learning/tests/test_learning_init_v28.py +0 -48
- package/src/learning/tests/test_outcome_signals.py +0 -48
- package/src/learning/tests/test_project_context.py +0 -292
- package/src/learning/tests/test_schema_migration.py +0 -319
- package/src/learning/tests/test_signal_inference.py +0 -397
- package/src/learning/tests/test_source_quality.py +0 -351
- package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
- package/src/learning/tests/test_workflow_miner.py +0 -318
- package/src/learning/workflow_pattern_miner.py +0 -655
- package/src/lifecycle/__init__.py +0 -54
- package/src/lifecycle/bounded_growth.py +0 -239
- package/src/lifecycle/compaction_engine.py +0 -226
- package/src/lifecycle/lifecycle_engine.py +0 -355
- package/src/lifecycle/lifecycle_evaluator.py +0 -257
- package/src/lifecycle/lifecycle_scheduler.py +0 -130
- package/src/lifecycle/retention_policy.py +0 -285
- package/src/lifecycle/tests/test_bounded_growth.py +0 -193
- package/src/lifecycle/tests/test_compaction.py +0 -179
- package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
- package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
- package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
- package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
- package/src/lifecycle/tests/test_mcp_compact.py +0 -149
- package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
- package/src/lifecycle/tests/test_retention_policy.py +0 -162
- package/src/mcp_tools_v28.py +0 -281
- package/src/memory/__init__.py +0 -36
- package/src/memory/cli.py +0 -205
- package/src/memory/constants.py +0 -39
- package/src/memory/helpers.py +0 -28
- package/src/memory/schema.py +0 -166
- package/src/memory-profiles.py +0 -595
- package/src/memory-reset.py +0 -491
- package/src/memory_compression.py +0 -989
- package/src/memory_store_v2.py +0 -1155
- package/src/migrate_v1_to_v2.py +0 -629
- package/src/pattern_learner.py +0 -34
- package/src/patterns/__init__.py +0 -24
- package/src/patterns/analyzers.py +0 -251
- package/src/patterns/learner.py +0 -271
- package/src/patterns/scoring.py +0 -171
- package/src/patterns/store.py +0 -225
- package/src/patterns/terminology.py +0 -140
- package/src/provenance_tracker.py +0 -312
- package/src/qualixar_attribution.py +0 -139
- package/src/qualixar_watermark.py +0 -78
- package/src/query_optimizer.py +0 -511
- package/src/rate_limiter.py +0 -83
- package/src/search/__init__.py +0 -20
- package/src/search/cli.py +0 -77
- package/src/search/constants.py +0 -26
- package/src/search/engine.py +0 -241
- package/src/search/fusion.py +0 -122
- package/src/search/index_loader.py +0 -114
- package/src/search/methods.py +0 -162
- package/src/search_engine_v2.py +0 -401
- package/src/setup_validator.py +0 -482
- package/src/subscription_manager.py +0 -391
- package/src/tree/__init__.py +0 -59
- package/src/tree/builder.py +0 -185
- package/src/tree/nodes.py +0 -202
- package/src/tree/queries.py +0 -257
- package/src/tree/schema.py +0 -80
- package/src/tree_manager.py +0 -19
- package/src/trust/__init__.py +0 -45
- package/src/trust/constants.py +0 -66
- package/src/trust/queries.py +0 -157
- package/src/trust/schema.py +0 -95
- package/src/trust/scorer.py +0 -299
- package/src/trust/signals.py +0 -95
- package/src/trust_scorer.py +0 -44
- package/ui/app.js +0 -1588
- package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
- package/ui/js/graph-cytoscape.js +0 -1168
- package/ui/js/graph-d3-backup.js +0 -32
- package/ui/js/graph.js +0 -32
- package/ui_server.py +0 -286
- /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
- /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
- /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
- /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
- /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
- /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
- /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
- /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
- /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
- /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
- /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
- /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
- /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
- /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
- /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
- /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
- /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
- /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
- /package/{completions → ide/completions}/slm.bash +0 -0
- /package/{completions → ide/completions}/slm.zsh +0 -0
- /package/{configs → ide/configs}/cody-commands.json +0 -0
- /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
- /package/{install.ps1 → scripts/install.ps1} +0 -0
- /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
|