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
package/src/tree/nodes.py
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
3
|
-
"""Tree Nodes — CRUD operations and count aggregation.
|
|
4
|
-
|
|
5
|
-
Provides TreeNodesMixin with add_node, delete_node, update_counts,
|
|
6
|
-
and internal helper methods for materialized-path management.
|
|
7
|
-
"""
|
|
8
|
-
import sqlite3
|
|
9
|
-
from typing import Optional, Dict, Any
|
|
10
|
-
from datetime import datetime
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class TreeNodesMixin:
|
|
14
|
-
"""Node CRUD and aggregation logic for the memory tree."""
|
|
15
|
-
|
|
16
|
-
def add_node(
|
|
17
|
-
self,
|
|
18
|
-
node_type: str,
|
|
19
|
-
name: str,
|
|
20
|
-
parent_id: int,
|
|
21
|
-
description: Optional[str] = None,
|
|
22
|
-
memory_id: Optional[int] = None
|
|
23
|
-
) -> int:
|
|
24
|
-
"""
|
|
25
|
-
Add a new node to the tree.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
node_type: Type of node ('root', 'project', 'category', 'memory')
|
|
29
|
-
name: Display name
|
|
30
|
-
parent_id: Parent node ID
|
|
31
|
-
description: Optional description
|
|
32
|
-
memory_id: Link to memories table (for leaf nodes)
|
|
33
|
-
|
|
34
|
-
Returns:
|
|
35
|
-
New node ID
|
|
36
|
-
"""
|
|
37
|
-
conn = sqlite3.connect(self.db_path)
|
|
38
|
-
try:
|
|
39
|
-
cursor = conn.cursor()
|
|
40
|
-
|
|
41
|
-
# Get parent path and depth
|
|
42
|
-
cursor.execute('SELECT tree_path, depth FROM memory_tree WHERE id = ?', (parent_id,))
|
|
43
|
-
result = cursor.fetchone()
|
|
44
|
-
|
|
45
|
-
if not result:
|
|
46
|
-
raise ValueError(f"Parent node {parent_id} not found")
|
|
47
|
-
|
|
48
|
-
parent_path, parent_depth = result
|
|
49
|
-
|
|
50
|
-
# Calculate new node position
|
|
51
|
-
depth = parent_depth + 1
|
|
52
|
-
|
|
53
|
-
cursor.execute('''
|
|
54
|
-
INSERT INTO memory_tree (
|
|
55
|
-
node_type, name, description,
|
|
56
|
-
parent_id, tree_path, depth,
|
|
57
|
-
memory_id, last_updated
|
|
58
|
-
)
|
|
59
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
60
|
-
''', (
|
|
61
|
-
node_type,
|
|
62
|
-
name,
|
|
63
|
-
description,
|
|
64
|
-
parent_id,
|
|
65
|
-
'', # Placeholder, updated below
|
|
66
|
-
depth,
|
|
67
|
-
memory_id,
|
|
68
|
-
datetime.now().isoformat()
|
|
69
|
-
))
|
|
70
|
-
|
|
71
|
-
node_id = cursor.lastrowid
|
|
72
|
-
|
|
73
|
-
# Update tree_path with actual node_id
|
|
74
|
-
tree_path = f"{parent_path}.{node_id}"
|
|
75
|
-
cursor.execute('UPDATE memory_tree SET tree_path = ? WHERE id = ?', (tree_path, node_id))
|
|
76
|
-
|
|
77
|
-
conn.commit()
|
|
78
|
-
finally:
|
|
79
|
-
conn.close()
|
|
80
|
-
|
|
81
|
-
return node_id
|
|
82
|
-
|
|
83
|
-
def delete_node(self, node_id: int) -> bool:
|
|
84
|
-
"""
|
|
85
|
-
Delete a node and all its descendants.
|
|
86
|
-
|
|
87
|
-
Args:
|
|
88
|
-
node_id: Node ID to delete
|
|
89
|
-
|
|
90
|
-
Returns:
|
|
91
|
-
True if deleted, False if not found
|
|
92
|
-
"""
|
|
93
|
-
if node_id == self.root_id:
|
|
94
|
-
raise ValueError("Cannot delete root node")
|
|
95
|
-
|
|
96
|
-
conn = sqlite3.connect(self.db_path)
|
|
97
|
-
try:
|
|
98
|
-
cursor = conn.cursor()
|
|
99
|
-
|
|
100
|
-
# Get tree_path
|
|
101
|
-
cursor.execute('SELECT tree_path, parent_id FROM memory_tree WHERE id = ?', (node_id,))
|
|
102
|
-
result = cursor.fetchone()
|
|
103
|
-
|
|
104
|
-
if not result:
|
|
105
|
-
return False
|
|
106
|
-
|
|
107
|
-
tree_path, parent_id = result
|
|
108
|
-
|
|
109
|
-
# Delete node and all descendants (CASCADE handles children)
|
|
110
|
-
cursor.execute('DELETE FROM memory_tree WHERE id = ? OR tree_path LIKE ?',
|
|
111
|
-
(node_id, f"{tree_path}.%"))
|
|
112
|
-
|
|
113
|
-
deleted = cursor.rowcount > 0
|
|
114
|
-
conn.commit()
|
|
115
|
-
finally:
|
|
116
|
-
conn.close()
|
|
117
|
-
|
|
118
|
-
# Update parent counts
|
|
119
|
-
if deleted and parent_id:
|
|
120
|
-
self.update_counts(parent_id)
|
|
121
|
-
|
|
122
|
-
return deleted
|
|
123
|
-
|
|
124
|
-
def update_counts(self, node_id: int):
|
|
125
|
-
"""
|
|
126
|
-
Update aggregated counts for a node (memory_count, total_size).
|
|
127
|
-
Recursively updates all ancestors.
|
|
128
|
-
|
|
129
|
-
Args:
|
|
130
|
-
node_id: Node ID to update
|
|
131
|
-
"""
|
|
132
|
-
conn = sqlite3.connect(self.db_path)
|
|
133
|
-
try:
|
|
134
|
-
cursor = conn.cursor()
|
|
135
|
-
|
|
136
|
-
# Get all descendant memory nodes
|
|
137
|
-
cursor.execute('SELECT tree_path FROM memory_tree WHERE id = ?', (node_id,))
|
|
138
|
-
result = cursor.fetchone()
|
|
139
|
-
|
|
140
|
-
if not result:
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
tree_path = result[0]
|
|
144
|
-
|
|
145
|
-
# Count memories in subtree
|
|
146
|
-
cursor.execute('''
|
|
147
|
-
SELECT COUNT(*), COALESCE(SUM(LENGTH(m.content)), 0)
|
|
148
|
-
FROM memory_tree t
|
|
149
|
-
LEFT JOIN memories m ON t.memory_id = m.id
|
|
150
|
-
WHERE t.tree_path LIKE ? AND t.memory_id IS NOT NULL
|
|
151
|
-
''', (f"{tree_path}%",))
|
|
152
|
-
|
|
153
|
-
memory_count, total_size = cursor.fetchone()
|
|
154
|
-
|
|
155
|
-
# Update node
|
|
156
|
-
cursor.execute('''
|
|
157
|
-
UPDATE memory_tree
|
|
158
|
-
SET memory_count = ?, total_size = ?, last_updated = ?
|
|
159
|
-
WHERE id = ?
|
|
160
|
-
''', (memory_count, total_size, datetime.now().isoformat(), node_id))
|
|
161
|
-
|
|
162
|
-
# Update all ancestors
|
|
163
|
-
path_ids = [int(x) for x in tree_path.split('.')]
|
|
164
|
-
for ancestor_id in path_ids[:-1]: # Exclude current node
|
|
165
|
-
self.update_counts(ancestor_id)
|
|
166
|
-
|
|
167
|
-
conn.commit()
|
|
168
|
-
finally:
|
|
169
|
-
conn.close()
|
|
170
|
-
|
|
171
|
-
def _update_all_counts(self):
|
|
172
|
-
"""Update counts for all nodes (used after build_tree)."""
|
|
173
|
-
conn = sqlite3.connect(self.db_path)
|
|
174
|
-
try:
|
|
175
|
-
cursor = conn.cursor()
|
|
176
|
-
|
|
177
|
-
# Get all nodes in reverse depth order (leaves first)
|
|
178
|
-
cursor.execute('''
|
|
179
|
-
SELECT id FROM memory_tree
|
|
180
|
-
ORDER BY depth DESC
|
|
181
|
-
''')
|
|
182
|
-
|
|
183
|
-
node_ids = [row[0] for row in cursor.fetchall()]
|
|
184
|
-
finally:
|
|
185
|
-
conn.close()
|
|
186
|
-
|
|
187
|
-
# Update each node (will cascade to parents)
|
|
188
|
-
processed = set()
|
|
189
|
-
for node_id in node_ids:
|
|
190
|
-
if node_id not in processed:
|
|
191
|
-
self.update_counts(node_id)
|
|
192
|
-
processed.add(node_id)
|
|
193
|
-
|
|
194
|
-
def _generate_tree_path(self, parent_path: str, node_id: int) -> str:
|
|
195
|
-
"""Generate tree_path for a new node."""
|
|
196
|
-
if parent_path:
|
|
197
|
-
return f"{parent_path}.{node_id}"
|
|
198
|
-
return str(node_id)
|
|
199
|
-
|
|
200
|
-
def _calculate_depth(self, tree_path: str) -> int:
|
|
201
|
-
"""Calculate depth from tree_path (count dots)."""
|
|
202
|
-
return tree_path.count('.')
|
package/src/tree/queries.py
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
3
|
-
"""Tree Queries — Read-only tree traversal and statistics.
|
|
4
|
-
|
|
5
|
-
Provides TreeQueriesMixin with get_tree, get_subtree,
|
|
6
|
-
get_path_to_root, and get_stats.
|
|
7
|
-
"""
|
|
8
|
-
import sqlite3
|
|
9
|
-
from typing import Optional, List, Dict, Any
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class TreeQueriesMixin:
|
|
13
|
-
"""Read-only query methods for the memory tree."""
|
|
14
|
-
|
|
15
|
-
def get_tree(
|
|
16
|
-
self,
|
|
17
|
-
project_name: Optional[str] = None,
|
|
18
|
-
max_depth: Optional[int] = None
|
|
19
|
-
) -> Dict[str, Any]:
|
|
20
|
-
"""
|
|
21
|
-
Get tree structure as nested dictionary.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
project_name: Filter by specific project
|
|
25
|
-
max_depth: Maximum depth to retrieve
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
Nested dictionary representing tree structure
|
|
29
|
-
"""
|
|
30
|
-
conn = sqlite3.connect(self.db_path)
|
|
31
|
-
try:
|
|
32
|
-
cursor = conn.cursor()
|
|
33
|
-
|
|
34
|
-
# Build query
|
|
35
|
-
if project_name:
|
|
36
|
-
# Find project node
|
|
37
|
-
cursor.execute('''
|
|
38
|
-
SELECT id, tree_path FROM memory_tree
|
|
39
|
-
WHERE node_type = 'project' AND name = ?
|
|
40
|
-
''', (project_name,))
|
|
41
|
-
result = cursor.fetchone()
|
|
42
|
-
|
|
43
|
-
if not result:
|
|
44
|
-
return {'error': f"Project '{project_name}' not found"}
|
|
45
|
-
|
|
46
|
-
project_id, project_path = result
|
|
47
|
-
|
|
48
|
-
# Get subtree
|
|
49
|
-
if max_depth is not None:
|
|
50
|
-
cursor.execute('''
|
|
51
|
-
SELECT id, node_type, name, description, parent_id, tree_path,
|
|
52
|
-
depth, memory_count, total_size, last_updated, memory_id
|
|
53
|
-
FROM memory_tree
|
|
54
|
-
WHERE (id = ? OR tree_path LIKE ?) AND depth <= ?
|
|
55
|
-
ORDER BY tree_path
|
|
56
|
-
''', (project_id, f"{project_path}.%", max_depth))
|
|
57
|
-
else:
|
|
58
|
-
cursor.execute('''
|
|
59
|
-
SELECT id, node_type, name, description, parent_id, tree_path,
|
|
60
|
-
depth, memory_count, total_size, last_updated, memory_id
|
|
61
|
-
FROM memory_tree
|
|
62
|
-
WHERE id = ? OR tree_path LIKE ?
|
|
63
|
-
ORDER BY tree_path
|
|
64
|
-
''', (project_id, f"{project_path}.%"))
|
|
65
|
-
else:
|
|
66
|
-
# Get entire tree
|
|
67
|
-
if max_depth is not None:
|
|
68
|
-
cursor.execute('''
|
|
69
|
-
SELECT id, node_type, name, description, parent_id, tree_path,
|
|
70
|
-
depth, memory_count, total_size, last_updated, memory_id
|
|
71
|
-
FROM memory_tree
|
|
72
|
-
WHERE depth <= ?
|
|
73
|
-
ORDER BY tree_path
|
|
74
|
-
''', (max_depth,))
|
|
75
|
-
else:
|
|
76
|
-
cursor.execute('''
|
|
77
|
-
SELECT id, node_type, name, description, parent_id, tree_path,
|
|
78
|
-
depth, memory_count, total_size, last_updated, memory_id
|
|
79
|
-
FROM memory_tree
|
|
80
|
-
ORDER BY tree_path
|
|
81
|
-
''')
|
|
82
|
-
|
|
83
|
-
rows = cursor.fetchall()
|
|
84
|
-
finally:
|
|
85
|
-
conn.close()
|
|
86
|
-
|
|
87
|
-
if not rows:
|
|
88
|
-
return {'error': 'No tree nodes found'}
|
|
89
|
-
|
|
90
|
-
# Build nested structure
|
|
91
|
-
nodes = {}
|
|
92
|
-
root = None
|
|
93
|
-
|
|
94
|
-
for row in rows:
|
|
95
|
-
node = {
|
|
96
|
-
'id': row[0],
|
|
97
|
-
'type': row[1],
|
|
98
|
-
'name': row[2],
|
|
99
|
-
'description': row[3],
|
|
100
|
-
'parent_id': row[4],
|
|
101
|
-
'tree_path': row[5],
|
|
102
|
-
'depth': row[6],
|
|
103
|
-
'memory_count': row[7],
|
|
104
|
-
'total_size': row[8],
|
|
105
|
-
'last_updated': row[9],
|
|
106
|
-
'memory_id': row[10],
|
|
107
|
-
'children': []
|
|
108
|
-
}
|
|
109
|
-
nodes[node['id']] = node
|
|
110
|
-
|
|
111
|
-
if node['parent_id'] is None or (project_name and node['type'] == 'project'):
|
|
112
|
-
root = node
|
|
113
|
-
elif node['parent_id'] in nodes:
|
|
114
|
-
nodes[node['parent_id']]['children'].append(node)
|
|
115
|
-
|
|
116
|
-
return root or {'error': 'Root node not found'}
|
|
117
|
-
|
|
118
|
-
def get_subtree(self, node_id: int) -> List[Dict[str, Any]]:
|
|
119
|
-
"""
|
|
120
|
-
Get all descendants of a specific node (flat list).
|
|
121
|
-
|
|
122
|
-
Args:
|
|
123
|
-
node_id: Node ID to get subtree for
|
|
124
|
-
|
|
125
|
-
Returns:
|
|
126
|
-
List of descendant nodes
|
|
127
|
-
"""
|
|
128
|
-
conn = sqlite3.connect(self.db_path)
|
|
129
|
-
try:
|
|
130
|
-
cursor = conn.cursor()
|
|
131
|
-
|
|
132
|
-
# Get node's tree_path
|
|
133
|
-
cursor.execute('SELECT tree_path FROM memory_tree WHERE id = ?', (node_id,))
|
|
134
|
-
result = cursor.fetchone()
|
|
135
|
-
|
|
136
|
-
if not result:
|
|
137
|
-
return []
|
|
138
|
-
|
|
139
|
-
tree_path = result[0]
|
|
140
|
-
|
|
141
|
-
# Get all descendants
|
|
142
|
-
cursor.execute('''
|
|
143
|
-
SELECT id, node_type, name, description, parent_id, tree_path,
|
|
144
|
-
depth, memory_count, total_size, last_updated, memory_id
|
|
145
|
-
FROM memory_tree
|
|
146
|
-
WHERE tree_path LIKE ?
|
|
147
|
-
ORDER BY tree_path
|
|
148
|
-
''', (f"{tree_path}.%",))
|
|
149
|
-
|
|
150
|
-
results = []
|
|
151
|
-
for row in cursor.fetchall():
|
|
152
|
-
results.append({
|
|
153
|
-
'id': row[0],
|
|
154
|
-
'type': row[1],
|
|
155
|
-
'name': row[2],
|
|
156
|
-
'description': row[3],
|
|
157
|
-
'parent_id': row[4],
|
|
158
|
-
'tree_path': row[5],
|
|
159
|
-
'depth': row[6],
|
|
160
|
-
'memory_count': row[7],
|
|
161
|
-
'total_size': row[8],
|
|
162
|
-
'last_updated': row[9],
|
|
163
|
-
'memory_id': row[10]
|
|
164
|
-
})
|
|
165
|
-
finally:
|
|
166
|
-
conn.close()
|
|
167
|
-
|
|
168
|
-
return results
|
|
169
|
-
|
|
170
|
-
def get_path_to_root(self, node_id: int) -> List[Dict[str, Any]]:
|
|
171
|
-
"""
|
|
172
|
-
Get path from node to root (breadcrumb trail).
|
|
173
|
-
|
|
174
|
-
Args:
|
|
175
|
-
node_id: Starting node ID
|
|
176
|
-
|
|
177
|
-
Returns:
|
|
178
|
-
List of nodes from root to target node
|
|
179
|
-
"""
|
|
180
|
-
conn = sqlite3.connect(self.db_path)
|
|
181
|
-
try:
|
|
182
|
-
cursor = conn.cursor()
|
|
183
|
-
|
|
184
|
-
# Get node's tree_path
|
|
185
|
-
cursor.execute('SELECT tree_path FROM memory_tree WHERE id = ?', (node_id,))
|
|
186
|
-
result = cursor.fetchone()
|
|
187
|
-
|
|
188
|
-
if not result:
|
|
189
|
-
return []
|
|
190
|
-
|
|
191
|
-
tree_path = result[0]
|
|
192
|
-
|
|
193
|
-
# Parse path to get all ancestor IDs
|
|
194
|
-
path_ids = [int(x) for x in tree_path.split('.')]
|
|
195
|
-
|
|
196
|
-
# Get all ancestor nodes
|
|
197
|
-
placeholders = ','.join('?' * len(path_ids))
|
|
198
|
-
cursor.execute(f'''
|
|
199
|
-
SELECT id, node_type, name, description, parent_id, tree_path,
|
|
200
|
-
depth, memory_count, total_size, last_updated, memory_id
|
|
201
|
-
FROM memory_tree
|
|
202
|
-
WHERE id IN ({placeholders})
|
|
203
|
-
ORDER BY depth
|
|
204
|
-
''', path_ids)
|
|
205
|
-
|
|
206
|
-
results = []
|
|
207
|
-
for row in cursor.fetchall():
|
|
208
|
-
results.append({
|
|
209
|
-
'id': row[0],
|
|
210
|
-
'type': row[1],
|
|
211
|
-
'name': row[2],
|
|
212
|
-
'description': row[3],
|
|
213
|
-
'parent_id': row[4],
|
|
214
|
-
'tree_path': row[5],
|
|
215
|
-
'depth': row[6],
|
|
216
|
-
'memory_count': row[7],
|
|
217
|
-
'total_size': row[8],
|
|
218
|
-
'last_updated': row[9],
|
|
219
|
-
'memory_id': row[10]
|
|
220
|
-
})
|
|
221
|
-
finally:
|
|
222
|
-
conn.close()
|
|
223
|
-
|
|
224
|
-
return results
|
|
225
|
-
|
|
226
|
-
def get_stats(self) -> Dict[str, Any]:
|
|
227
|
-
"""Get tree statistics."""
|
|
228
|
-
conn = sqlite3.connect(self.db_path)
|
|
229
|
-
try:
|
|
230
|
-
cursor = conn.cursor()
|
|
231
|
-
|
|
232
|
-
cursor.execute('SELECT COUNT(*) FROM memory_tree')
|
|
233
|
-
total_nodes = cursor.fetchone()[0]
|
|
234
|
-
|
|
235
|
-
cursor.execute('SELECT node_type, COUNT(*) FROM memory_tree GROUP BY node_type')
|
|
236
|
-
by_type = dict(cursor.fetchall())
|
|
237
|
-
|
|
238
|
-
cursor.execute('SELECT MAX(depth) FROM memory_tree')
|
|
239
|
-
max_depth = cursor.fetchone()[0] or 0
|
|
240
|
-
|
|
241
|
-
cursor.execute('''
|
|
242
|
-
SELECT SUM(memory_count), SUM(total_size)
|
|
243
|
-
FROM memory_tree
|
|
244
|
-
WHERE node_type = 'root'
|
|
245
|
-
''')
|
|
246
|
-
total_memories, total_size = cursor.fetchone()
|
|
247
|
-
|
|
248
|
-
finally:
|
|
249
|
-
conn.close()
|
|
250
|
-
|
|
251
|
-
return {
|
|
252
|
-
'total_nodes': total_nodes,
|
|
253
|
-
'by_type': by_type,
|
|
254
|
-
'max_depth': max_depth,
|
|
255
|
-
'total_memories': total_memories or 0,
|
|
256
|
-
'total_size_bytes': total_size or 0
|
|
257
|
-
}
|
package/src/tree/schema.py
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
3
|
-
"""Tree Schema — Database initialization and root node management.
|
|
4
|
-
|
|
5
|
-
Provides the TreeSchemaMixin with DB init and root-node bootstrap logic
|
|
6
|
-
for the materialized-path tree structure.
|
|
7
|
-
"""
|
|
8
|
-
import sqlite3
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
from typing import Optional
|
|
11
|
-
from datetime import datetime
|
|
12
|
-
|
|
13
|
-
MEMORY_DIR = Path.home() / ".claude-memory"
|
|
14
|
-
DB_PATH = MEMORY_DIR / "memory.db"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class TreeSchemaMixin:
|
|
18
|
-
"""Database schema and root-node management for the memory tree."""
|
|
19
|
-
|
|
20
|
-
def _init_db(self):
|
|
21
|
-
"""Initialize memory_tree table."""
|
|
22
|
-
conn = sqlite3.connect(self.db_path)
|
|
23
|
-
try:
|
|
24
|
-
cursor = conn.cursor()
|
|
25
|
-
|
|
26
|
-
cursor.execute('''
|
|
27
|
-
CREATE TABLE IF NOT EXISTS memory_tree (
|
|
28
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
29
|
-
node_type TEXT NOT NULL,
|
|
30
|
-
name TEXT NOT NULL,
|
|
31
|
-
description TEXT,
|
|
32
|
-
|
|
33
|
-
parent_id INTEGER,
|
|
34
|
-
tree_path TEXT NOT NULL,
|
|
35
|
-
depth INTEGER DEFAULT 0,
|
|
36
|
-
|
|
37
|
-
memory_count INTEGER DEFAULT 0,
|
|
38
|
-
total_size INTEGER DEFAULT 0,
|
|
39
|
-
last_updated TIMESTAMP,
|
|
40
|
-
|
|
41
|
-
memory_id INTEGER,
|
|
42
|
-
|
|
43
|
-
FOREIGN KEY (parent_id) REFERENCES memory_tree(id) ON DELETE CASCADE,
|
|
44
|
-
FOREIGN KEY (memory_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
45
|
-
)
|
|
46
|
-
''')
|
|
47
|
-
|
|
48
|
-
cursor.execute('CREATE INDEX IF NOT EXISTS idx_tree_path_layer2 ON memory_tree(tree_path)')
|
|
49
|
-
cursor.execute('CREATE INDEX IF NOT EXISTS idx_node_type ON memory_tree(node_type)')
|
|
50
|
-
cursor.execute('CREATE INDEX IF NOT EXISTS idx_parent_id_tree ON memory_tree(parent_id)')
|
|
51
|
-
|
|
52
|
-
conn.commit()
|
|
53
|
-
finally:
|
|
54
|
-
conn.close()
|
|
55
|
-
|
|
56
|
-
def _ensure_root(self) -> int:
|
|
57
|
-
"""Ensure root node exists and return its ID."""
|
|
58
|
-
conn = sqlite3.connect(self.db_path)
|
|
59
|
-
try:
|
|
60
|
-
cursor = conn.cursor()
|
|
61
|
-
|
|
62
|
-
cursor.execute('SELECT id FROM memory_tree WHERE node_type = ? AND parent_id IS NULL', ('root',))
|
|
63
|
-
result = cursor.fetchone()
|
|
64
|
-
|
|
65
|
-
if result:
|
|
66
|
-
root_id = result[0]
|
|
67
|
-
else:
|
|
68
|
-
cursor.execute('''
|
|
69
|
-
INSERT INTO memory_tree (node_type, name, tree_path, depth, last_updated)
|
|
70
|
-
VALUES (?, ?, ?, ?, ?)
|
|
71
|
-
''', ('root', 'Root', '1', 0, datetime.now().isoformat()))
|
|
72
|
-
root_id = cursor.lastrowid
|
|
73
|
-
|
|
74
|
-
# Update tree_path with actual ID
|
|
75
|
-
cursor.execute('UPDATE memory_tree SET tree_path = ? WHERE id = ?', (str(root_id), root_id))
|
|
76
|
-
conn.commit()
|
|
77
|
-
|
|
78
|
-
finally:
|
|
79
|
-
conn.close()
|
|
80
|
-
return root_id
|
package/src/tree_manager.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
TreeManager - Thin re-export shim.
|
|
6
|
-
|
|
7
|
-
Implementation lives in src/tree/ (schema, nodes, queries, builder).
|
|
8
|
-
This file preserves backward compatibility for any existing imports.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from tree.schema import MEMORY_DIR, DB_PATH
|
|
12
|
-
from tree import TreeManager
|
|
13
|
-
|
|
14
|
-
__all__ = ['TreeManager', 'MEMORY_DIR', 'DB_PATH']
|
|
15
|
-
|
|
16
|
-
# CLI interface
|
|
17
|
-
if __name__ == "__main__":
|
|
18
|
-
from tree.builder import run_cli
|
|
19
|
-
run_cli()
|
package/src/trust/__init__.py
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
Trust scoring package -- Bayesian Beta-Binomial trust for AI agents.
|
|
6
|
-
|
|
7
|
-
Re-exports all public symbols for backward compatibility.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from .constants import (
|
|
11
|
-
SIGNAL_WEIGHTS,
|
|
12
|
-
SIGNAL_DELTAS,
|
|
13
|
-
INITIAL_ALPHA,
|
|
14
|
-
INITIAL_BETA,
|
|
15
|
-
DECAY_FACTOR,
|
|
16
|
-
DECAY_INTERVAL,
|
|
17
|
-
ALPHA_FLOOR,
|
|
18
|
-
BETA_FLOOR,
|
|
19
|
-
QUICK_DELETE_HOURS,
|
|
20
|
-
BURST_THRESHOLD,
|
|
21
|
-
BURST_WINDOW_MINUTES,
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
from .schema import init_trust_schema
|
|
25
|
-
|
|
26
|
-
from .scorer import TrustScorer
|
|
27
|
-
|
|
28
|
-
__all__ = [
|
|
29
|
-
# Class
|
|
30
|
-
"TrustScorer",
|
|
31
|
-
# Constants
|
|
32
|
-
"SIGNAL_WEIGHTS",
|
|
33
|
-
"SIGNAL_DELTAS",
|
|
34
|
-
"INITIAL_ALPHA",
|
|
35
|
-
"INITIAL_BETA",
|
|
36
|
-
"DECAY_FACTOR",
|
|
37
|
-
"DECAY_INTERVAL",
|
|
38
|
-
"ALPHA_FLOOR",
|
|
39
|
-
"BETA_FLOOR",
|
|
40
|
-
"QUICK_DELETE_HOURS",
|
|
41
|
-
"BURST_THRESHOLD",
|
|
42
|
-
"BURST_WINDOW_MINUTES",
|
|
43
|
-
# Schema
|
|
44
|
-
"init_trust_schema",
|
|
45
|
-
]
|
package/src/trust/constants.py
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
4
|
-
"""
|
|
5
|
-
Beta-Binomial signal weights and trust scoring constants.
|
|
6
|
-
|
|
7
|
-
Extracted from trust_scorer.py for modularity.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
# ---------------------------------------------------------------------------
|
|
11
|
-
# Beta-Binomial signal weights
|
|
12
|
-
# ---------------------------------------------------------------------------
|
|
13
|
-
# Positive signals increment alpha (building trust).
|
|
14
|
-
# Negative signals increment beta (eroding trust).
|
|
15
|
-
# Neutral signals give a tiny alpha nudge to reward normal activity.
|
|
16
|
-
#
|
|
17
|
-
# Asymmetry: negative weights are larger than positive weights.
|
|
18
|
-
# This means it's harder to build trust than to lose it -- the system
|
|
19
|
-
# is intentionally skeptical. One poisoning event takes many good
|
|
20
|
-
# actions to recover from.
|
|
21
|
-
# ---------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
SIGNAL_WEIGHTS = {
|
|
24
|
-
# Positive signals -> alpha += weight
|
|
25
|
-
"memory_recalled_by_others": ("positive", 0.30), # cross-agent validation
|
|
26
|
-
"memory_updated": ("positive", 0.15), # ongoing relevance
|
|
27
|
-
"high_importance_write": ("positive", 0.20), # valuable content (importance >= 7)
|
|
28
|
-
"consistent_pattern": ("positive", 0.15), # stable write behavior
|
|
29
|
-
|
|
30
|
-
# Negative signals -> beta += weight
|
|
31
|
-
"quick_delete": ("negative", 0.50), # deleted within 1 hour
|
|
32
|
-
"high_volume_burst": ("negative", 0.40), # >20 writes in 5 minutes
|
|
33
|
-
"content_overwritten_by_user": ("negative", 0.25), # user had to fix output
|
|
34
|
-
|
|
35
|
-
# Neutral signals -> tiny alpha nudge
|
|
36
|
-
"normal_write": ("neutral", 0.01),
|
|
37
|
-
"normal_recall": ("neutral", 0.01),
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
# Backward-compatible: expose SIGNAL_DELTAS as a derived dict so that
|
|
41
|
-
# bm6_trust.py (which imports SIGNAL_DELTAS) and any other consumer
|
|
42
|
-
# continues to work. The values represent the *direction* and *magnitude*
|
|
43
|
-
# of each signal: positive for alpha, negative for beta, zero for neutral.
|
|
44
|
-
SIGNAL_DELTAS = {}
|
|
45
|
-
for _sig, (_direction, _weight) in SIGNAL_WEIGHTS.items():
|
|
46
|
-
if _direction == "positive":
|
|
47
|
-
SIGNAL_DELTAS[_sig] = +_weight
|
|
48
|
-
elif _direction == "negative":
|
|
49
|
-
SIGNAL_DELTAS[_sig] = -_weight
|
|
50
|
-
else:
|
|
51
|
-
SIGNAL_DELTAS[_sig] = 0.0
|
|
52
|
-
|
|
53
|
-
# ---------------------------------------------------------------------------
|
|
54
|
-
# Beta prior and decay parameters
|
|
55
|
-
# ---------------------------------------------------------------------------
|
|
56
|
-
INITIAL_ALPHA = 2.0 # Slight positive prior
|
|
57
|
-
INITIAL_BETA = 1.0 # -> initial trust = 2/(2+1) = 0.667
|
|
58
|
-
DECAY_FACTOR = 0.995 # Multiply alpha & beta every DECAY_INTERVAL signals
|
|
59
|
-
DECAY_INTERVAL = 50 # Apply decay every N signals per agent
|
|
60
|
-
ALPHA_FLOOR = 1.0 # Never decay alpha below this
|
|
61
|
-
BETA_FLOOR = 0.5 # Never decay beta below this
|
|
62
|
-
|
|
63
|
-
# Thresholds
|
|
64
|
-
QUICK_DELETE_HOURS = 1 # Delete within 1 hour = negative signal
|
|
65
|
-
BURST_THRESHOLD = 20 # >20 writes in burst window = negative
|
|
66
|
-
BURST_WINDOW_MINUTES = 5 # Burst detection window
|