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.
- package/LICENSE +9 -1
- package/NOTICE +63 -0
- package/README.md +165 -480
- package/bin/slm +17 -449
- package/bin/slm-npm +62 -48
- 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
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""SuperLocalMemory V2 - Tests for v2.8 Schema Migration
|
|
5
|
-
|
|
6
|
-
Tests that the v2.8.0 lifecycle + access control columns are added
|
|
7
|
-
via backward-compatible ALTER TABLE migration in memory_store_v2.py.
|
|
8
|
-
"""
|
|
9
|
-
import json
|
|
10
|
-
import sqlite3
|
|
11
|
-
import sys
|
|
12
|
-
import importlib
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
|
|
15
|
-
import pytest
|
|
16
|
-
|
|
17
|
-
# Ensure src/ is importable AND takes precedence over ~/.claude-memory/
|
|
18
|
-
# (the installed production copy). Other test modules in this suite may
|
|
19
|
-
# cause ~/.claude-memory to appear on sys.path earlier, so we must ensure
|
|
20
|
-
# our development src/ directory wins.
|
|
21
|
-
SRC_DIR = Path(__file__).resolve().parent.parent.parent # src/
|
|
22
|
-
_src_str = str(SRC_DIR)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _import_memory_store_v2():
|
|
26
|
-
"""
|
|
27
|
-
Import MemoryStoreV2 from the development src/ directory.
|
|
28
|
-
|
|
29
|
-
When running in a full test suite, other test modules may cause
|
|
30
|
-
~/.claude-memory/ (the installed production copy) to appear on sys.path
|
|
31
|
-
before src/. This helper ensures we always load from the correct location
|
|
32
|
-
by temporarily prioritizing src/ and invalidating any stale cached import.
|
|
33
|
-
"""
|
|
34
|
-
# Ensure src/ is at position 0
|
|
35
|
-
if sys.path[0] != _src_str:
|
|
36
|
-
if _src_str in sys.path:
|
|
37
|
-
sys.path.remove(_src_str)
|
|
38
|
-
sys.path.insert(0, _src_str)
|
|
39
|
-
|
|
40
|
-
# If memory_store_v2 was already imported from a different location
|
|
41
|
-
# (e.g., ~/.claude-memory/), force a reimport from src/
|
|
42
|
-
mod = sys.modules.get("memory_store_v2")
|
|
43
|
-
if mod is not None and hasattr(mod, "__file__"):
|
|
44
|
-
mod_path = str(Path(mod.__file__).resolve().parent)
|
|
45
|
-
if mod_path != _src_str:
|
|
46
|
-
del sys.modules["memory_store_v2"]
|
|
47
|
-
# Also clear any cached submodule imports that may hold refs
|
|
48
|
-
for key in list(sys.modules.keys()):
|
|
49
|
-
m = sys.modules[key]
|
|
50
|
-
if m is not None and hasattr(m, "__file__") and m.__file__ and "memory_store_v2" in str(m.__file__):
|
|
51
|
-
pass # memory_store_v2 is not a package, no submodules
|
|
52
|
-
|
|
53
|
-
from memory_store_v2 import MemoryStoreV2
|
|
54
|
-
return MemoryStoreV2
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# ---------------------------------------------------------------------------
|
|
58
|
-
# Helper — create a v2.7.6 schema database (WITHOUT lifecycle columns)
|
|
59
|
-
# ---------------------------------------------------------------------------
|
|
60
|
-
|
|
61
|
-
def _create_v276_database(db_path: Path) -> None:
|
|
62
|
-
"""
|
|
63
|
-
Create a minimal memories table matching the v2.7.6 schema.
|
|
64
|
-
This deliberately omits the v2.8 lifecycle columns so the migration
|
|
65
|
-
can be verified.
|
|
66
|
-
"""
|
|
67
|
-
conn = sqlite3.connect(str(db_path))
|
|
68
|
-
conn.execute("PRAGMA journal_mode=WAL")
|
|
69
|
-
conn.execute("""
|
|
70
|
-
CREATE TABLE IF NOT EXISTS memories (
|
|
71
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
72
|
-
content TEXT NOT NULL,
|
|
73
|
-
summary TEXT,
|
|
74
|
-
project_path TEXT,
|
|
75
|
-
project_name TEXT,
|
|
76
|
-
tags TEXT,
|
|
77
|
-
category TEXT,
|
|
78
|
-
parent_id INTEGER,
|
|
79
|
-
tree_path TEXT,
|
|
80
|
-
depth INTEGER DEFAULT 0,
|
|
81
|
-
memory_type TEXT DEFAULT 'session',
|
|
82
|
-
importance INTEGER DEFAULT 5,
|
|
83
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
84
|
-
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
85
|
-
last_accessed TIMESTAMP,
|
|
86
|
-
access_count INTEGER DEFAULT 0,
|
|
87
|
-
content_hash TEXT UNIQUE,
|
|
88
|
-
cluster_id INTEGER,
|
|
89
|
-
profile TEXT DEFAULT 'default',
|
|
90
|
-
FOREIGN KEY (parent_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
91
|
-
)
|
|
92
|
-
""")
|
|
93
|
-
conn.commit()
|
|
94
|
-
conn.close()
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def _insert_test_memory(db_path: Path, content: str = "test memory content") -> int:
|
|
98
|
-
"""Insert a single test memory into a v2.7.6 database and return its id."""
|
|
99
|
-
conn = sqlite3.connect(str(db_path))
|
|
100
|
-
cursor = conn.cursor()
|
|
101
|
-
cursor.execute(
|
|
102
|
-
"INSERT INTO memories (content, profile) VALUES (?, ?)",
|
|
103
|
-
(content, "default"),
|
|
104
|
-
)
|
|
105
|
-
conn.commit()
|
|
106
|
-
row_id = cursor.lastrowid
|
|
107
|
-
conn.close()
|
|
108
|
-
return row_id
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def _get_column_names(db_path: Path, table: str = "memories") -> set:
|
|
112
|
-
"""Return the set of column names for a table."""
|
|
113
|
-
conn = sqlite3.connect(str(db_path))
|
|
114
|
-
cursor = conn.cursor()
|
|
115
|
-
cursor.execute(f"PRAGMA table_info({table})")
|
|
116
|
-
columns = {row[1] for row in cursor.fetchall()}
|
|
117
|
-
conn.close()
|
|
118
|
-
return columns
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _get_index_names(db_path: Path) -> set:
|
|
122
|
-
"""Return the set of index names in the database."""
|
|
123
|
-
conn = sqlite3.connect(str(db_path))
|
|
124
|
-
cursor = conn.cursor()
|
|
125
|
-
cursor.execute("SELECT name FROM sqlite_master WHERE type='index'")
|
|
126
|
-
indexes = {row[0] for row in cursor.fetchall()}
|
|
127
|
-
conn.close()
|
|
128
|
-
return indexes
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
# ---------------------------------------------------------------------------
|
|
132
|
-
# Fixtures
|
|
133
|
-
# ---------------------------------------------------------------------------
|
|
134
|
-
|
|
135
|
-
@pytest.fixture
|
|
136
|
-
def v276_db(tmp_path):
|
|
137
|
-
"""
|
|
138
|
-
Create a temporary v2.7.6 schema database with one pre-existing memory.
|
|
139
|
-
Returns (db_path, memory_id).
|
|
140
|
-
"""
|
|
141
|
-
db_path = tmp_path / "memory.db"
|
|
142
|
-
_create_v276_database(db_path)
|
|
143
|
-
mem_id = _insert_test_memory(db_path, "pre-existing memory from v2.7.6")
|
|
144
|
-
return db_path, mem_id
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@pytest.fixture
|
|
148
|
-
def migrated_store(v276_db):
|
|
149
|
-
"""
|
|
150
|
-
Initialize MemoryStoreV2 on the v2.7.6 database, triggering the migration.
|
|
151
|
-
Returns (store, db_path, pre_existing_memory_id).
|
|
152
|
-
"""
|
|
153
|
-
db_path, mem_id = v276_db
|
|
154
|
-
MemoryStoreV2 = _import_memory_store_v2()
|
|
155
|
-
store = MemoryStoreV2(db_path=db_path)
|
|
156
|
-
return store, db_path, mem_id
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
# ---------------------------------------------------------------------------
|
|
160
|
-
# Tests
|
|
161
|
-
# ---------------------------------------------------------------------------
|
|
162
|
-
|
|
163
|
-
class TestV28SchemaMigration:
|
|
164
|
-
"""Verify v2.8.0 lifecycle + access control migration."""
|
|
165
|
-
|
|
166
|
-
def test_lifecycle_state_column_added(self, migrated_store):
|
|
167
|
-
"""After MemoryStoreV2 init, lifecycle_state column exists."""
|
|
168
|
-
_store, db_path, _mem_id = migrated_store
|
|
169
|
-
columns = _get_column_names(db_path)
|
|
170
|
-
assert "lifecycle_state" in columns, (
|
|
171
|
-
f"lifecycle_state column missing. Columns: {sorted(columns)}"
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
def test_existing_memories_get_active_state(self, migrated_store):
|
|
175
|
-
"""Pre-existing memories get lifecycle_state='active' from DEFAULT."""
|
|
176
|
-
_store, db_path, mem_id = migrated_store
|
|
177
|
-
conn = sqlite3.connect(str(db_path))
|
|
178
|
-
cursor = conn.cursor()
|
|
179
|
-
cursor.execute(
|
|
180
|
-
"SELECT lifecycle_state FROM memories WHERE id = ?", (mem_id,)
|
|
181
|
-
)
|
|
182
|
-
row = cursor.fetchone()
|
|
183
|
-
conn.close()
|
|
184
|
-
|
|
185
|
-
assert row is not None, "Pre-existing memory not found after migration"
|
|
186
|
-
assert row[0] == "active", (
|
|
187
|
-
f"Expected lifecycle_state='active', got '{row[0]}'"
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
def test_access_level_column_added(self, migrated_store):
|
|
191
|
-
"""access_level column exists with DEFAULT 'public'."""
|
|
192
|
-
_store, db_path, mem_id = migrated_store
|
|
193
|
-
columns = _get_column_names(db_path)
|
|
194
|
-
assert "access_level" in columns, (
|
|
195
|
-
f"access_level column missing. Columns: {sorted(columns)}"
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
# Verify default value on pre-existing row
|
|
199
|
-
conn = sqlite3.connect(str(db_path))
|
|
200
|
-
cursor = conn.cursor()
|
|
201
|
-
cursor.execute(
|
|
202
|
-
"SELECT access_level FROM memories WHERE id = ?", (mem_id,)
|
|
203
|
-
)
|
|
204
|
-
row = cursor.fetchone()
|
|
205
|
-
conn.close()
|
|
206
|
-
|
|
207
|
-
assert row is not None
|
|
208
|
-
assert row[0] == "public", (
|
|
209
|
-
f"Expected access_level='public', got '{row[0]}'"
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
def test_lifecycle_history_column_added(self, migrated_store):
|
|
213
|
-
"""lifecycle_history column exists with DEFAULT '[]'."""
|
|
214
|
-
_store, db_path, mem_id = migrated_store
|
|
215
|
-
columns = _get_column_names(db_path)
|
|
216
|
-
assert "lifecycle_history" in columns, (
|
|
217
|
-
f"lifecycle_history column missing. Columns: {sorted(columns)}"
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
# Verify default value on pre-existing row
|
|
221
|
-
conn = sqlite3.connect(str(db_path))
|
|
222
|
-
cursor = conn.cursor()
|
|
223
|
-
cursor.execute(
|
|
224
|
-
"SELECT lifecycle_history FROM memories WHERE id = ?", (mem_id,)
|
|
225
|
-
)
|
|
226
|
-
row = cursor.fetchone()
|
|
227
|
-
conn.close()
|
|
228
|
-
|
|
229
|
-
assert row is not None
|
|
230
|
-
assert row[0] == "[]", (
|
|
231
|
-
f"Expected lifecycle_history='[]', got '{row[0]}'"
|
|
232
|
-
)
|
|
233
|
-
# Verify it's valid JSON
|
|
234
|
-
parsed = json.loads(row[0])
|
|
235
|
-
assert parsed == []
|
|
236
|
-
|
|
237
|
-
def test_lifecycle_updated_at_column_added(self, migrated_store):
|
|
238
|
-
"""lifecycle_updated_at column exists (nullable, no default)."""
|
|
239
|
-
_store, db_path, mem_id = migrated_store
|
|
240
|
-
columns = _get_column_names(db_path)
|
|
241
|
-
assert "lifecycle_updated_at" in columns, (
|
|
242
|
-
f"lifecycle_updated_at column missing. Columns: {sorted(columns)}"
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
# Pre-existing rows should have NULL for this column
|
|
246
|
-
conn = sqlite3.connect(str(db_path))
|
|
247
|
-
cursor = conn.cursor()
|
|
248
|
-
cursor.execute(
|
|
249
|
-
"SELECT lifecycle_updated_at FROM memories WHERE id = ?", (mem_id,)
|
|
250
|
-
)
|
|
251
|
-
row = cursor.fetchone()
|
|
252
|
-
conn.close()
|
|
253
|
-
|
|
254
|
-
assert row is not None
|
|
255
|
-
assert row[0] is None, (
|
|
256
|
-
f"Expected lifecycle_updated_at=NULL for pre-existing row, got '{row[0]}'"
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
def test_migration_is_idempotent(self, v276_db):
|
|
260
|
-
"""Running migration twice (two MemoryStoreV2 inits) doesn't error."""
|
|
261
|
-
db_path, mem_id = v276_db
|
|
262
|
-
MemoryStoreV2 = _import_memory_store_v2()
|
|
263
|
-
|
|
264
|
-
# First init — migration runs
|
|
265
|
-
store1 = MemoryStoreV2(db_path=db_path)
|
|
266
|
-
|
|
267
|
-
# Second init — migration runs again (ALTER TABLE should be caught)
|
|
268
|
-
store2 = MemoryStoreV2(db_path=db_path)
|
|
269
|
-
|
|
270
|
-
# Both should succeed, columns should exist exactly once
|
|
271
|
-
columns = _get_column_names(db_path)
|
|
272
|
-
assert "lifecycle_state" in columns
|
|
273
|
-
assert "access_level" in columns
|
|
274
|
-
assert "lifecycle_history" in columns
|
|
275
|
-
assert "lifecycle_updated_at" in columns
|
|
276
|
-
|
|
277
|
-
# Pre-existing data should be intact
|
|
278
|
-
conn = sqlite3.connect(str(db_path))
|
|
279
|
-
cursor = conn.cursor()
|
|
280
|
-
cursor.execute("SELECT content FROM memories WHERE id = ?", (mem_id,))
|
|
281
|
-
row = cursor.fetchone()
|
|
282
|
-
conn.close()
|
|
283
|
-
assert row is not None
|
|
284
|
-
assert row[0] == "pre-existing memory from v2.7.6"
|
|
285
|
-
|
|
286
|
-
def test_existing_queries_still_work(self, migrated_store):
|
|
287
|
-
"""list_all() and search() work after migration."""
|
|
288
|
-
store, db_path, mem_id = migrated_store
|
|
289
|
-
|
|
290
|
-
# list_all should return the pre-existing memory
|
|
291
|
-
all_memories = store.list_all(limit=10)
|
|
292
|
-
assert len(all_memories) >= 1, "list_all() returned no results after migration"
|
|
293
|
-
|
|
294
|
-
found = any(m["id"] == mem_id for m in all_memories)
|
|
295
|
-
assert found, (
|
|
296
|
-
f"Pre-existing memory id={mem_id} not found in list_all() results"
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
# Add a memory through the store API (so FTS is properly populated)
|
|
300
|
-
new_id = store.add_memory(
|
|
301
|
-
content="post-migration memory for search test",
|
|
302
|
-
tags=["test"],
|
|
303
|
-
)
|
|
304
|
-
assert new_id is not None, "add_memory() should succeed after migration"
|
|
305
|
-
|
|
306
|
-
# search should not crash (may return empty if TF-IDF vectors not rebuilt)
|
|
307
|
-
results = store.search("post-migration", limit=5)
|
|
308
|
-
assert isinstance(results, list), "search() should return a list"
|
|
309
|
-
|
|
310
|
-
def test_v28_indexes_created(self, migrated_store):
|
|
311
|
-
"""v2.8.0 indexes for lifecycle_state and access_level exist."""
|
|
312
|
-
_store, db_path, _mem_id = migrated_store
|
|
313
|
-
indexes = _get_index_names(db_path)
|
|
314
|
-
assert "idx_lifecycle_state" in indexes, (
|
|
315
|
-
f"idx_lifecycle_state index missing. Indexes: {sorted(indexes)}"
|
|
316
|
-
)
|
|
317
|
-
assert "idx_access_level" in indexes, (
|
|
318
|
-
f"idx_access_level index missing. Indexes: {sorted(indexes)}"
|
|
319
|
-
)
|