superlocalmemory 4.1.13 → 4.1.15
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +103 -0
- package/README.md +3 -3
- package/package.json +1 -8
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/agents/slm-memory-advisor.md +1 -1
- package/plugin-src/agents/slm-optimize-advisor.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-governance/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +1 -1
- package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
- package/plugin-src/skills/slm-profile/SKILL.md +1 -1
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-scope/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/scripts/postinstall.js +71 -2
- package/pyproject.toml +0 -250
- package/src/superlocalmemory/__init__.py +0 -82
- package/src/superlocalmemory/access/__init__.py +0 -3
- package/src/superlocalmemory/access/rbac.py +0 -575
- package/src/superlocalmemory/attribution/__init__.py +0 -9
- package/src/superlocalmemory/attribution/signer.py +0 -173
- package/src/superlocalmemory/attribution/watermark.py +0 -189
- package/src/superlocalmemory/brain/__init__.py +0 -5
- package/src/superlocalmemory/brain/truth.py +0 -418
- package/src/superlocalmemory/cli/__init__.py +0 -5
- package/src/superlocalmemory/cli/__main__.py +0 -17
- package/src/superlocalmemory/cli/_lazy_init.py +0 -115
- package/src/superlocalmemory/cli/cache_cmd.py +0 -198
- package/src/superlocalmemory/cli/commands.py +0 -4710
- package/src/superlocalmemory/cli/compress_cmd.py +0 -151
- package/src/superlocalmemory/cli/context_commands.py +0 -193
- package/src/superlocalmemory/cli/daemon.py +0 -909
- package/src/superlocalmemory/cli/db_migrate.py +0 -150
- package/src/superlocalmemory/cli/diagnostics_cmd.py +0 -101
- package/src/superlocalmemory/cli/escape_hatch.py +0 -220
- package/src/superlocalmemory/cli/evidence_cmd.py +0 -103
- package/src/superlocalmemory/cli/gdpr_cmd.py +0 -792
- package/src/superlocalmemory/cli/gdpr_io.py +0 -109
- package/src/superlocalmemory/cli/help_cmd.py +0 -197
- package/src/superlocalmemory/cli/host_upgrades.py +0 -189
- package/src/superlocalmemory/cli/ingest_cmd.py +0 -327
- package/src/superlocalmemory/cli/json_output.py +0 -81
- package/src/superlocalmemory/cli/loop_cmd.py +0 -187
- package/src/superlocalmemory/cli/main.py +0 -1145
- package/src/superlocalmemory/cli/mesh_cmd.py +0 -38
- package/src/superlocalmemory/cli/migrate_cmd.py +0 -55
- package/src/superlocalmemory/cli/ops_cmd.py +0 -281
- package/src/superlocalmemory/cli/optimize_cmd.py +0 -179
- package/src/superlocalmemory/cli/optimize_constants.py +0 -31
- package/src/superlocalmemory/cli/pending_store.py +0 -296
- package/src/superlocalmemory/cli/proxy_cmd.py +0 -108
- package/src/superlocalmemory/cli/scale_engine_cmd.py +0 -56
- package/src/superlocalmemory/cli/service_installer.py +0 -373
- package/src/superlocalmemory/cli/setup_wizard.py +0 -1162
- package/src/superlocalmemory/cli/summary_cmd.py +0 -215
- package/src/superlocalmemory/cli/version_banner.py +0 -202
- package/src/superlocalmemory/cli/wizard_v3426_options.py +0 -129
- package/src/superlocalmemory/code_graph/__init__.py +0 -46
- package/src/superlocalmemory/code_graph/blast_radius.py +0 -177
- package/src/superlocalmemory/code_graph/bridge/__init__.py +0 -36
- package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +0 -490
- package/src/superlocalmemory/code_graph/bridge/event_listeners.py +0 -206
- package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +0 -159
- package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +0 -170
- package/src/superlocalmemory/code_graph/bridge/maintenance.py +0 -220
- package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +0 -152
- package/src/superlocalmemory/code_graph/changes.py +0 -363
- package/src/superlocalmemory/code_graph/communities.py +0 -299
- package/src/superlocalmemory/code_graph/config.py +0 -154
- package/src/superlocalmemory/code_graph/database.py +0 -526
- package/src/superlocalmemory/code_graph/extractors/__init__.py +0 -95
- package/src/superlocalmemory/code_graph/extractors/python.py +0 -413
- package/src/superlocalmemory/code_graph/extractors/typescript.py +0 -556
- package/src/superlocalmemory/code_graph/flows.py +0 -350
- package/src/superlocalmemory/code_graph/git_hooks.py +0 -226
- package/src/superlocalmemory/code_graph/graph_engine.py +0 -295
- package/src/superlocalmemory/code_graph/graph_store.py +0 -335
- package/src/superlocalmemory/code_graph/incremental.py +0 -200
- package/src/superlocalmemory/code_graph/models.py +0 -130
- package/src/superlocalmemory/code_graph/parser.py +0 -687
- package/src/superlocalmemory/code_graph/resolver.py +0 -321
- package/src/superlocalmemory/code_graph/search.py +0 -460
- package/src/superlocalmemory/code_graph/service.py +0 -95
- package/src/superlocalmemory/code_graph/watcher.py +0 -207
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +0 -204
- package/src/superlocalmemory/compliance/audit.py +0 -385
- package/src/superlocalmemory/compliance/eu_ai_act.py +0 -101
- package/src/superlocalmemory/compliance/gdpr.py +0 -1479
- package/src/superlocalmemory/compliance/lifecycle.py +0 -158
- package/src/superlocalmemory/compliance/retention.py +0 -415
- package/src/superlocalmemory/compliance/scheduler.py +0 -217
- package/src/superlocalmemory/contracts/__init__.py +0 -1
- package/src/superlocalmemory/contracts/schemas/agent-experience-v1.schema.json +0 -92
- package/src/superlocalmemory/contracts/schemas/agent-integration-contract-v2.schema.json +0 -46
- package/src/superlocalmemory/contracts/schemas/cognitive-turn-receipt-v1.schema.json +0 -59
- package/src/superlocalmemory/contracts/v402.py +0 -62
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/actor_context.py +0 -166
- package/src/superlocalmemory/core/admission.py +0 -769
- package/src/superlocalmemory/core/backend_orchestrator.py +0 -637
- package/src/superlocalmemory/core/block_hygiene.py +0 -147
- package/src/superlocalmemory/core/community_summary.py +0 -267
- package/src/superlocalmemory/core/component_healer.py +0 -144
- package/src/superlocalmemory/core/component_registry.py +0 -514
- package/src/superlocalmemory/core/config.py +0 -2204
- package/src/superlocalmemory/core/consolidation_engine.py +0 -983
- package/src/superlocalmemory/core/context_cache.py +0 -574
- package/src/superlocalmemory/core/derivation_lineage.py +0 -246
- package/src/superlocalmemory/core/embedding_worker.py +0 -208
- package/src/superlocalmemory/core/embeddings.py +0 -1052
- package/src/superlocalmemory/core/engine.py +0 -1395
- package/src/superlocalmemory/core/engine_capabilities.py +0 -24
- package/src/superlocalmemory/core/engine_ingestion.py +0 -983
- package/src/superlocalmemory/core/engine_lock.py +0 -75
- package/src/superlocalmemory/core/engine_wiring.py +0 -776
- package/src/superlocalmemory/core/entity_community.py +0 -178
- package/src/superlocalmemory/core/error_envelope.py +0 -60
- package/src/superlocalmemory/core/evidence_bundle.py +0 -528
- package/src/superlocalmemory/core/fact_consolidator.py +0 -812
- package/src/superlocalmemory/core/file_lock.py +0 -92
- package/src/superlocalmemory/core/graph_analyzer.py +0 -456
- package/src/superlocalmemory/core/graph_metrics.py +0 -597
- package/src/superlocalmemory/core/graph_pruner.py +0 -939
- package/src/superlocalmemory/core/health_monitor.py +0 -338
- package/src/superlocalmemory/core/hooks.py +0 -65
- package/src/superlocalmemory/core/ingest_gate.py +0 -133
- package/src/superlocalmemory/core/ingest_policy.py +0 -38
- package/src/superlocalmemory/core/ingestion_command.py +0 -1042
- package/src/superlocalmemory/core/injection.py +0 -434
- package/src/superlocalmemory/core/install_detector.py +0 -131
- package/src/superlocalmemory/core/key_expander.py +0 -138
- package/src/superlocalmemory/core/lifecycle_state.py +0 -153
- package/src/superlocalmemory/core/maintenance.py +0 -777
- package/src/superlocalmemory/core/maintenance_scheduler.py +0 -507
- package/src/superlocalmemory/core/materialization_control.py +0 -20
- package/src/superlocalmemory/core/mcp_embedder_proxy.py +0 -89
- package/src/superlocalmemory/core/memory_health.py +0 -266
- package/src/superlocalmemory/core/mode_capability.py +0 -111
- package/src/superlocalmemory/core/modes.py +0 -168
- package/src/superlocalmemory/core/mutations.py +0 -688
- package/src/superlocalmemory/core/ollama_embedder.py +0 -266
- package/src/superlocalmemory/core/ollama_validator.py +0 -315
- package/src/superlocalmemory/core/operation_policy.py +0 -92
- package/src/superlocalmemory/core/operation_policy_registry.py +0 -542
- package/src/superlocalmemory/core/operation_request.py +0 -127
- package/src/superlocalmemory/core/ops_remediation.py +0 -542
- package/src/superlocalmemory/core/pii.py +0 -105
- package/src/superlocalmemory/core/platform_utils.py +0 -138
- package/src/superlocalmemory/core/profiles.py +0 -234
- package/src/superlocalmemory/core/progressive_abstraction.py +0 -208
- package/src/superlocalmemory/core/projection_drain.py +0 -380
- package/src/superlocalmemory/core/queue_consumer.py +0 -168
- package/src/superlocalmemory/core/ram_lock.py +0 -160
- package/src/superlocalmemory/core/rate_limit.py +0 -151
- package/src/superlocalmemory/core/recall_gate.py +0 -95
- package/src/superlocalmemory/core/recall_pipeline.py +0 -1337
- package/src/superlocalmemory/core/recall_queue.py +0 -377
- package/src/superlocalmemory/core/recall_worker.py +0 -414
- package/src/superlocalmemory/core/registry.py +0 -121
- package/src/superlocalmemory/core/remember_admission.py +0 -161
- package/src/superlocalmemory/core/remember_runtime.py +0 -1190
- package/src/superlocalmemory/core/remote_mode.py +0 -214
- package/src/superlocalmemory/core/reranker_worker.py +0 -338
- package/src/superlocalmemory/core/safe_fs.py +0 -108
- package/src/superlocalmemory/core/scale_autopromote.py +0 -196
- package/src/superlocalmemory/core/scale_engine.py +0 -915
- package/src/superlocalmemory/core/score_contract.py +0 -82
- package/src/superlocalmemory/core/security_primitives.py +0 -672
- package/src/superlocalmemory/core/session_identity.py +0 -98
- package/src/superlocalmemory/core/shadow_router.py +0 -319
- package/src/superlocalmemory/core/slm_disabled.py +0 -85
- package/src/superlocalmemory/core/status_contract.py +0 -108
- package/src/superlocalmemory/core/store_pipeline.py +0 -1404
- package/src/superlocalmemory/core/summarizer.py +0 -200
- package/src/superlocalmemory/core/tier_manager.py +0 -461
- package/src/superlocalmemory/core/topic_signature.py +0 -156
- package/src/superlocalmemory/core/transactions/__init__.py +0 -78
- package/src/superlocalmemory/core/transactions/concrete_owners.py +0 -604
- package/src/superlocalmemory/core/transactions/erasure.py +0 -825
- package/src/superlocalmemory/core/transactions/manifest.py +0 -255
- package/src/superlocalmemory/core/transactions/manifest_key.py +0 -155
- package/src/superlocalmemory/core/transactions/obligations.py +0 -272
- package/src/superlocalmemory/core/transactions/owners.py +0 -114
- package/src/superlocalmemory/core/transactions/reconciler.py +0 -285
- package/src/superlocalmemory/core/transactions/service.py +0 -330
- package/src/superlocalmemory/core/worker_pool.py +0 -377
- package/src/superlocalmemory/core/working_memory.py +0 -288
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -374
- package/src/superlocalmemory/dynamics/eap_scheduler.py +0 -294
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -171
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -227
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/auto_linker.py +0 -308
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +0 -899
- package/src/superlocalmemory/encoding/consolidator.py +0 -472
- package/src/superlocalmemory/encoding/context_generator.py +0 -175
- package/src/superlocalmemory/encoding/emotional.py +0 -189
- package/src/superlocalmemory/encoding/entity_reflexion.py +0 -200
- package/src/superlocalmemory/encoding/entity_resolver.py +0 -687
- package/src/superlocalmemory/encoding/entropy_gate.py +0 -101
- package/src/superlocalmemory/encoding/fact_extractor.py +0 -877
- package/src/superlocalmemory/encoding/foresight.py +0 -93
- package/src/superlocalmemory/encoding/graph_builder.py +0 -346
- package/src/superlocalmemory/encoding/observation_builder.py +0 -177
- package/src/superlocalmemory/encoding/prospective_markers.py +0 -262
- package/src/superlocalmemory/encoding/scene_builder.py +0 -410
- package/src/superlocalmemory/encoding/signal_inference.py +0 -90
- package/src/superlocalmemory/encoding/temporal_parser.py +0 -432
- package/src/superlocalmemory/encoding/temporal_validator.py +0 -572
- package/src/superlocalmemory/encoding/type_router.py +0 -237
- package/src/superlocalmemory/evaluation/__init__.py +0 -13
- package/src/superlocalmemory/evaluation/calibration.py +0 -308
- package/src/superlocalmemory/evolution/__init__.py +0 -29
- package/src/superlocalmemory/evolution/blind_verifier.py +0 -122
- package/src/superlocalmemory/evolution/budget.py +0 -356
- package/src/superlocalmemory/evolution/evolution_store.py +0 -619
- package/src/superlocalmemory/evolution/llm_dispatch.py +0 -559
- package/src/superlocalmemory/evolution/model_selection.py +0 -175
- package/src/superlocalmemory/evolution/mutation_generator.py +0 -226
- package/src/superlocalmemory/evolution/skill_activator.py +0 -270
- package/src/superlocalmemory/evolution/skill_evolver.py +0 -928
- package/src/superlocalmemory/evolution/triggers.py +0 -376
- package/src/superlocalmemory/evolution/types.py +0 -114
- package/src/superlocalmemory/graph/__init__.py +0 -9
- package/src/superlocalmemory/graph/cozo_adjacency.py +0 -122
- package/src/superlocalmemory/graph/cozo_backend.py +0 -751
- package/src/superlocalmemory/hooks/__init__.py +0 -3
- package/src/superlocalmemory/hooks/_outcome_common.py +0 -523
- package/src/superlocalmemory/hooks/adapter_base.py +0 -347
- package/src/superlocalmemory/hooks/antigravity_adapter.py +0 -171
- package/src/superlocalmemory/hooks/auto_capture.py +0 -133
- package/src/superlocalmemory/hooks/auto_invoker.py +0 -521
- package/src/superlocalmemory/hooks/auto_parameterize.py +0 -147
- package/src/superlocalmemory/hooks/auto_recall.py +0 -191
- package/src/superlocalmemory/hooks/auto_recall_hook.py +0 -251
- package/src/superlocalmemory/hooks/before_web_hook.py +0 -131
- package/src/superlocalmemory/hooks/claude_code_hooks.py +0 -637
- package/src/superlocalmemory/hooks/codex_assets.py +0 -251
- package/src/superlocalmemory/hooks/codex_hooks.py +0 -186
- package/src/superlocalmemory/hooks/context_payload.py +0 -311
- package/src/superlocalmemory/hooks/copilot_adapter.py +0 -208
- package/src/superlocalmemory/hooks/cross_platform_connector.py +0 -90
- package/src/superlocalmemory/hooks/cursor_adapter.py +0 -173
- package/src/superlocalmemory/hooks/hook_daemon.py +0 -295
- package/src/superlocalmemory/hooks/hook_handlers.py +0 -822
- package/src/superlocalmemory/hooks/ide_connector.py +0 -246
- package/src/superlocalmemory/hooks/memory_protocol.py +0 -158
- package/src/superlocalmemory/hooks/portable_kit.py +0 -755
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +0 -183
- package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +0 -351
- package/src/superlocalmemory/hooks/prewarm_auth.py +0 -187
- package/src/superlocalmemory/hooks/rules_engine.py +0 -99
- package/src/superlocalmemory/hooks/session_registry.py +0 -330
- package/src/superlocalmemory/hooks/stop_outcome_hook.py +0 -138
- package/src/superlocalmemory/hooks/sync_loop.py +0 -114
- package/src/superlocalmemory/hooks/topic_shift_hook.py +0 -302
- package/src/superlocalmemory/hooks/user_prompt_hook.py +0 -131
- package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +0 -210
- package/src/superlocalmemory/infra/__init__.py +0 -3
- package/src/superlocalmemory/infra/auth_middleware.py +0 -145
- package/src/superlocalmemory/infra/backup.py +0 -974
- package/src/superlocalmemory/infra/backup_obligations.py +0 -423
- package/src/superlocalmemory/infra/cache_manager.py +0 -267
- package/src/superlocalmemory/infra/cloud_backup.py +0 -788
- package/src/superlocalmemory/infra/daemon_identity.py +0 -300
- package/src/superlocalmemory/infra/data_root.py +0 -238
- package/src/superlocalmemory/infra/event_bus.py +0 -637
- package/src/superlocalmemory/infra/local_diagnostics.py +0 -327
- package/src/superlocalmemory/infra/pid_manager.py +0 -193
- package/src/superlocalmemory/infra/process_identity.py +0 -180
- package/src/superlocalmemory/infra/process_reaper.py +0 -624
- package/src/superlocalmemory/infra/rate_limiter.py +0 -228
- package/src/superlocalmemory/infra/self_heal.py +0 -401
- package/src/superlocalmemory/infra/version_integrity.py +0 -229
- package/src/superlocalmemory/ingestion/__init__.py +0 -13
- package/src/superlocalmemory/ingestion/adapter_manager.py +0 -255
- package/src/superlocalmemory/ingestion/base_adapter.py +0 -171
- package/src/superlocalmemory/ingestion/calendar_adapter.py +0 -349
- package/src/superlocalmemory/ingestion/credentials.py +0 -125
- package/src/superlocalmemory/ingestion/gmail_adapter.py +0 -378
- package/src/superlocalmemory/ingestion/parsers.py +0 -100
- package/src/superlocalmemory/ingestion/transcript_adapter.py +0 -161
- package/src/superlocalmemory/integrations/__init__.py +0 -1
- package/src/superlocalmemory/integrations/bounded_loops_mcp.py +0 -431
- package/src/superlocalmemory/integrations/bounded_loops_v051.py +0 -236
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +0 -172
- package/src/superlocalmemory/learning/arm_catalog.py +0 -97
- package/src/superlocalmemory/learning/assertion_miner.py +0 -403
- package/src/superlocalmemory/learning/bandit.py +0 -654
- package/src/superlocalmemory/learning/bandit_cache.py +0 -131
- package/src/superlocalmemory/learning/behavioral.py +0 -542
- package/src/superlocalmemory/learning/bootstrap.py +0 -298
- package/src/superlocalmemory/learning/consolidation_cycle.py +0 -398
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -115
- package/src/superlocalmemory/learning/consolidation_worker.py +0 -261
- package/src/superlocalmemory/learning/cross_project.py +0 -408
- package/src/superlocalmemory/learning/database.py +0 -698
- package/src/superlocalmemory/learning/dedup_hnsw.py +0 -413
- package/src/superlocalmemory/learning/engagement.py +0 -487
- package/src/superlocalmemory/learning/engagement_features.py +0 -279
- package/src/superlocalmemory/learning/ensemble.py +0 -309
- package/src/superlocalmemory/learning/entity_compiler.py +0 -356
- package/src/superlocalmemory/learning/fact_outcome_joins.py +0 -207
- package/src/superlocalmemory/learning/features.py +0 -138
- package/src/superlocalmemory/learning/feedback.py +0 -724
- package/src/superlocalmemory/learning/forgetting_scheduler.py +0 -375
- package/src/superlocalmemory/learning/hnsw_dedup.py +0 -69
- package/src/superlocalmemory/learning/labeler.py +0 -85
- package/src/superlocalmemory/learning/legacy_migration.py +0 -316
- package/src/superlocalmemory/learning/lightgbm_subprocess.py +0 -236
- package/src/superlocalmemory/learning/memory_merge.py +0 -175
- package/src/superlocalmemory/learning/model_cache.py +0 -267
- package/src/superlocalmemory/learning/model_rollback.py +0 -281
- package/src/superlocalmemory/learning/outcome_queue.py +0 -306
- package/src/superlocalmemory/learning/outcomes.py +0 -286
- package/src/superlocalmemory/learning/pattern_miner.py +0 -465
- package/src/superlocalmemory/learning/pattern_miner_constants.py +0 -90
- package/src/superlocalmemory/learning/pcos.py +0 -291
- package/src/superlocalmemory/learning/project_context.py +0 -366
- package/src/superlocalmemory/learning/propensity.py +0 -131
- package/src/superlocalmemory/learning/ranker.py +0 -300
- package/src/superlocalmemory/learning/ranker_common.py +0 -163
- package/src/superlocalmemory/learning/ranker_retrain_legacy.py +0 -210
- package/src/superlocalmemory/learning/ranker_retrain_online.py +0 -423
- package/src/superlocalmemory/learning/reward.py +0 -888
- package/src/superlocalmemory/learning/reward_archive.py +0 -223
- package/src/superlocalmemory/learning/reward_boost.py +0 -211
- package/src/superlocalmemory/learning/reward_from_outcomes.py +0 -365
- package/src/superlocalmemory/learning/reward_model.py +0 -144
- package/src/superlocalmemory/learning/reward_proxy.py +0 -578
- package/src/superlocalmemory/learning/shadow_test.py +0 -524
- package/src/superlocalmemory/learning/signal_kinds.py +0 -79
- package/src/superlocalmemory/learning/signal_worker.py +0 -268
- package/src/superlocalmemory/learning/signals.py +0 -646
- package/src/superlocalmemory/learning/skill_performance_miner.py +0 -422
- package/src/superlocalmemory/learning/source_quality.py +0 -828
- package/src/superlocalmemory/learning/trigram_index.py +0 -548
- package/src/superlocalmemory/learning/workflows.py +0 -309
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +0 -364
- package/src/superlocalmemory/loops/__init__.py +0 -58
- package/src/superlocalmemory/loops/budget.py +0 -58
- package/src/superlocalmemory/loops/engine.py +0 -174
- package/src/superlocalmemory/loops/ledger.py +0 -298
- package/src/superlocalmemory/loops/models.py +0 -152
- package/src/superlocalmemory/loops/rules.py +0 -52
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/ebbinghaus.py +0 -352
- package/src/superlocalmemory/math/fisher.py +0 -356
- package/src/superlocalmemory/math/fisher_quantized.py +0 -255
- package/src/superlocalmemory/math/hopfield.py +0 -282
- package/src/superlocalmemory/math/langevin.py +0 -411
- package/src/superlocalmemory/math/polar_quant.py +0 -414
- package/src/superlocalmemory/math/qjl.py +0 -115
- package/src/superlocalmemory/math/sheaf.py +0 -261
- package/src/superlocalmemory/math/turbo_quant.py +0 -318
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/_daemon_proxy.py +0 -203
- package/src/superlocalmemory/mcp/_pool_adapter.py +0 -181
- package/src/superlocalmemory/mcp/_stdin_guard.py +0 -60
- package/src/superlocalmemory/mcp/agent_context.py +0 -115
- package/src/superlocalmemory/mcp/cli_fallback.py +0 -602
- package/src/superlocalmemory/mcp/http_transport.py +0 -85
- package/src/superlocalmemory/mcp/profiles.py +0 -154
- package/src/superlocalmemory/mcp/resources.py +0 -281
- package/src/superlocalmemory/mcp/server.py +0 -480
- package/src/superlocalmemory/mcp/session_binding.py +0 -98
- package/src/superlocalmemory/mcp/shared.py +0 -112
- package/src/superlocalmemory/mcp/tools.py +0 -18
- package/src/superlocalmemory/mcp/tools_active.py +0 -958
- package/src/superlocalmemory/mcp/tools_brain.py +0 -298
- package/src/superlocalmemory/mcp/tools_code_graph.py +0 -1717
- package/src/superlocalmemory/mcp/tools_context.py +0 -239
- package/src/superlocalmemory/mcp/tools_core.py +0 -1112
- package/src/superlocalmemory/mcp/tools_evolution.py +0 -343
- package/src/superlocalmemory/mcp/tools_learning.py +0 -393
- package/src/superlocalmemory/mcp/tools_loops.py +0 -345
- package/src/superlocalmemory/mcp/tools_mesh.py +0 -429
- package/src/superlocalmemory/mcp/tools_ops.py +0 -115
- package/src/superlocalmemory/mcp/tools_optimize.py +0 -322
- package/src/superlocalmemory/mcp/tools_summaries.py +0 -147
- package/src/superlocalmemory/mcp/tools_v28.py +0 -292
- package/src/superlocalmemory/mcp/tools_v3.py +0 -398
- package/src/superlocalmemory/mcp/tools_v33.py +0 -507
- package/src/superlocalmemory/mesh/__init__.py +0 -12
- package/src/superlocalmemory/mesh/broker.py +0 -812
- package/src/superlocalmemory/mesh/broker_security.py +0 -470
- package/src/superlocalmemory/mesh/discovery.py +0 -365
- package/src/superlocalmemory/mesh/lock_protocol.py +0 -313
- package/src/superlocalmemory/mesh/node_identity.py +0 -97
- package/src/superlocalmemory/mesh/outbox_remote.py +0 -429
- package/src/superlocalmemory/mesh/remote_sync.py +0 -829
- package/src/superlocalmemory/mesh/state_sync.py +0 -286
- package/src/superlocalmemory/migrations/__init__.py +0 -5
- package/src/superlocalmemory/migrations/v3_4_25_to_v3_4_26.py +0 -144
- package/src/superlocalmemory/optimize/NOTICE +0 -6
- package/src/superlocalmemory/optimize/__init__.py +0 -0
- package/src/superlocalmemory/optimize/adapters/__init__.py +0 -68
- package/src/superlocalmemory/optimize/adapters/_agent_registry.py +0 -120
- package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +0 -112
- package/src/superlocalmemory/optimize/adapters/openai_adapter.py +0 -122
- package/src/superlocalmemory/optimize/adapters/wrap.py +0 -228
- package/src/superlocalmemory/optimize/cache/__init__.py +0 -31
- package/src/superlocalmemory/optimize/cache/boundary_store.py +0 -488
- package/src/superlocalmemory/optimize/cache/centroid_store.py +0 -199
- package/src/superlocalmemory/optimize/cache/context_key.py +0 -67
- package/src/superlocalmemory/optimize/cache/exact.py +0 -88
- package/src/superlocalmemory/optimize/cache/invalidation.py +0 -36
- package/src/superlocalmemory/optimize/cache/key_builder.py +0 -111
- package/src/superlocalmemory/optimize/cache/manager.py +0 -737
- package/src/superlocalmemory/optimize/cache/semantic.py +0 -637
- package/src/superlocalmemory/optimize/cache/stampede.py +0 -50
- package/src/superlocalmemory/optimize/compress/__init__.py +0 -17
- package/src/superlocalmemory/optimize/compress/align.py +0 -159
- package/src/superlocalmemory/optimize/compress/ccr.py +0 -116
- package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +0 -71
- package/src/superlocalmemory/optimize/compress/router.py +0 -667
- package/src/superlocalmemory/optimize/config/__init__.py +0 -56
- package/src/superlocalmemory/optimize/config/defaults.py +0 -43
- package/src/superlocalmemory/optimize/config/schema.py +0 -327
- package/src/superlocalmemory/optimize/config/store.py +0 -270
- package/src/superlocalmemory/optimize/metrics/__init__.py +0 -8
- package/src/superlocalmemory/optimize/metrics/counters.py +0 -155
- package/src/superlocalmemory/optimize/metrics/estimator.py +0 -87
- package/src/superlocalmemory/optimize/metrics/exporters.py +0 -77
- package/src/superlocalmemory/optimize/metrics/persistence.py +0 -115
- package/src/superlocalmemory/optimize/proxy/__init__.py +0 -28
- package/src/superlocalmemory/optimize/proxy/_helpers.py +0 -730
- package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +0 -375
- package/src/superlocalmemory/optimize/proxy/capture.py +0 -550
- package/src/superlocalmemory/optimize/proxy/gemini_surface.py +0 -528
- package/src/superlocalmemory/optimize/proxy/lifecycle.py +0 -126
- package/src/superlocalmemory/optimize/proxy/openai_surface.py +0 -465
- package/src/superlocalmemory/optimize/proxy/server.py +0 -199
- package/src/superlocalmemory/optimize/proxy/vertex_surface.py +0 -246
- package/src/superlocalmemory/optimize/storage/__init__.py +0 -0
- package/src/superlocalmemory/optimize/storage/db.py +0 -1185
- package/src/superlocalmemory/optimize/storage/schema.py +0 -205
- package/src/superlocalmemory/parameterization/__init__.py +0 -47
- package/src/superlocalmemory/parameterization/cross_project.py +0 -12
- package/src/superlocalmemory/parameterization/pattern_extractor.py +0 -584
- package/src/superlocalmemory/parameterization/pii_filter.py +0 -106
- package/src/superlocalmemory/parameterization/prompt_injector.py +0 -219
- package/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -281
- package/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -542
- package/src/superlocalmemory/parameterization/workflow_miner.py +0 -17
- package/src/superlocalmemory/reliability/__init__.py +0 -45
- package/src/superlocalmemory/reliability/join_liveness.py +0 -301
- package/src/superlocalmemory/reliability/prior_distance.py +0 -243
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +0 -367
- package/src/superlocalmemory/retrieval/ann_index.py +0 -235
- package/src/superlocalmemory/retrieval/bm25_channel.py +0 -451
- package/src/superlocalmemory/retrieval/bridge_discovery.py +0 -253
- package/src/superlocalmemory/retrieval/channel_registry.py +0 -154
- package/src/superlocalmemory/retrieval/channel_status.py +0 -117
- package/src/superlocalmemory/retrieval/engine.py +0 -1615
- package/src/superlocalmemory/retrieval/entity_channel.py +0 -994
- package/src/superlocalmemory/retrieval/forgetting_filter.py +0 -160
- package/src/superlocalmemory/retrieval/fusion.py +0 -81
- package/src/superlocalmemory/retrieval/graph_adjacency.py +0 -219
- package/src/superlocalmemory/retrieval/hopfield_channel.py +0 -465
- package/src/superlocalmemory/retrieval/profile_channel.py +0 -105
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -147
- package/src/superlocalmemory/retrieval/remote_reranker.py +0 -758
- package/src/superlocalmemory/retrieval/reranker.py +0 -674
- package/src/superlocalmemory/retrieval/scope_policy.py +0 -126
- package/src/superlocalmemory/retrieval/semantic_channel.py +0 -638
- package/src/superlocalmemory/retrieval/spreading.py +0 -288
- package/src/superlocalmemory/retrieval/spreading_activation.py +0 -616
- package/src/superlocalmemory/retrieval/strategy.py +0 -248
- package/src/superlocalmemory/retrieval/temporal_channel.py +0 -433
- package/src/superlocalmemory/retrieval/temporal_frame.py +0 -102
- package/src/superlocalmemory/retrieval/temporal_utils.py +0 -122
- package/src/superlocalmemory/retrieval/temporal_validity_filter.py +0 -499
- package/src/superlocalmemory/retrieval/time_window.py +0 -181
- package/src/superlocalmemory/retrieval/vector_store.py +0 -863
- package/src/superlocalmemory/server/__init__.py +0 -1
- package/src/superlocalmemory/server/api.py +0 -310
- package/src/superlocalmemory/server/asset_versions.py +0 -171
- package/src/superlocalmemory/server/bandit_loops.py +0 -158
- package/src/superlocalmemory/server/config_file.py +0 -90
- package/src/superlocalmemory/server/consolidation_runner.py +0 -140
- package/src/superlocalmemory/server/egress_policy.py +0 -258
- package/src/superlocalmemory/server/loopback.py +0 -85
- package/src/superlocalmemory/server/middleware/__init__.py +0 -11
- package/src/superlocalmemory/server/middleware/security_headers.py +0 -144
- package/src/superlocalmemory/server/origin.py +0 -55
- package/src/superlocalmemory/server/profile_runtime.py +0 -515
- package/src/superlocalmemory/server/rbac_enforce.py +0 -194
- package/src/superlocalmemory/server/recall_health.py +0 -343
- package/src/superlocalmemory/server/recall_serializer.py +0 -320
- package/src/superlocalmemory/server/route_mutations.py +0 -104
- package/src/superlocalmemory/server/routes/__init__.py +0 -4
- package/src/superlocalmemory/server/routes/abstraction.py +0 -314
- package/src/superlocalmemory/server/routes/adapters.py +0 -63
- package/src/superlocalmemory/server/routes/agents.py +0 -303
- package/src/superlocalmemory/server/routes/backup.py +0 -869
- package/src/superlocalmemory/server/routes/behavioral.py +0 -659
- package/src/superlocalmemory/server/routes/brain.py +0 -1892
- package/src/superlocalmemory/server/routes/chat.py +0 -393
- package/src/superlocalmemory/server/routes/compliance.py +0 -533
- package/src/superlocalmemory/server/routes/config_api.py +0 -703
- package/src/superlocalmemory/server/routes/data_io.py +0 -329
- package/src/superlocalmemory/server/routes/entity.py +0 -237
- package/src/superlocalmemory/server/routes/events.py +0 -214
- package/src/superlocalmemory/server/routes/evolution.py +0 -510
- package/src/superlocalmemory/server/routes/helpers.py +0 -499
- package/src/superlocalmemory/server/routes/ingest.py +0 -137
- package/src/superlocalmemory/server/routes/insights.py +0 -366
- package/src/superlocalmemory/server/routes/learning.py +0 -834
- package/src/superlocalmemory/server/routes/learning_telemetry.py +0 -154
- package/src/superlocalmemory/server/routes/lifecycle.py +0 -184
- package/src/superlocalmemory/server/routes/memories.py +0 -1661
- package/src/superlocalmemory/server/routes/mesh.py +0 -517
- package/src/superlocalmemory/server/routes/mesh_lock.py +0 -54
- package/src/superlocalmemory/server/routes/mesh_state.py +0 -63
- package/src/superlocalmemory/server/routes/optimize.py +0 -197
- package/src/superlocalmemory/server/routes/prewarm.py +0 -173
- package/src/superlocalmemory/server/routes/profiles.py +0 -292
- package/src/superlocalmemory/server/routes/ratelimit.py +0 -132
- package/src/superlocalmemory/server/routes/rbac.py +0 -366
- package/src/superlocalmemory/server/routes/stats.py +0 -385
- package/src/superlocalmemory/server/routes/tiers.py +0 -222
- package/src/superlocalmemory/server/routes/timeline.py +0 -258
- package/src/superlocalmemory/server/routes/token.py +0 -90
- package/src/superlocalmemory/server/routes/v3_api.py +0 -3023
- package/src/superlocalmemory/server/routes/ws.py +0 -171
- package/src/superlocalmemory/server/security_middleware.py +0 -89
- package/src/superlocalmemory/server/ui.py +0 -354
- package/src/superlocalmemory/server/unified_daemon.py +0 -6326
- package/src/superlocalmemory/server/write_identity.py +0 -195
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/_migration_internals.py +0 -638
- package/src/superlocalmemory/storage/_schema_version.py +0 -174
- package/src/superlocalmemory/storage/access_log.py +0 -170
- package/src/superlocalmemory/storage/admission_codec.py +0 -129
- package/src/superlocalmemory/storage/admission_journal.py +0 -843
- package/src/superlocalmemory/storage/agent_experience.py +0 -546
- package/src/superlocalmemory/storage/backup.py +0 -531
- package/src/superlocalmemory/storage/correction_cases.py +0 -670
- package/src/superlocalmemory/storage/database.py +0 -3180
- package/src/superlocalmemory/storage/deferred_writes.py +0 -209
- package/src/superlocalmemory/storage/embedding_codec.py +0 -200
- package/src/superlocalmemory/storage/embedding_migrator.py +0 -672
- package/src/superlocalmemory/storage/erasure_fence.py +0 -45
- package/src/superlocalmemory/storage/execution_learning.py +0 -285
- package/src/superlocalmemory/storage/external_evidence.py +0 -359
- package/src/superlocalmemory/storage/generation_fence.py +0 -63
- package/src/superlocalmemory/storage/lineage_retention.py +0 -236
- package/src/superlocalmemory/storage/logical_edges.py +0 -86
- package/src/superlocalmemory/storage/memory_write.py +0 -115
- package/src/superlocalmemory/storage/migration_runner.py +0 -895
- package/src/superlocalmemory/storage/migration_v33.py +0 -140
- package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +0 -67
- package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +0 -107
- package/src/superlocalmemory/storage/migrations/M003_migration_log.py +0 -38
- package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +0 -46
- package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +0 -75
- package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +0 -75
- package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +0 -63
- package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +0 -94
- package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +0 -80
- package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +0 -87
- package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +0 -72
- package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +0 -55
- package/src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py +0 -45
- package/src/superlocalmemory/storage/migrations/M015_add_pinned_column.py +0 -58
- package/src/superlocalmemory/storage/migrations/M016_add_scope_support.py +0 -120
- package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +0 -79
- package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +0 -120
- package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +0 -54
- package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +0 -52
- package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +0 -108
- package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +0 -86
- package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +0 -194
- package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +0 -87
- package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +0 -90
- package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +0 -136
- package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +0 -163
- package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +0 -305
- package/src/superlocalmemory/storage/migrations/M029_behavioral_history_indexes.py +0 -137
- package/src/superlocalmemory/storage/migrations/M030_entity_explorer_indexes.py +0 -93
- package/src/superlocalmemory/storage/migrations/M031_dead_letter_operations.py +0 -80
- package/src/superlocalmemory/storage/migrations/M032_write_coordinator_admission.py +0 -188
- package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +0 -148
- package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +0 -58
- package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +0 -113
- package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +0 -107
- package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +0 -162
- package/src/superlocalmemory/storage/migrations/M038_learning_feedback_channel.py +0 -77
- package/src/superlocalmemory/storage/migrations/M039_scene_fact_members.py +0 -137
- package/src/superlocalmemory/storage/migrations/M040_agent_experience_receipts.py +0 -254
- package/src/superlocalmemory/storage/migrations/M041_external_evidence_receipts.py +0 -189
- package/src/superlocalmemory/storage/migrations/M042_correction_case_ledger.py +0 -245
- package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +0 -512
- package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +0 -127
- package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +0 -158
- package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +0 -620
- package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +0 -306
- package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +0 -229
- package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +0 -201
- package/src/superlocalmemory/storage/migrations/M050_execution_learning_v2.py +0 -70
- package/src/superlocalmemory/storage/migrations/__init__.py +0 -103
- package/src/superlocalmemory/storage/migrations.py +0 -333
- package/src/superlocalmemory/storage/models.py +0 -500
- package/src/superlocalmemory/storage/projection_outbox.py +0 -346
- package/src/superlocalmemory/storage/quantized_store.py +0 -280
- package/src/superlocalmemory/storage/read_connection.py +0 -115
- package/src/superlocalmemory/storage/retention_policy.py +0 -860
- package/src/superlocalmemory/storage/schema.py +0 -1108
- package/src/superlocalmemory/storage/schema_code_graph.py +0 -282
- package/src/superlocalmemory/storage/schema_v32.py +0 -382
- package/src/superlocalmemory/storage/schema_v3410.py +0 -159
- package/src/superlocalmemory/storage/schema_v3411.py +0 -149
- package/src/superlocalmemory/storage/schema_v343.py +0 -315
- package/src/superlocalmemory/storage/schema_v345.py +0 -109
- package/src/superlocalmemory/storage/schema_v347.py +0 -140
- package/src/superlocalmemory/storage/sqlite_vectors.py +0 -169
- package/src/superlocalmemory/storage/v2_migrator.py +0 -466
- package/src/superlocalmemory/storage/write_coordinator.py +0 -949
- package/src/superlocalmemory/storage/write_lock.py +0 -88
- package/src/superlocalmemory/summaries/__init__.py +0 -37
- package/src/superlocalmemory/summaries/base.py +0 -267
- package/src/superlocalmemory/summaries/daily_reflection.py +0 -340
- package/src/superlocalmemory/summaries/non_answer.py +0 -223
- package/src/superlocalmemory/summaries/project_work_log.py +0 -440
- package/src/superlocalmemory/summaries/session_summary.py +0 -311
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +0 -171
- package/src/superlocalmemory/trust/provenance.py +0 -124
- package/src/superlocalmemory/trust/scorer.py +0 -413
- package/src/superlocalmemory/trust/signals.py +0 -153
- package/src/superlocalmemory/ui/assets/slm-icon-white.svg +0 -64
- package/src/superlocalmemory/ui/assets/slm-icon.svg +0 -36
- package/src/superlocalmemory/ui/css/brain.css +0 -409
- package/src/superlocalmemory/ui/css/design-system.css +0 -696
- package/src/superlocalmemory/ui/css/legacy-dashboard.css +0 -663
- package/src/superlocalmemory/ui/css/neural-glass.css +0 -1599
- package/src/superlocalmemory/ui/css/od-bridge.css +0 -158
- package/src/superlocalmemory/ui/favicon.svg +0 -36
- package/src/superlocalmemory/ui/index.html +0 -1638
- package/src/superlocalmemory/ui/js/agents.js +0 -192
- package/src/superlocalmemory/ui/js/auto-settings.js +0 -624
- package/src/superlocalmemory/ui/js/brain.js +0 -1400
- package/src/superlocalmemory/ui/js/clusters.js +0 -326
- package/src/superlocalmemory/ui/js/compliance.js +0 -307
- package/src/superlocalmemory/ui/js/core.js +0 -566
- package/src/superlocalmemory/ui/js/dashboard.js +0 -503
- package/src/superlocalmemory/ui/js/event-delegation.js +0 -113
- package/src/superlocalmemory/ui/js/events.js +0 -178
- package/src/superlocalmemory/ui/js/fact-detail.js +0 -142
- package/src/superlocalmemory/ui/js/feedback.js +0 -339
- package/src/superlocalmemory/ui/js/graph-event-bus.js +0 -83
- package/src/superlocalmemory/ui/js/graph-filters.js +0 -220
- package/src/superlocalmemory/ui/js/graph-ui.js +0 -214
- package/src/superlocalmemory/ui/js/ide-status.js +0 -115
- package/src/superlocalmemory/ui/js/init.js +0 -54
- package/src/superlocalmemory/ui/js/knowledge-graph.js +0 -945
- package/src/superlocalmemory/ui/js/lifecycle.js +0 -387
- package/src/superlocalmemory/ui/js/math-health.js +0 -114
- package/src/superlocalmemory/ui/js/memories.js +0 -394
- package/src/superlocalmemory/ui/js/memory-chat.js +0 -371
- package/src/superlocalmemory/ui/js/memory-timeline.js +0 -265
- package/src/superlocalmemory/ui/js/modal.js +0 -733
- package/src/superlocalmemory/ui/js/ng-entities.js +0 -298
- package/src/superlocalmemory/ui/js/ng-health.js +0 -208
- package/src/superlocalmemory/ui/js/ng-ingestion.js +0 -203
- package/src/superlocalmemory/ui/js/ng-mesh.js +0 -374
- package/src/superlocalmemory/ui/js/ng-shell.js +0 -524
- package/src/superlocalmemory/ui/js/ng-skills.js +0 -663
- package/src/superlocalmemory/ui/js/od-agents.js +0 -588
- package/src/superlocalmemory/ui/js/od-auth-gate.js +0 -257
- package/src/superlocalmemory/ui/js/od-backup.js +0 -878
- package/src/superlocalmemory/ui/js/od-boundedloops.js +0 -324
- package/src/superlocalmemory/ui/js/od-brain.js +0 -1095
- package/src/superlocalmemory/ui/js/od-compliance-ext.js +0 -301
- package/src/superlocalmemory/ui/js/od-components.js +0 -147
- package/src/superlocalmemory/ui/js/od-entities.js +0 -622
- package/src/superlocalmemory/ui/js/od-graph.js +0 -776
- package/src/superlocalmemory/ui/js/od-health.js +0 -579
- package/src/superlocalmemory/ui/js/od-mcp.js +0 -508
- package/src/superlocalmemory/ui/js/od-memories.js +0 -1499
- package/src/superlocalmemory/ui/js/od-mesh.js +0 -645
- package/src/superlocalmemory/ui/js/od-operations.js +0 -1268
- package/src/superlocalmemory/ui/js/od-ops-health.js +0 -417
- package/src/superlocalmemory/ui/js/od-optimize.js +0 -828
- package/src/superlocalmemory/ui/js/od-settings.js +0 -1275
- package/src/superlocalmemory/ui/js/od-shell.js +0 -819
- package/src/superlocalmemory/ui/js/od-skills.js +0 -600
- package/src/superlocalmemory/ui/js/od-team.js +0 -265
- package/src/superlocalmemory/ui/js/optimize.js +0 -191
- package/src/superlocalmemory/ui/js/profiles.js +0 -362
- package/src/superlocalmemory/ui/js/quick-actions.js +0 -334
- package/src/superlocalmemory/ui/js/recall-lab.js +0 -373
- package/src/superlocalmemory/ui/js/search.js +0 -86
- package/src/superlocalmemory/ui/js/settings.js +0 -556
- package/src/superlocalmemory/ui/js/timeline.js +0 -62
- package/src/superlocalmemory/ui/js/trust-dashboard.js +0 -225
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/bootstrap-icons.css +0 -2018
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap.bundle.min.js +0 -7
- package/src/superlocalmemory/ui/vendor/bootstrap.min.css +0 -6
- package/src/superlocalmemory/ui/vendor/d3.v7.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology-library.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology.umd.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/inter-ui/inter-variable.min.css +0 -8
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable-Italic.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/sigma.min.js +0 -1
- package/src/superlocalmemory/vector/__init__.py +0 -9
- package/src/superlocalmemory/vector/lancedb_backend.py +0 -366
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
# Part of SuperLocalMemory v3.4.22 — LLD-01 §4.5
|
|
4
|
-
|
|
5
|
-
"""Authentication primitives for the /internal/prewarm daemon route.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Four gates, applied in order, BEFORE any engine work:
|
|
9
|
-
1. Loopback-only — client address must be 127.0.0.1 / ::1.
|
|
10
|
-
2. Origin-header CSRF guard — browsers always send Origin on CORS
|
|
11
|
-
requests; hooks using stdlib urllib do not. Present Origin ⇒ reject.
|
|
12
|
-
3. Install-token match — X-SLM-Hook-Token constant-time compared to
|
|
13
|
-
the bytes stored at ``~/.superlocalmemory/.install_token``.
|
|
14
|
-
4. Body-size cap — requests > ``MAX_BODY_BYTES`` rejected upfront.
|
|
15
|
-
|
|
16
|
-
Framework-agnostic. The FastAPI route composes these primitives; tests
|
|
17
|
-
exercise them without starting an HTTP server.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
from __future__ import annotations
|
|
21
|
-
|
|
22
|
-
from dataclasses import dataclass
|
|
23
|
-
from typing import Mapping
|
|
24
|
-
|
|
25
|
-
from superlocalmemory.core.security_primitives import verify_install_token
|
|
26
|
-
|
|
27
|
-
# Headers we consider equivalent for the install-token lookup. Covers the
|
|
28
|
-
# common normalizations (exact, lowercase, title-case).
|
|
29
|
-
_TOKEN_HEADER_VARIANTS: tuple[str, ...] = (
|
|
30
|
-
"X-SLM-Hook-Token",
|
|
31
|
-
"x-slm-hook-token",
|
|
32
|
-
"X-Slm-Hook-Token",
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
_ORIGIN_HEADER_VARIANTS: tuple[str, ...] = ("Origin", "origin")
|
|
36
|
-
|
|
37
|
-
# Loopback addresses accepted by LLD-01. ``localhost`` is NOT included per
|
|
38
|
-
# SEC-01-02 — we want literal IPs only to avoid DNS-based bypass tricks.
|
|
39
|
-
# Note: ::ffff:127.x.x.x is handled dynamically via ipaddress.ip_address()
|
|
40
|
-
# in is_loopback() below to cover dual-stack container deployments (#90).
|
|
41
|
-
_LOOPBACK_ADDRS: frozenset[str] = frozenset({"127.0.0.1", "::1"})
|
|
42
|
-
|
|
43
|
-
# Body-size cap: LLD-01 §4.5 step 4 → 8 KB.
|
|
44
|
-
MAX_BODY_BYTES: int = 8 * 1024
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@dataclass(frozen=True, slots=True)
|
|
48
|
-
class AuthDecision:
|
|
49
|
-
"""Outcome of ``authorize``.
|
|
50
|
-
|
|
51
|
-
- ``allowed`` — True when the request passes every gate.
|
|
52
|
-
- ``status`` — suggested HTTP status when ``allowed`` is False
|
|
53
|
-
(``200`` otherwise).
|
|
54
|
-
- ``reason`` — short machine-readable tag. Never echoes secrets.
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
allowed: bool
|
|
58
|
-
status: int
|
|
59
|
-
reason: str = ""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# ---------------------------------------------------------------------------
|
|
63
|
-
# Gate 1: Loopback-only
|
|
64
|
-
# ---------------------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def is_loopback(client_host: str) -> bool:
|
|
68
|
-
"""Return True iff ``client_host`` is an accepted loopback literal.
|
|
69
|
-
|
|
70
|
-
Deliberately excludes ``"localhost"`` per SEC-01-02 — /internal/prewarm
|
|
71
|
-
callers are in-process hooks that always connect to a literal IP, so
|
|
72
|
-
hostname aliases are rejected to prevent DNS-based bypass tricks.
|
|
73
|
-
|
|
74
|
-
Accepts IPv4-mapped IPv6 loopback (``::ffff:127.x.x.x``) for dual-stack
|
|
75
|
-
correctness (issue #90), while still excluding ``"localhost"``.
|
|
76
|
-
"""
|
|
77
|
-
if not isinstance(client_host, str) or not client_host:
|
|
78
|
-
return False
|
|
79
|
-
if client_host in _LOOPBACK_ADDRS:
|
|
80
|
-
return True
|
|
81
|
-
# Handle IPv4-mapped IPv6 loopback (::ffff:127.x.x.x) — dual-stack fix.
|
|
82
|
-
# Intentionally NOT accepting "localhost" (SEC-01-02 preserved).
|
|
83
|
-
try:
|
|
84
|
-
import ipaddress as _ipa
|
|
85
|
-
ip = _ipa.ip_address(client_host)
|
|
86
|
-
return ip.is_loopback
|
|
87
|
-
except ValueError:
|
|
88
|
-
return False
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# ---------------------------------------------------------------------------
|
|
92
|
-
# Gate 2: Origin CSRF guard
|
|
93
|
-
# ---------------------------------------------------------------------------
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def is_browser_originated(headers: Mapping[str, str]) -> bool:
|
|
97
|
-
"""True if the request carries a non-empty ``Origin`` header.
|
|
98
|
-
|
|
99
|
-
Defensive against accidental case variants. We treat an explicit empty
|
|
100
|
-
Origin as non-browser per LLD-01 §4.5 — real browsers always send a
|
|
101
|
-
non-empty origin on cross-origin requests.
|
|
102
|
-
"""
|
|
103
|
-
if not headers:
|
|
104
|
-
return False
|
|
105
|
-
for name in _ORIGIN_HEADER_VARIANTS:
|
|
106
|
-
val = headers.get(name)
|
|
107
|
-
if val:
|
|
108
|
-
return True
|
|
109
|
-
return False
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
# ---------------------------------------------------------------------------
|
|
113
|
-
# Gate 3: Install-token
|
|
114
|
-
# ---------------------------------------------------------------------------
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def _extract_token(headers: Mapping[str, str]) -> str:
|
|
118
|
-
"""Return the presented X-SLM-Hook-Token across casing variants."""
|
|
119
|
-
if not headers:
|
|
120
|
-
return ""
|
|
121
|
-
for name in _TOKEN_HEADER_VARIANTS:
|
|
122
|
-
val = headers.get(name)
|
|
123
|
-
if val:
|
|
124
|
-
return val
|
|
125
|
-
return ""
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# ---------------------------------------------------------------------------
|
|
129
|
-
# Gate 4: Body size
|
|
130
|
-
# ---------------------------------------------------------------------------
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def check_body_size(body: bytes) -> tuple[bool, str]:
|
|
134
|
-
"""Verify request body is within ``MAX_BODY_BYTES``.
|
|
135
|
-
|
|
136
|
-
Returns ``(True, "")`` on pass and ``(False, reason)`` on fail.
|
|
137
|
-
"""
|
|
138
|
-
if not isinstance(body, (bytes, bytearray)):
|
|
139
|
-
return False, "body must be bytes"
|
|
140
|
-
if len(body) > MAX_BODY_BYTES:
|
|
141
|
-
return False, f"body size {len(body)} exceeds {MAX_BODY_BYTES}"
|
|
142
|
-
return True, ""
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
# ---------------------------------------------------------------------------
|
|
146
|
-
# Composite authorize()
|
|
147
|
-
# ---------------------------------------------------------------------------
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def authorize(
|
|
151
|
-
*,
|
|
152
|
-
client_host: str,
|
|
153
|
-
headers: Mapping[str, str],
|
|
154
|
-
) -> AuthDecision:
|
|
155
|
-
"""Run gates 1 → 2 → 3 in order and return the first failure.
|
|
156
|
-
|
|
157
|
-
Order rationale:
|
|
158
|
-
- Loopback check runs first so we reject off-host traffic with 403
|
|
159
|
-
before touching any user-supplied header material.
|
|
160
|
-
- Origin check runs second to neutralize browser-driven CSRF even
|
|
161
|
-
when the attacker somehow obtained the install token.
|
|
162
|
-
- Token check runs last; constant-time compared via
|
|
163
|
-
``verify_install_token``.
|
|
164
|
-
"""
|
|
165
|
-
if not is_loopback(client_host):
|
|
166
|
-
return AuthDecision(False, 403, "loopback only")
|
|
167
|
-
|
|
168
|
-
if is_browser_originated(headers):
|
|
169
|
-
return AuthDecision(False, 403, "origin header not allowed")
|
|
170
|
-
|
|
171
|
-
token = _extract_token(headers)
|
|
172
|
-
if not token:
|
|
173
|
-
return AuthDecision(False, 401, "unauthorized: missing token")
|
|
174
|
-
if not verify_install_token(token):
|
|
175
|
-
return AuthDecision(False, 401, "unauthorized: token mismatch")
|
|
176
|
-
|
|
177
|
-
return AuthDecision(True, 200, "")
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
__all__ = (
|
|
181
|
-
"AuthDecision",
|
|
182
|
-
"MAX_BODY_BYTES",
|
|
183
|
-
"authorize",
|
|
184
|
-
"check_body_size",
|
|
185
|
-
"is_browser_originated",
|
|
186
|
-
"is_loopback",
|
|
187
|
-
)
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
# Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
|
|
4
|
-
|
|
5
|
-
"""Rules engine for configurable auto-capture and auto-recall behavior."""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
import logging
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
15
|
-
|
|
16
|
-
DEFAULT_RULES = {
|
|
17
|
-
"auto_recall": {
|
|
18
|
-
"enabled": True,
|
|
19
|
-
"on_session_start": True,
|
|
20
|
-
"on_every_prompt": False,
|
|
21
|
-
"max_memories_injected": 10,
|
|
22
|
-
"relevance_threshold": 0.3,
|
|
23
|
-
},
|
|
24
|
-
"auto_capture": {
|
|
25
|
-
"enabled": True,
|
|
26
|
-
"capture_decisions": True,
|
|
27
|
-
"capture_bugs": True,
|
|
28
|
-
"capture_preferences": True,
|
|
29
|
-
"capture_session_summary": True,
|
|
30
|
-
"min_confidence": 0.5,
|
|
31
|
-
},
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class RulesEngine:
|
|
36
|
-
"""Manage configurable rules for auto-capture and auto-recall."""
|
|
37
|
-
|
|
38
|
-
def __init__(self, config: dict | None = None, config_path: Path | None = None):
|
|
39
|
-
if config:
|
|
40
|
-
self._rules = {**DEFAULT_RULES, **config}
|
|
41
|
-
elif config_path and config_path.exists():
|
|
42
|
-
data = json.loads(config_path.read_text())
|
|
43
|
-
self._rules = {**DEFAULT_RULES, **data.get("rules", {})}
|
|
44
|
-
else:
|
|
45
|
-
self._rules = dict(DEFAULT_RULES)
|
|
46
|
-
|
|
47
|
-
def should_capture(self, category: str, confidence: float) -> bool:
|
|
48
|
-
"""Check if a category should be captured based on rules."""
|
|
49
|
-
capture_rules = self._rules.get("auto_capture", {})
|
|
50
|
-
if not capture_rules.get("enabled", True):
|
|
51
|
-
return False
|
|
52
|
-
|
|
53
|
-
category_key = f"capture_{category}s" if not category.endswith("s") else f"capture_{category}"
|
|
54
|
-
if not capture_rules.get(category_key, True):
|
|
55
|
-
return False
|
|
56
|
-
|
|
57
|
-
min_conf = capture_rules.get("min_confidence", 0.5)
|
|
58
|
-
return confidence >= min_conf
|
|
59
|
-
|
|
60
|
-
def should_recall(self, trigger: str) -> bool:
|
|
61
|
-
"""Check if auto-recall should fire for a trigger."""
|
|
62
|
-
recall_rules = self._rules.get("auto_recall", {})
|
|
63
|
-
if not recall_rules.get("enabled", True):
|
|
64
|
-
return False
|
|
65
|
-
|
|
66
|
-
if trigger == "session_start":
|
|
67
|
-
return recall_rules.get("on_session_start", True)
|
|
68
|
-
if trigger == "every_prompt":
|
|
69
|
-
return recall_rules.get("on_every_prompt", False)
|
|
70
|
-
|
|
71
|
-
return True
|
|
72
|
-
|
|
73
|
-
def get_recall_config(self) -> dict:
|
|
74
|
-
"""Get auto-recall configuration."""
|
|
75
|
-
return dict(self._rules.get("auto_recall", DEFAULT_RULES["auto_recall"]))
|
|
76
|
-
|
|
77
|
-
def get_capture_config(self) -> dict:
|
|
78
|
-
"""Get auto-capture configuration."""
|
|
79
|
-
return dict(self._rules.get("auto_capture", DEFAULT_RULES["auto_capture"]))
|
|
80
|
-
|
|
81
|
-
def update_rule(self, section: str, key: str, value: Any) -> None:
|
|
82
|
-
"""Update a specific rule."""
|
|
83
|
-
if section not in self._rules:
|
|
84
|
-
self._rules[section] = {}
|
|
85
|
-
self._rules[section][key] = value
|
|
86
|
-
|
|
87
|
-
def save(self, config_path: Path) -> None:
|
|
88
|
-
"""Save rules to config file."""
|
|
89
|
-
if config_path.exists():
|
|
90
|
-
data = json.loads(config_path.read_text())
|
|
91
|
-
else:
|
|
92
|
-
data = {}
|
|
93
|
-
data["rules"] = self._rules
|
|
94
|
-
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
95
|
-
config_path.write_text(json.dumps(data, indent=2))
|
|
96
|
-
|
|
97
|
-
def to_dict(self) -> dict:
|
|
98
|
-
"""Export rules as dict."""
|
|
99
|
-
return dict(self._rules)
|
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
# Part of SuperLocalMemory v3.4.22 — S9-DASH-10
|
|
4
|
-
|
|
5
|
-
"""Lightweight session registry for cross-process session_id handoff.
|
|
6
|
-
|
|
7
|
-
**Problem.** Claude Code (and Cursor/Antigravity) invoke two separate
|
|
8
|
-
SLM surfaces per user turn:
|
|
9
|
-
|
|
10
|
-
1. ``user_prompt_hook`` — receives ``session_id`` via stdin JSON
|
|
11
|
-
(Claude Code's hook payload). This is the real session id.
|
|
12
|
-
2. MCP ``recall`` tool — invoked by the AI mid-turn. The MCP protocol
|
|
13
|
-
does NOT thread ``CLAUDE_SESSION_ID`` into tool arguments by
|
|
14
|
-
default, so the MCP tool cannot see what session it is serving.
|
|
15
|
-
|
|
16
|
-
Result: ``record_recall`` writes ``pending_outcomes`` with
|
|
17
|
-
``session_id='mcp:mcp_client'`` while the Stop hook queries by the
|
|
18
|
-
real session id — they never match, so cite/edit/dwell signals are
|
|
19
|
-
lost (reaper finalizes everything at neutral 0.5).
|
|
20
|
-
|
|
21
|
-
**Fix (this module).** A simple file-based registry:
|
|
22
|
-
|
|
23
|
-
* ``mark_active(session_id, agent_type, profile_id)`` — called by hooks on
|
|
24
|
-
every prompt/tool event. Writes ``(session_id, agent_type, profile_id,
|
|
25
|
-
ts_ns, pid)``
|
|
26
|
-
to ``~/.superlocalmemory/.active_sessions.json``.
|
|
27
|
-
* ``most_recent_active(agent_type, within_seconds=60)`` — queries the
|
|
28
|
-
registry for the most recently seen session of the named agent.
|
|
29
|
-
MCP uses this as the default when the tool caller omits
|
|
30
|
-
``session_id``.
|
|
31
|
-
|
|
32
|
-
Concurrency: each write is atomic via write-temp + ``os.replace`` (atomic on
|
|
33
|
-
POSIX/Windows), so a concurrent reader never sees a half-written file —
|
|
34
|
-
last-writer-wins. This is best-effort, not lock-serialised: a concurrent
|
|
35
|
-
read-modify-write may lose an interleaved update, which is acceptable because
|
|
36
|
-
the registry only drives session attribution for closed-loop learning, not
|
|
37
|
-
memory correctness. Rollover: entries older than 1 hour are pruned on every
|
|
38
|
-
write. Fail-soft: every error path returns empty or the passed default — the
|
|
39
|
-
learning loop must never crash the hot path.
|
|
40
|
-
|
|
41
|
-
This is not a perfect correlation channel; two Claude sessions
|
|
42
|
-
typing in the same second can race. For single-user workstations
|
|
43
|
-
(the overwhelming SLM case) it is 99%+ accurate.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
from __future__ import annotations
|
|
47
|
-
|
|
48
|
-
import json
|
|
49
|
-
import logging
|
|
50
|
-
import os
|
|
51
|
-
import time
|
|
52
|
-
from pathlib import Path
|
|
53
|
-
from typing import Optional
|
|
54
|
-
|
|
55
|
-
logger = logging.getLogger(__name__)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
_PRUNE_AFTER_SEC = 3600 # 1h — anything older is dead
|
|
59
|
-
|
|
60
|
-
# Keep the public host vocabulary small and stable. Callers can still use an
|
|
61
|
-
# unknown value internally, but the Living Brain must not turn arbitrary hook
|
|
62
|
-
# input into a new UI label or expose a host identifier verbatim.
|
|
63
|
-
_PUBLIC_CLIENT_KINDS = {
|
|
64
|
-
"claude": "claude_code",
|
|
65
|
-
"claude_code": "claude_code",
|
|
66
|
-
"codex": "codex",
|
|
67
|
-
"cursor": "cursor",
|
|
68
|
-
"antigravity": "antigravity",
|
|
69
|
-
"copilot": "copilot",
|
|
70
|
-
"cli": "cli",
|
|
71
|
-
"mcp": "mcp",
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def _registry_file() -> Path:
|
|
76
|
-
from superlocalmemory.infra.data_root import state_path
|
|
77
|
-
|
|
78
|
-
return state_path(".active_sessions.json")
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def _profiles_file() -> Path:
|
|
82
|
-
"""Return the profile cache updated atomically by daemon switches."""
|
|
83
|
-
from superlocalmemory.infra.data_root import state_path
|
|
84
|
-
|
|
85
|
-
return state_path("profiles.json")
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def resolve_active_profile() -> str | None:
|
|
89
|
-
"""Read the canonical active profile without relying on host env wiring.
|
|
90
|
-
|
|
91
|
-
Hooks are separate host processes, so daemon-managed profile changes are
|
|
92
|
-
not reliably reflected in their environment. The profile runtime writes
|
|
93
|
-
this compatibility cache atomically on every successful switch; using it
|
|
94
|
-
keeps ephemeral presence scoped like the durable memory stores.
|
|
95
|
-
"""
|
|
96
|
-
try:
|
|
97
|
-
payload = json.loads(_profiles_file().read_text(encoding="utf-8"))
|
|
98
|
-
if not isinstance(payload, dict):
|
|
99
|
-
return None
|
|
100
|
-
modern_pointer = payload.get("active_profile")
|
|
101
|
-
legacy_pointer = payload.get("active")
|
|
102
|
-
pointer = (
|
|
103
|
-
modern_pointer.strip()
|
|
104
|
-
if isinstance(modern_pointer, str) and modern_pointer.strip()
|
|
105
|
-
else legacy_pointer.strip()
|
|
106
|
-
if isinstance(legacy_pointer, str) and legacy_pointer.strip()
|
|
107
|
-
else None
|
|
108
|
-
)
|
|
109
|
-
if pointer is None:
|
|
110
|
-
return None
|
|
111
|
-
profiles = payload.get("profiles")
|
|
112
|
-
catalog_present = "profiles" in payload
|
|
113
|
-
entries = []
|
|
114
|
-
if isinstance(profiles, list):
|
|
115
|
-
entries = [(None, profile) for profile in profiles]
|
|
116
|
-
elif isinstance(profiles, dict):
|
|
117
|
-
entries = list(profiles.items())
|
|
118
|
-
canonical: list[tuple[str, str | None]] = []
|
|
119
|
-
for key, profile in entries:
|
|
120
|
-
if not isinstance(profile, dict):
|
|
121
|
-
continue
|
|
122
|
-
profile_id = profile.get("profile_id")
|
|
123
|
-
if not isinstance(profile_id, str) or not profile_id.strip():
|
|
124
|
-
profile_id = key if isinstance(key, str) and key.strip() else None
|
|
125
|
-
name = profile.get("name")
|
|
126
|
-
if isinstance(profile_id, str) and profile_id.strip():
|
|
127
|
-
canonical.append((profile_id.strip(), name if isinstance(name, str) else None))
|
|
128
|
-
id_matches = {profile_id for profile_id, _name in canonical if profile_id == pointer}
|
|
129
|
-
if len(id_matches) == 1:
|
|
130
|
-
return id_matches.pop()
|
|
131
|
-
name_matches = {profile_id for profile_id, name in canonical if name == pointer}
|
|
132
|
-
if len(name_matches) == 1:
|
|
133
|
-
return name_matches.pop()
|
|
134
|
-
# The current runtime writes an ``active_profile`` ID even when its
|
|
135
|
-
# catalog has not been materialized yet. With no catalog at all it is
|
|
136
|
-
# the only available authority; a partially present catalog instead
|
|
137
|
-
# fails closed to avoid treating an unmapped display name as an ID.
|
|
138
|
-
if not catalog_present and isinstance(modern_pointer, str) and modern_pointer.strip():
|
|
139
|
-
return modern_pointer.strip()
|
|
140
|
-
except (OSError, TypeError, ValueError):
|
|
141
|
-
pass
|
|
142
|
-
return None
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def _now_ns() -> int:
|
|
146
|
-
return time.time_ns()
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def _load() -> dict:
|
|
150
|
-
try:
|
|
151
|
-
registry_file = _registry_file()
|
|
152
|
-
if not registry_file.exists():
|
|
153
|
-
return {}
|
|
154
|
-
return json.loads(registry_file.read_text(encoding="utf-8"))
|
|
155
|
-
except Exception:
|
|
156
|
-
return {}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def _save(data: dict) -> None:
|
|
160
|
-
try:
|
|
161
|
-
registry_file = _registry_file()
|
|
162
|
-
registry_file.parent.mkdir(parents=True, exist_ok=True)
|
|
163
|
-
tmp = registry_file.with_suffix(
|
|
164
|
-
f".{os.getpid()}.{time.time_ns()}.tmp",
|
|
165
|
-
)
|
|
166
|
-
tmp.write_text(json.dumps(data), encoding="utf-8")
|
|
167
|
-
os.replace(tmp, registry_file)
|
|
168
|
-
try:
|
|
169
|
-
os.chmod(registry_file, 0o600)
|
|
170
|
-
except OSError:
|
|
171
|
-
pass
|
|
172
|
-
except Exception as exc: # pragma: no cover — defensive
|
|
173
|
-
logger.debug("session_registry save failed: %s", exc)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
def _prune(data: dict) -> dict:
|
|
177
|
-
cutoff_ns = _now_ns() - (_PRUNE_AFTER_SEC * 1_000_000_000)
|
|
178
|
-
return {
|
|
179
|
-
sid: row for sid, row in data.items()
|
|
180
|
-
if isinstance(row, dict) and int(row.get("ts_ns", 0)) >= cutoff_ns
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def mark_active(
|
|
185
|
-
session_id: str,
|
|
186
|
-
agent_type: str = "claude",
|
|
187
|
-
profile_id: str | None = None,
|
|
188
|
-
) -> None:
|
|
189
|
-
"""Record ``session_id`` keyed by the CALLING process PID.
|
|
190
|
-
|
|
191
|
-
Called from UserPromptSubmit + PostToolUse hooks — those hooks run
|
|
192
|
-
INSIDE the Claude Code / IDE process. So ``os.getpid()`` is the
|
|
193
|
-
IDE's PID. The MCP server spawned BY that same IDE process has
|
|
194
|
-
``os.getppid() == IDE_PID``. Keying by PID means two parallel
|
|
195
|
-
Claude Code windows never collide — each MCP server reads only
|
|
196
|
-
its own parent's entry.
|
|
197
|
-
|
|
198
|
-
Hot-path safe — returns within <2 ms on a warm cache. Never raises.
|
|
199
|
-
"""
|
|
200
|
-
if not session_id or not isinstance(session_id, str):
|
|
201
|
-
return
|
|
202
|
-
try:
|
|
203
|
-
data = _load()
|
|
204
|
-
key = str(os.getpid()) # the IDE / hook process PID
|
|
205
|
-
row = {
|
|
206
|
-
"session_id": session_id,
|
|
207
|
-
"agent_type": agent_type or "unknown",
|
|
208
|
-
"ts_ns": _now_ns(),
|
|
209
|
-
}
|
|
210
|
-
if isinstance(profile_id, str) and profile_id.strip():
|
|
211
|
-
row["profile_id"] = profile_id.strip()
|
|
212
|
-
data[key] = row
|
|
213
|
-
data = _prune(data)
|
|
214
|
-
_save(data)
|
|
215
|
-
except Exception as exc: # pragma: no cover — defensive
|
|
216
|
-
logger.debug("mark_active failed: %s", exc)
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def lookup_by_parent(within_seconds: int = 60) -> Optional[str]:
|
|
220
|
-
"""Return the session_id whose registry key == ``os.getppid()``.
|
|
221
|
-
|
|
222
|
-
Called from the MCP server process. ``os.getppid()`` is the PID of
|
|
223
|
-
the IDE that spawned the MCP server — exactly the same PID that
|
|
224
|
-
the hook used as its key in ``mark_active``. Collision-free across
|
|
225
|
-
multiple parallel Claude Code / IDE sessions.
|
|
226
|
-
"""
|
|
227
|
-
try:
|
|
228
|
-
parent_key = str(os.getppid())
|
|
229
|
-
data = _load()
|
|
230
|
-
row = data.get(parent_key)
|
|
231
|
-
if not isinstance(row, dict):
|
|
232
|
-
return None
|
|
233
|
-
ts = int(row.get("ts_ns", 0))
|
|
234
|
-
if _now_ns() - ts > within_seconds * 1_000_000_000:
|
|
235
|
-
return None # stale — IDE likely restarted
|
|
236
|
-
return row.get("session_id") or None
|
|
237
|
-
except Exception:
|
|
238
|
-
return None
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
def most_recent_active(
|
|
242
|
-
agent_type: Optional[str] = None,
|
|
243
|
-
within_seconds: int = 60,
|
|
244
|
-
) -> Optional[str]:
|
|
245
|
-
"""Fallback: most-recently-written entry of the given agent_type.
|
|
246
|
-
|
|
247
|
-
Used by surfaces that DON'T have a stable parent-PID linkage (e.g.
|
|
248
|
-
CLI tools invoked ad-hoc). Prefer ``lookup_by_parent`` for MCP.
|
|
249
|
-
"""
|
|
250
|
-
try:
|
|
251
|
-
data = _load()
|
|
252
|
-
if not data:
|
|
253
|
-
return None
|
|
254
|
-
cutoff_ns = _now_ns() - (within_seconds * 1_000_000_000)
|
|
255
|
-
candidates = []
|
|
256
|
-
for _key, row in data.items():
|
|
257
|
-
if not isinstance(row, dict):
|
|
258
|
-
continue
|
|
259
|
-
ts = int(row.get("ts_ns", 0))
|
|
260
|
-
if ts < cutoff_ns:
|
|
261
|
-
continue
|
|
262
|
-
if agent_type and row.get("agent_type") != agent_type:
|
|
263
|
-
continue
|
|
264
|
-
sid = row.get("session_id")
|
|
265
|
-
if sid:
|
|
266
|
-
candidates.append((ts, sid))
|
|
267
|
-
if not candidates:
|
|
268
|
-
return None
|
|
269
|
-
candidates.sort(reverse=True)
|
|
270
|
-
return candidates[0][1]
|
|
271
|
-
except Exception:
|
|
272
|
-
return None
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
def active_client_summary(
|
|
276
|
-
profile_id: str | None = None,
|
|
277
|
-
within_seconds: int = 60,
|
|
278
|
-
) -> list[dict[str, object]]:
|
|
279
|
-
"""Return privacy-safe, recently active hosts for the Living Brain.
|
|
280
|
-
|
|
281
|
-
This is deliberately a *presence* signal, not durable product analytics:
|
|
282
|
-
registry entries expire within an hour and session identifiers never leave
|
|
283
|
-
the local registry. The dashboard therefore distinguishes these active
|
|
284
|
-
clients from configured adapters, which only prove installation.
|
|
285
|
-
"""
|
|
286
|
-
# Compatibility-safe default for any out-of-tree caller that used the
|
|
287
|
-
# original no-argument helper: no profile means no visibility, never a
|
|
288
|
-
# silent cross-profile aggregate.
|
|
289
|
-
if not profile_id:
|
|
290
|
-
return []
|
|
291
|
-
try:
|
|
292
|
-
cutoff_ns = _now_ns() - (max(0, int(within_seconds)) * 1_000_000_000)
|
|
293
|
-
newest_by_kind: dict[str, int] = {}
|
|
294
|
-
for row in _load().values():
|
|
295
|
-
if not isinstance(row, dict):
|
|
296
|
-
continue
|
|
297
|
-
# Entries written before profile attribution are intentionally
|
|
298
|
-
# invisible here: guessing a profile would leak client metadata.
|
|
299
|
-
if str(row.get("profile_id", "")) != profile_id:
|
|
300
|
-
continue
|
|
301
|
-
try:
|
|
302
|
-
ts_ns = int(row.get("ts_ns", 0))
|
|
303
|
-
except (TypeError, ValueError):
|
|
304
|
-
continue
|
|
305
|
-
if ts_ns < cutoff_ns:
|
|
306
|
-
continue
|
|
307
|
-
raw_kind = str(row.get("agent_type", "")).strip().lower()
|
|
308
|
-
kind = _PUBLIC_CLIENT_KINDS.get(raw_kind, "other")
|
|
309
|
-
newest_by_kind[kind] = max(newest_by_kind.get(kind, 0), ts_ns)
|
|
310
|
-
now_ns = _now_ns()
|
|
311
|
-
return [
|
|
312
|
-
{
|
|
313
|
-
"kind": kind,
|
|
314
|
-
"active": True,
|
|
315
|
-
"last_seen_seconds_ago": max(0, int((now_ns - ts_ns) / 1_000_000_000)),
|
|
316
|
-
"source": "session_registry",
|
|
317
|
-
"is_real": True,
|
|
318
|
-
}
|
|
319
|
-
for kind, ts_ns in sorted(newest_by_kind.items())
|
|
320
|
-
]
|
|
321
|
-
except Exception:
|
|
322
|
-
return []
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
def _reset_for_testing() -> None:
|
|
326
|
-
"""TEST-ONLY: wipe registry."""
|
|
327
|
-
try:
|
|
328
|
-
_registry_file().unlink(missing_ok=True)
|
|
329
|
-
except Exception:
|
|
330
|
-
pass
|