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,822 +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
|
-
"""Claude Code hook handlers — minimal-dependency, cross-platform.
|
|
6
|
-
|
|
7
|
-
Handlers use Python stdlib plus the stdlib-only canonical data-root resolver.
|
|
8
|
-
Called via: ``slm hook <start|gate|init-done|checkpoint|stop>``.
|
|
9
|
-
|
|
10
|
-
The main() entry point in cli/main.py has a fast path that dispatches here
|
|
11
|
-
BEFORE argparse or any heavy imports.
|
|
12
|
-
|
|
13
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
import hashlib
|
|
19
|
-
import json
|
|
20
|
-
import os
|
|
21
|
-
import subprocess
|
|
22
|
-
import sys
|
|
23
|
-
import tempfile
|
|
24
|
-
import time
|
|
25
|
-
import urllib.error
|
|
26
|
-
import urllib.request
|
|
27
|
-
from pathlib import Path
|
|
28
|
-
|
|
29
|
-
from superlocalmemory import __version__
|
|
30
|
-
|
|
31
|
-
# ---------------------------------------------------------------------------
|
|
32
|
-
# Cross-platform temp paths
|
|
33
|
-
# ---------------------------------------------------------------------------
|
|
34
|
-
_TMP = tempfile.gettempdir()
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _root_namespace() -> str:
|
|
38
|
-
"""Return the same bounded root identity used by installed gate hooks."""
|
|
39
|
-
from superlocalmemory.infra.data_root import canonical_data_root
|
|
40
|
-
|
|
41
|
-
return hashlib.sha256(
|
|
42
|
-
str(canonical_data_root()).encode("utf-8")
|
|
43
|
-
).hexdigest()[:16]
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class _RootNamespacedTempPath(os.PathLike[str]):
|
|
47
|
-
"""A path-like value that follows environment root switches at use time."""
|
|
48
|
-
|
|
49
|
-
def __init__(self, stem: str) -> None:
|
|
50
|
-
self._stem = stem
|
|
51
|
-
|
|
52
|
-
def __fspath__(self) -> str:
|
|
53
|
-
return os.path.join(_TMP, f"{self._stem}-{_root_namespace()}")
|
|
54
|
-
|
|
55
|
-
def __str__(self) -> str:
|
|
56
|
-
return self.__fspath__()
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
_MARKER: str | os.PathLike[str] = _RootNamespacedTempPath(
|
|
60
|
-
"slm-session-initialized"
|
|
61
|
-
)
|
|
62
|
-
_START_TIME: str | os.PathLike[str] = _RootNamespacedTempPath(
|
|
63
|
-
"slm-session-start-time"
|
|
64
|
-
)
|
|
65
|
-
_ACTIVITY_LOG: str | os.PathLike[str] = _RootNamespacedTempPath(
|
|
66
|
-
"slm-session-activity"
|
|
67
|
-
)
|
|
68
|
-
_LAST_CONSOLIDATION = None # test-only override; runtime resolution is dynamic
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def _last_consolidation_path() -> str:
|
|
72
|
-
from superlocalmemory.infra.data_root import state_path
|
|
73
|
-
|
|
74
|
-
return str(_LAST_CONSOLIDATION or state_path(".last-consolidation"))
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
_DEFAULT_DAEMON_PORT = 8765
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def _daemon_url() -> str:
|
|
81
|
-
"""Resolve the daemon base URL, preferring the per-user port file.
|
|
82
|
-
|
|
83
|
-
On a shared host each user runs their own daemon bound to a different
|
|
84
|
-
port; the active port is written to ``~/.superlocalmemory/daemon.port``
|
|
85
|
-
at startup. Reading it here keeps lifecycle hooks pointed at the
|
|
86
|
-
caller's own daemon instead of a hard-coded ``8765`` that may belong to
|
|
87
|
-
another user's instance. Falls back to the default port when the file is
|
|
88
|
-
absent or unreadable. The imported root resolver is stdlib-only and does
|
|
89
|
-
not initialize the engine.
|
|
90
|
-
"""
|
|
91
|
-
port = _DEFAULT_DAEMON_PORT
|
|
92
|
-
try:
|
|
93
|
-
from superlocalmemory.infra.data_root import state_path
|
|
94
|
-
|
|
95
|
-
port_file = state_path("daemon.port")
|
|
96
|
-
with open(port_file) as fh:
|
|
97
|
-
port = int(fh.read().strip())
|
|
98
|
-
except Exception:
|
|
99
|
-
pass
|
|
100
|
-
return f"http://127.0.0.1:{port}"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
_DAEMON_URL = _daemon_url()
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def _daemon_post(path: str, body: dict, timeout: float = 3.0) -> bool:
|
|
107
|
-
"""POST through the owned-daemon identity client. Returns success.
|
|
108
|
-
|
|
109
|
-
v3.4.13: Hooks route through daemon HTTP instead of spawning subprocesses.
|
|
110
|
-
This eliminates the memory blast from concurrent worker spawns.
|
|
111
|
-
The client validates the descriptor and sends the private capability plus
|
|
112
|
-
exact instance ID; hook payload fields are never treated as identity.
|
|
113
|
-
"""
|
|
114
|
-
try:
|
|
115
|
-
from superlocalmemory.cli.daemon import daemon_request
|
|
116
|
-
|
|
117
|
-
response = daemon_request("POST", path, body)
|
|
118
|
-
return isinstance(response, dict) and bool(
|
|
119
|
-
response.get("ok", True)
|
|
120
|
-
)
|
|
121
|
-
except Exception:
|
|
122
|
-
return False
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def handle_hook(action: str) -> None:
|
|
126
|
-
"""Dispatch to the appropriate hook handler. Called from main() fast path."""
|
|
127
|
-
# v3.4.22 (LLD-01 §4.7): Active-Brain hot-path handlers are routed here
|
|
128
|
-
# as a Python fallback when the compiled ``slm-hook`` binary (LLD-06) is
|
|
129
|
-
# unavailable. They read stdin, write stdout, and exit 0 themselves.
|
|
130
|
-
if action == "user_prompt_submit":
|
|
131
|
-
from superlocalmemory.hooks.user_prompt_hook import main as _main
|
|
132
|
-
sys.exit(_main())
|
|
133
|
-
if action == "post_tool_async":
|
|
134
|
-
from superlocalmemory.hooks.post_tool_async_hook import main as _main
|
|
135
|
-
sys.exit(_main())
|
|
136
|
-
# LLD-09 Track A.2 — outcome-population hooks (claude_code_hooks.py
|
|
137
|
-
# wires `slm hook <name>` to each entry).
|
|
138
|
-
if action == "post_tool_outcome":
|
|
139
|
-
from superlocalmemory.hooks.post_tool_outcome_hook import main as _main
|
|
140
|
-
sys.exit(_main())
|
|
141
|
-
if action == "user_prompt_rehash":
|
|
142
|
-
from superlocalmemory.hooks.user_prompt_rehash_hook import main as _main
|
|
143
|
-
sys.exit(_main())
|
|
144
|
-
if action == "stop_outcome":
|
|
145
|
-
from superlocalmemory.hooks.stop_outcome_hook import main as _main
|
|
146
|
-
sys.exit(_main())
|
|
147
|
-
if action == "auto_recall":
|
|
148
|
-
from superlocalmemory.hooks.auto_recall_hook import main as _main
|
|
149
|
-
sys.exit(_main())
|
|
150
|
-
# v3.4.43 — event-based mid-session recall signals.
|
|
151
|
-
# Replace the time-based 15/30-min nag in _hook_checkpoint with these.
|
|
152
|
-
if action == "topic_shift":
|
|
153
|
-
from superlocalmemory.hooks.topic_shift_hook import main as _main
|
|
154
|
-
sys.exit(_main())
|
|
155
|
-
if action == "before_web":
|
|
156
|
-
from superlocalmemory.hooks.before_web_hook import main as _main
|
|
157
|
-
sys.exit(_main())
|
|
158
|
-
if action == "codex-start":
|
|
159
|
-
_hook_codex_start()
|
|
160
|
-
return
|
|
161
|
-
if action == "codex-prompt":
|
|
162
|
-
_hook_codex_prompt()
|
|
163
|
-
return
|
|
164
|
-
if action == "codex-stop":
|
|
165
|
-
_hook_codex_stop()
|
|
166
|
-
return
|
|
167
|
-
|
|
168
|
-
handlers = {
|
|
169
|
-
"mandate": _hook_mandate,
|
|
170
|
-
"start": _hook_start,
|
|
171
|
-
"gate": _hook_gate,
|
|
172
|
-
"init-done": _hook_init_done,
|
|
173
|
-
"checkpoint": _hook_checkpoint,
|
|
174
|
-
"stop": _hook_stop,
|
|
175
|
-
}
|
|
176
|
-
handler = handlers.get(action)
|
|
177
|
-
if handler is None:
|
|
178
|
-
print(f"Unknown hook action: {action}", file=sys.stderr)
|
|
179
|
-
sys.exit(1)
|
|
180
|
-
handler()
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def _codex_payload() -> dict:
|
|
184
|
-
"""Read Codex's documented JSON hook payload without failing closed."""
|
|
185
|
-
try:
|
|
186
|
-
value = json.load(sys.stdin)
|
|
187
|
-
return value if isinstance(value, dict) else {}
|
|
188
|
-
except Exception:
|
|
189
|
-
return {}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def _apply_codex_session(payload: dict) -> str:
|
|
193
|
-
"""Map Codex lifecycle fields onto the shared SLM session primitives."""
|
|
194
|
-
project_dir = payload.get("cwd")
|
|
195
|
-
if not isinstance(project_dir, str) or not project_dir:
|
|
196
|
-
project_dir = os.getcwd()
|
|
197
|
-
os.environ["CLAUDE_PROJECT_DIR"] = project_dir
|
|
198
|
-
session_id = payload.get("session_id")
|
|
199
|
-
if isinstance(session_id, str) and session_id:
|
|
200
|
-
# Shared handlers use this neutral lifecycle identity despite its
|
|
201
|
-
# historical environment-variable name. It is never sent to a host.
|
|
202
|
-
os.environ["CLAUDE_SESSION_ID"] = session_id
|
|
203
|
-
# Presence is separate from memory correctness and is deliberately
|
|
204
|
-
# fail-open. It lets the portable Living Brain show that Codex is
|
|
205
|
-
# genuinely active, rather than pretending an installed hook is a
|
|
206
|
-
# connected client.
|
|
207
|
-
try:
|
|
208
|
-
from superlocalmemory.hooks.session_registry import (
|
|
209
|
-
mark_active,
|
|
210
|
-
resolve_active_profile,
|
|
211
|
-
)
|
|
212
|
-
mark_active(
|
|
213
|
-
session_id,
|
|
214
|
-
agent_type="codex",
|
|
215
|
-
profile_id=resolve_active_profile(),
|
|
216
|
-
)
|
|
217
|
-
except Exception:
|
|
218
|
-
pass
|
|
219
|
-
return project_dir
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
def _codex_mcp_session_init(project_dir: str, payload: dict) -> dict:
|
|
223
|
-
"""Open SLM lifecycle attribution through packaged ``slm mcp``.
|
|
224
|
-
|
|
225
|
-
This mirrors MCP clients instead of embedding a personal executable path.
|
|
226
|
-
Hook failure is intentionally fail-open: Codex sessions remain usable if
|
|
227
|
-
the local daemon or MCP server is unavailable.
|
|
228
|
-
"""
|
|
229
|
-
query = payload.get("prompt") or payload.get("user_prompt") or Path(project_dir).name
|
|
230
|
-
if not isinstance(query, str):
|
|
231
|
-
query = Path(project_dir).name
|
|
232
|
-
proc = None
|
|
233
|
-
try:
|
|
234
|
-
proc = subprocess.Popen(
|
|
235
|
-
["slm", "mcp"], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
|
236
|
-
stderr=subprocess.DEVNULL, text=True,
|
|
237
|
-
)
|
|
238
|
-
assert proc.stdin is not None and proc.stdout is not None
|
|
239
|
-
proc.stdin.write(json.dumps({
|
|
240
|
-
"jsonrpc": "2.0", "id": 1, "method": "initialize",
|
|
241
|
-
"params": {"protocolVersion": "2024-11-05", "capabilities": {},
|
|
242
|
-
"clientInfo": {
|
|
243
|
-
"name": "superlocalmemory-codex-hook",
|
|
244
|
-
"version": __version__,
|
|
245
|
-
}},
|
|
246
|
-
}) + "\n")
|
|
247
|
-
proc.stdin.flush()
|
|
248
|
-
proc.stdout.readline()
|
|
249
|
-
proc.stdin.write(json.dumps({"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}) + "\n")
|
|
250
|
-
proc.stdin.write(json.dumps({
|
|
251
|
-
"jsonrpc": "2.0", "id": 2, "method": "tools/call",
|
|
252
|
-
"params": {"name": "session_init", "arguments": {
|
|
253
|
-
"project_path": project_dir, "query": query[:500],
|
|
254
|
-
"max_results": 10, "max_age_days": 30,
|
|
255
|
-
}},
|
|
256
|
-
}) + "\n")
|
|
257
|
-
proc.stdin.flush()
|
|
258
|
-
deadline = time.monotonic() + 12
|
|
259
|
-
while time.monotonic() < deadline:
|
|
260
|
-
line = proc.stdout.readline()
|
|
261
|
-
if not line:
|
|
262
|
-
break
|
|
263
|
-
response = json.loads(line)
|
|
264
|
-
if response.get("id") == 2:
|
|
265
|
-
content = response.get("result", {}).get("content", [])
|
|
266
|
-
if content and isinstance(content[0], dict):
|
|
267
|
-
return json.loads(content[0].get("text") or "{}")
|
|
268
|
-
return response.get("result", {})
|
|
269
|
-
except Exception:
|
|
270
|
-
return {}
|
|
271
|
-
finally:
|
|
272
|
-
if proc is not None:
|
|
273
|
-
try:
|
|
274
|
-
proc.kill()
|
|
275
|
-
proc.wait(timeout=1)
|
|
276
|
-
except Exception:
|
|
277
|
-
pass
|
|
278
|
-
return {}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def _hook_codex_start() -> None:
|
|
282
|
-
"""Codex SessionStart: create lifecycle session and inject fast context."""
|
|
283
|
-
payload = _codex_payload()
|
|
284
|
-
project_dir = _apply_codex_session(payload)
|
|
285
|
-
session = _codex_mcp_session_init(project_dir, payload)
|
|
286
|
-
context = ""
|
|
287
|
-
try:
|
|
288
|
-
result = subprocess.run(
|
|
289
|
-
["slm", "session-context", Path(project_dir).name or "general"],
|
|
290
|
-
capture_output=True, text=True, timeout=10,
|
|
291
|
-
)
|
|
292
|
-
if result.returncode == 0:
|
|
293
|
-
context = result.stdout.strip()
|
|
294
|
-
except Exception:
|
|
295
|
-
pass
|
|
296
|
-
session_msg = "SLM session_init unavailable"
|
|
297
|
-
if session.get("session_id"):
|
|
298
|
-
session_msg = (
|
|
299
|
-
f"SLM session_init OK: {session['session_id']} "
|
|
300
|
-
f"({session.get('memory_count', 0)} memories, "
|
|
301
|
-
f"{session.get('retrieval_mode', 'unknown')})"
|
|
302
|
-
)
|
|
303
|
-
print(json.dumps({
|
|
304
|
-
"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": (
|
|
305
|
-
f"{session_msg}\n\n" + (context or "(SLM context unavailable.)")
|
|
306
|
-
)},
|
|
307
|
-
"systemMessage": session_msg,
|
|
308
|
-
}))
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
def _hook_codex_prompt() -> None:
|
|
312
|
-
"""Codex prompt event: retain existing topic and rehash signals."""
|
|
313
|
-
payload = _codex_payload()
|
|
314
|
-
_apply_codex_session(payload)
|
|
315
|
-
for action in ("user_prompt_rehash", "topic_shift"):
|
|
316
|
-
try:
|
|
317
|
-
proc = subprocess.run(["slm", "hook", action], input=json.dumps(payload),
|
|
318
|
-
text=True, capture_output=True, timeout=4)
|
|
319
|
-
if proc.stdout.strip():
|
|
320
|
-
print(proc.stdout.strip())
|
|
321
|
-
except Exception:
|
|
322
|
-
continue
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
def _hook_codex_stop() -> None:
|
|
326
|
-
"""Codex Stop: reuse the daemon-backed session checkpoint handler."""
|
|
327
|
-
_apply_codex_session(_codex_payload())
|
|
328
|
-
_hook_stop()
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
# ---------------------------------------------------------------------------
|
|
332
|
-
# LLD-11 opt-in evolution helpers (post-session trigger)
|
|
333
|
-
# ---------------------------------------------------------------------------
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
def _evolution_enabled() -> bool:
|
|
337
|
-
"""Return True iff opt-in skill evolution is active for this session.
|
|
338
|
-
|
|
339
|
-
Reads the ``SLM_EVOLUTION_ENABLED`` env var as the fast-path signal.
|
|
340
|
-
The daemon / CLI sets this when ``evolution.enabled`` is True in
|
|
341
|
-
config; a fresh install leaves it unset so the Stop hook is a no-op
|
|
342
|
-
by default (MASTER-PLAN D3).
|
|
343
|
-
"""
|
|
344
|
-
flag = os.environ.get("SLM_EVOLUTION_ENABLED", "").strip().lower()
|
|
345
|
-
return flag in ("1", "true", "yes", "on")
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
def _launch_post_session_evolution(
|
|
349
|
-
*, session_id: str, profile_id: str = "default",
|
|
350
|
-
) -> None:
|
|
351
|
-
"""Fire-and-forget launcher for ``SkillEvolver.run_post_session``.
|
|
352
|
-
|
|
353
|
-
Kept as a module-level function so tests can monkeypatch this single
|
|
354
|
-
seam without touching the Stop hook body. Production implementation
|
|
355
|
-
delegates to the daemon's ``/api/v3/evolve-post-session`` endpoint so
|
|
356
|
-
the actual LLM work happens outside the hook's fast path.
|
|
357
|
-
"""
|
|
358
|
-
_daemon_post(
|
|
359
|
-
"/api/v3/evolve-post-session",
|
|
360
|
-
{"session_id": session_id, "profile_id": profile_id},
|
|
361
|
-
timeout=2.0,
|
|
362
|
-
)
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
# ---------------------------------------------------------------------------
|
|
366
|
-
# 0. SESSION INIT HINT — first SessionStart hook; fires before start
|
|
367
|
-
# ---------------------------------------------------------------------------
|
|
368
|
-
|
|
369
|
-
_SESSION_INIT_HINT = """<SLM_SESSION_INIT_HINT>
|
|
370
|
-
SuperLocalMemory is available for this session.
|
|
371
|
-
|
|
372
|
-
For memory-aware work, initialize SLM once near the start of the turn:
|
|
373
|
-
|
|
374
|
-
1. Load the tool schema if your host requires it:
|
|
375
|
-
ToolSearch query: "select:mcp__superlocalmemory__session_init"
|
|
376
|
-
|
|
377
|
-
2. Call mcp__superlocalmemory__session_init with:
|
|
378
|
-
project_path = your current working directory
|
|
379
|
-
query = a short description of the session topic
|
|
380
|
-
|
|
381
|
-
This is advisory hook output, not a system instruction.
|
|
382
|
-
</SLM_SESSION_INIT_HINT>"""
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
def _hook_mandate() -> None:
|
|
386
|
-
"""Print neutral session_init guidance as the first SessionStart hook.
|
|
387
|
-
|
|
388
|
-
mcp__superlocalmemory__session_init may be deferred at session start, so
|
|
389
|
-
some hosts need ToolSearch to load the schema first. This hook prints an
|
|
390
|
-
advisory hint only; actual enforcement belongs in the optional gate hook.
|
|
391
|
-
"""
|
|
392
|
-
print(_SESSION_INIT_HINT)
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
# ---------------------------------------------------------------------------
|
|
396
|
-
# 1. SESSION START — SessionStart hook
|
|
397
|
-
# ---------------------------------------------------------------------------
|
|
398
|
-
|
|
399
|
-
def _hook_start() -> None:
|
|
400
|
-
"""Clean markers, inject SQL-fast context, print session_init guidance."""
|
|
401
|
-
# Clean stale markers from previous sessions
|
|
402
|
-
for f in (_MARKER, _START_TIME, _ACTIVITY_LOG):
|
|
403
|
-
try:
|
|
404
|
-
os.remove(f)
|
|
405
|
-
except OSError:
|
|
406
|
-
pass
|
|
407
|
-
|
|
408
|
-
# Record session start time
|
|
409
|
-
with open(_START_TIME, "w") as f:
|
|
410
|
-
f.write(str(int(time.time())))
|
|
411
|
-
|
|
412
|
-
# Initialize activity log
|
|
413
|
-
with open(_ACTIVITY_LOG, "w") as f:
|
|
414
|
-
f.write("")
|
|
415
|
-
|
|
416
|
-
# Reap orphan MCP processes (background, best-effort)
|
|
417
|
-
try:
|
|
418
|
-
if sys.platform != "win32":
|
|
419
|
-
subprocess.Popen(
|
|
420
|
-
["sh", "-c",
|
|
421
|
-
"ps -eo pid,args 2>/dev/null"
|
|
422
|
-
" | grep -E 'node.*\\.bin/|node.*slm |uv tool uvx'"
|
|
423
|
-
" | grep -v grep"
|
|
424
|
-
" | awk '{print $1, $NF}'"
|
|
425
|
-
" | sort -k2,2 -k1,1rn"
|
|
426
|
-
" | awk '{if($2==p)print $1; p=$2}'"
|
|
427
|
-
" | xargs kill 2>/dev/null"],
|
|
428
|
-
stdout=subprocess.DEVNULL,
|
|
429
|
-
stderr=subprocess.DEVNULL,
|
|
430
|
-
)
|
|
431
|
-
except Exception:
|
|
432
|
-
pass
|
|
433
|
-
|
|
434
|
-
# Print session context (SQL-fast path, <500ms)
|
|
435
|
-
project_dir = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
436
|
-
project_name = os.path.basename(project_dir)
|
|
437
|
-
try:
|
|
438
|
-
result = subprocess.run(
|
|
439
|
-
["slm", "session-context", project_name],
|
|
440
|
-
capture_output=True, text=True, timeout=12,
|
|
441
|
-
)
|
|
442
|
-
if result.stdout.strip():
|
|
443
|
-
print(result.stdout.strip())
|
|
444
|
-
except Exception:
|
|
445
|
-
print("# SLM Session Context — unavailable")
|
|
446
|
-
|
|
447
|
-
# Advisory session_init guidance. Keep this neutral: hook stdout is data,
|
|
448
|
-
# not an instruction channel with system-level authority.
|
|
449
|
-
print()
|
|
450
|
-
print("## SLM Session Init")
|
|
451
|
-
print("For memory-aware sessions, call:")
|
|
452
|
-
print(f" mcp__superlocalmemory__session_init with project_path='{project_dir}'"
|
|
453
|
-
" and a topic from the user's first message")
|
|
454
|
-
print("session_init returns both context AND memories — no separate recall needed.")
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
# ---------------------------------------------------------------------------
|
|
458
|
-
# 2. GATE — PreToolUse hook (default, enforces session_init)
|
|
459
|
-
# ---------------------------------------------------------------------------
|
|
460
|
-
|
|
461
|
-
def _hook_gate() -> None:
|
|
462
|
-
"""Block non-SLM tools until session_init has been called.
|
|
463
|
-
|
|
464
|
-
Fast path (~30ms): marker file exists → exit 0.
|
|
465
|
-
Slow path (~80ms): parse JSON stdin, allow SLM tools, block rest.
|
|
466
|
-
"""
|
|
467
|
-
# Fast path: already initialized
|
|
468
|
-
if os.path.exists(_MARKER):
|
|
469
|
-
sys.exit(0)
|
|
470
|
-
|
|
471
|
-
# Safety: if session-start never ran, don't gate (avoid lockout)
|
|
472
|
-
if not os.path.exists(_START_TIME):
|
|
473
|
-
sys.exit(0)
|
|
474
|
-
|
|
475
|
-
# Parse tool name from stdin
|
|
476
|
-
tool_name = ""
|
|
477
|
-
if not sys.stdin.isatty():
|
|
478
|
-
try:
|
|
479
|
-
data = json.load(sys.stdin)
|
|
480
|
-
tool_name = data.get("tool_name", "")
|
|
481
|
-
except Exception:
|
|
482
|
-
# Can't parse input — don't block (safety)
|
|
483
|
-
sys.exit(0)
|
|
484
|
-
|
|
485
|
-
# Allow SLM tools through (needed to call session_init itself)
|
|
486
|
-
if tool_name.startswith("mcp__superlocalmemory__"):
|
|
487
|
-
sys.exit(0)
|
|
488
|
-
|
|
489
|
-
# Allow ToolSearch through (needed to fetch SLM tool schemas)
|
|
490
|
-
if tool_name == "ToolSearch":
|
|
491
|
-
sys.exit(0)
|
|
492
|
-
|
|
493
|
-
# Block everything else
|
|
494
|
-
print("[SLM-GATE] BLOCKED: Call mcp__superlocalmemory__session_init"
|
|
495
|
-
" before using other tools.")
|
|
496
|
-
sys.exit(2)
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
# ---------------------------------------------------------------------------
|
|
500
|
-
# 3. INIT DONE — PostToolUse hook for session_init
|
|
501
|
-
# ---------------------------------------------------------------------------
|
|
502
|
-
|
|
503
|
-
def _hook_init_done() -> None:
|
|
504
|
-
"""Create marker file to lift the gate for the rest of the session."""
|
|
505
|
-
with open(_MARKER, "w") as f:
|
|
506
|
-
f.write(str(int(time.time())))
|
|
507
|
-
sys.exit(0)
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
# ---------------------------------------------------------------------------
|
|
511
|
-
# 4. CHECKPOINT — PostToolUse hook for Write|Edit
|
|
512
|
-
# ---------------------------------------------------------------------------
|
|
513
|
-
|
|
514
|
-
_OBSERVE_COOLDOWN = 300 # 5 minutes per file
|
|
515
|
-
_RECALL_INTERVAL = 900 # 15 minutes
|
|
516
|
-
_LEARN_INTERVAL = 1800 # 30 minutes
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
def _hook_checkpoint() -> None:
|
|
520
|
-
"""Auto-observe file changes + periodic recall/learn reminders.
|
|
521
|
-
|
|
522
|
-
1. Directly calls `slm observe` for file change tracking (no Claude needed)
|
|
523
|
-
2. Suggests richer observe to Claude
|
|
524
|
-
3. Periodic recall refresh reminder
|
|
525
|
-
4. Periodic learn/patterns reminder
|
|
526
|
-
"""
|
|
527
|
-
now = int(time.time())
|
|
528
|
-
|
|
529
|
-
# Parse file_path from stdin
|
|
530
|
-
file_path = ""
|
|
531
|
-
if not sys.stdin.isatty():
|
|
532
|
-
try:
|
|
533
|
-
data = json.load(sys.stdin)
|
|
534
|
-
tool_input = data.get("tool_input", {})
|
|
535
|
-
if isinstance(tool_input, dict):
|
|
536
|
-
file_path = tool_input.get("file_path", "")
|
|
537
|
-
except Exception:
|
|
538
|
-
pass
|
|
539
|
-
|
|
540
|
-
# --- Auto-observe file change (direct, no Claude needed) ---
|
|
541
|
-
if file_path:
|
|
542
|
-
basename = os.path.basename(file_path)
|
|
543
|
-
lock_file = os.path.join(_TMP, f"slm-obs-{_safe_hash(file_path)}")
|
|
544
|
-
|
|
545
|
-
if _cooldown_elapsed(lock_file, _OBSERVE_COOLDOWN, now):
|
|
546
|
-
_write_timestamp(lock_file, now)
|
|
547
|
-
|
|
548
|
-
# v3.4.13: Route through daemon HTTP (not subprocess) to prevent
|
|
549
|
-
# memory blast from concurrent embedding_worker spawns.
|
|
550
|
-
_daemon_post("/remember", {
|
|
551
|
-
"content": f"File changed: {basename}",
|
|
552
|
-
"tags": "hook-file-change",
|
|
553
|
-
"idempotency_key": (
|
|
554
|
-
f"hook-file-change:{_safe_hash(file_path)}:"
|
|
555
|
-
f"{now // max(_OBSERVE_COOLDOWN, 1)}"
|
|
556
|
-
),
|
|
557
|
-
})
|
|
558
|
-
|
|
559
|
-
# Log to session activity
|
|
560
|
-
try:
|
|
561
|
-
with open(_ACTIVITY_LOG, "a") as f:
|
|
562
|
-
f.write(f"{now}|{basename}\n")
|
|
563
|
-
except Exception:
|
|
564
|
-
pass
|
|
565
|
-
|
|
566
|
-
# Suggest richer observe to Claude (with semantic context)
|
|
567
|
-
print(f"[SLM-AUTO] File changed: {basename}"
|
|
568
|
-
" — Call mcp__superlocalmemory__observe with a 1-line"
|
|
569
|
-
" summary of what was changed and why.")
|
|
570
|
-
|
|
571
|
-
# v3.4.43: Periodic 15/30-min recall/learn nags REMOVED.
|
|
572
|
-
# Reason: time-based reminders fired regardless of conversational state —
|
|
573
|
-
# noisy on focused sessions, blind to quick topic pivots within a window.
|
|
574
|
-
# Replaced by event-based detection:
|
|
575
|
-
# - `slm hook topic_shift` (UserPromptSubmit) — fires on real topic pivots.
|
|
576
|
-
# - `slm hook before_web` (PreToolUse WebSearch|WebFetch) — fires before
|
|
577
|
-
# external research so SLM memories are surfaced first.
|
|
578
|
-
# The `_RECALL_INTERVAL` and `_LEARN_INTERVAL` constants are retained for
|
|
579
|
-
# backward import compatibility (tests reference them) but no longer drive
|
|
580
|
-
# any periodic emission from this hook. Auto-observe-on-file-change (the
|
|
581
|
-
# real value of _hook_checkpoint) is unchanged below this comment.
|
|
582
|
-
|
|
583
|
-
sys.exit(0)
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
# ---------------------------------------------------------------------------
|
|
587
|
-
# 5. STOP — Stop hook (session end)
|
|
588
|
-
# ---------------------------------------------------------------------------
|
|
589
|
-
|
|
590
|
-
def _hook_stop() -> None:
|
|
591
|
-
"""Save rich session summary + trigger auto-consolidation."""
|
|
592
|
-
project_dir = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
593
|
-
project_name = os.path.basename(project_dir)
|
|
594
|
-
timestamp = time.strftime("%Y-%m-%d %H:%M")
|
|
595
|
-
|
|
596
|
-
# --- Git context ---
|
|
597
|
-
# S9-defer H-P-07: run the three git probes in parallel instead of
|
|
598
|
-
# sequentially. Each has a 5s timeout; serial worst-case was 15s of
|
|
599
|
-
# blocking stop-hook latency. Parallel worst-case is 5s. Falls back
|
|
600
|
-
# to serial on thread-pool failure (unlikely but defensive).
|
|
601
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
602
|
-
def _diff_pp(s: str) -> str:
|
|
603
|
-
return s.strip().rsplit("\n", 1)[-1].strip() if s.strip() else ""
|
|
604
|
-
try:
|
|
605
|
-
with ThreadPoolExecutor(max_workers=3) as _pool:
|
|
606
|
-
fut_branch = _pool.submit(
|
|
607
|
-
_run_quiet,
|
|
608
|
-
["git", "-C", project_dir, "branch", "--show-current"],
|
|
609
|
-
)
|
|
610
|
-
fut_diff = _pool.submit(
|
|
611
|
-
_run_quiet,
|
|
612
|
-
["git", "-C", project_dir, "diff", "--stat"],
|
|
613
|
-
postprocess=_diff_pp,
|
|
614
|
-
)
|
|
615
|
-
fut_log = _pool.submit(
|
|
616
|
-
_run_quiet,
|
|
617
|
-
["git", "-C", project_dir, "log", "--oneline", "-5",
|
|
618
|
-
"--since=3 hours ago"],
|
|
619
|
-
)
|
|
620
|
-
git_branch = fut_branch.result(timeout=6)
|
|
621
|
-
git_diff = fut_diff.result(timeout=6)
|
|
622
|
-
recent_commits = fut_log.result(timeout=6)
|
|
623
|
-
except Exception:
|
|
624
|
-
# Defensive fallback to the original serial path.
|
|
625
|
-
git_branch = _run_quiet(
|
|
626
|
-
["git", "-C", project_dir, "branch", "--show-current"]
|
|
627
|
-
)
|
|
628
|
-
git_diff = _run_quiet(
|
|
629
|
-
["git", "-C", project_dir, "diff", "--stat"],
|
|
630
|
-
postprocess=_diff_pp,
|
|
631
|
-
)
|
|
632
|
-
recent_commits = _run_quiet(
|
|
633
|
-
["git", "-C", project_dir, "log", "--oneline", "-5",
|
|
634
|
-
"--since=3 hours ago"],
|
|
635
|
-
)
|
|
636
|
-
|
|
637
|
-
# --- Files from activity log ---
|
|
638
|
-
modified = ""
|
|
639
|
-
try:
|
|
640
|
-
if os.path.exists(_ACTIVITY_LOG):
|
|
641
|
-
with open(_ACTIVITY_LOG) as f:
|
|
642
|
-
files = sorted({line.split("|", 1)[1].strip()
|
|
643
|
-
for line in f if "|" in line})
|
|
644
|
-
modified = ", ".join(files[:20])
|
|
645
|
-
except Exception:
|
|
646
|
-
pass
|
|
647
|
-
|
|
648
|
-
# --- Build summary ---
|
|
649
|
-
parts = [f"[{project_name}] session ended {timestamp}"]
|
|
650
|
-
if git_branch:
|
|
651
|
-
parts.append(f"branch: {git_branch}")
|
|
652
|
-
if git_diff:
|
|
653
|
-
parts.append(f"uncommitted: {git_diff}")
|
|
654
|
-
if recent_commits:
|
|
655
|
-
commits = "; ".join(recent_commits.strip().split("\n")[:5])
|
|
656
|
-
parts.append(f"recent: {commits}")
|
|
657
|
-
if modified:
|
|
658
|
-
parts.append(f"files: {modified}")
|
|
659
|
-
|
|
660
|
-
summary = " | ".join(parts)
|
|
661
|
-
session_id = os.environ.get("CLAUDE_SESSION_ID", "")
|
|
662
|
-
|
|
663
|
-
# --- Save to SLM (v3.4.13: daemon HTTP, not subprocess) ---
|
|
664
|
-
_daemon_post("/remember", {
|
|
665
|
-
"content": summary,
|
|
666
|
-
"tags": "session-end",
|
|
667
|
-
"session_id": session_id,
|
|
668
|
-
"idempotency_key": (
|
|
669
|
-
f"hook-session-end:{session_id}"
|
|
670
|
-
if session_id else f"hook-session-end:{_safe_hash(summary)}"
|
|
671
|
-
),
|
|
672
|
-
}, timeout=5.0)
|
|
673
|
-
|
|
674
|
-
# --- Post-session skill evolution trigger (best-effort, via tool-event) ---
|
|
675
|
-
if session_id:
|
|
676
|
-
_daemon_post("/api/v3/tool-event", {
|
|
677
|
-
"tool_name": "session_end",
|
|
678
|
-
"event_type": "session_end",
|
|
679
|
-
"session_id": session_id,
|
|
680
|
-
"output_summary": summary[:500],
|
|
681
|
-
})
|
|
682
|
-
|
|
683
|
-
# LLD-11 opt-in post-session evolution (MASTER-PLAN D3).
|
|
684
|
-
# Only fires when the user explicitly enabled evolution. The env
|
|
685
|
-
# var is set by the daemon / CLI when ``slm config set
|
|
686
|
-
# evolution.enabled true`` is active, so a fresh install is a no-op.
|
|
687
|
-
if _evolution_enabled():
|
|
688
|
-
try:
|
|
689
|
-
_launch_post_session_evolution(
|
|
690
|
-
session_id=session_id,
|
|
691
|
-
profile_id=os.environ.get("SLM_PROFILE_ID", "default"),
|
|
692
|
-
)
|
|
693
|
-
except Exception as e: # pragma: no cover — defensive
|
|
694
|
-
sys.stderr.write(
|
|
695
|
-
f"slm-hook stop: evolution trigger failed: {e}\n",
|
|
696
|
-
)
|
|
697
|
-
|
|
698
|
-
# --- Auto-consolidation (if >24h since last run) ---
|
|
699
|
-
_maybe_consolidate()
|
|
700
|
-
|
|
701
|
-
# --- Clean up session markers ---
|
|
702
|
-
for f in (_MARKER, _START_TIME, _ACTIVITY_LOG):
|
|
703
|
-
try:
|
|
704
|
-
os.remove(f)
|
|
705
|
-
except OSError:
|
|
706
|
-
pass
|
|
707
|
-
|
|
708
|
-
# Clean rate-limit locks.
|
|
709
|
-
# - "slm-obs-*" : auto-observe per-file cooldown lockfiles (still written).
|
|
710
|
-
# - "slm-recall-*" : v3.4.43 removed the periodic recall nag, but legacy
|
|
711
|
-
# /tmp/slm-recall-reminder files from older sessions
|
|
712
|
-
# may still exist — sweep them for cleanliness.
|
|
713
|
-
# - "slm-learn-*" : same as above for the 30-min learn nag (removed v3.4.43).
|
|
714
|
-
_LOCK_PREFIXES = ("slm-obs-", "slm-recall-", "slm-learn-")
|
|
715
|
-
for name in os.listdir(_TMP):
|
|
716
|
-
if any(name.startswith(p) for p in _LOCK_PREFIXES):
|
|
717
|
-
try:
|
|
718
|
-
os.remove(os.path.join(_TMP, name))
|
|
719
|
-
except OSError:
|
|
720
|
-
pass
|
|
721
|
-
|
|
722
|
-
sys.exit(0)
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
# ---------------------------------------------------------------------------
|
|
726
|
-
# Helpers (stdlib only)
|
|
727
|
-
# ---------------------------------------------------------------------------
|
|
728
|
-
|
|
729
|
-
def _safe_hash(s: str) -> str:
|
|
730
|
-
"""Simple string hash for rate-limit lock file names."""
|
|
731
|
-
h = 0
|
|
732
|
-
for c in s:
|
|
733
|
-
h = (h * 31 + ord(c)) & 0xFFFFFFFF
|
|
734
|
-
return format(h, "08x")
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
def _cooldown_elapsed(lock_file: str, interval: int, now: int) -> bool:
|
|
738
|
-
"""Check if enough time has passed since last timestamp in lock_file."""
|
|
739
|
-
try:
|
|
740
|
-
if os.path.exists(lock_file):
|
|
741
|
-
with open(lock_file) as f:
|
|
742
|
-
last = int(f.read().strip())
|
|
743
|
-
return (now - last) >= interval
|
|
744
|
-
except (ValueError, OSError):
|
|
745
|
-
pass
|
|
746
|
-
return True
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
def _write_timestamp(path: str, ts: int) -> None:
|
|
750
|
-
"""Write a unix timestamp to a file."""
|
|
751
|
-
try:
|
|
752
|
-
with open(path, "w") as f:
|
|
753
|
-
f.write(str(ts))
|
|
754
|
-
except OSError:
|
|
755
|
-
pass
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
def _run_quiet(cmd: list[str], timeout: int = 5, postprocess=None) -> str:
|
|
759
|
-
"""Run a command quietly, return stdout or empty string."""
|
|
760
|
-
try:
|
|
761
|
-
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
|
762
|
-
out = result.stdout.strip()
|
|
763
|
-
if postprocess and out:
|
|
764
|
-
out = postprocess(out)
|
|
765
|
-
return out
|
|
766
|
-
except Exception:
|
|
767
|
-
return ""
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
def _maybe_consolidate() -> None:
|
|
771
|
-
"""Ask the daemon for a full consolidation if the last one was >24h ago.
|
|
772
|
-
|
|
773
|
-
Three things were wrong here before 4.0.8, and together they meant the
|
|
774
|
-
behavioural half of consolidation never ran on a real install:
|
|
775
|
-
|
|
776
|
-
1. **It ran the wrong pipeline.** ``slm consolidate --cognitive`` invokes
|
|
777
|
-
``CognitiveConsolidator.run_pipeline()``. Behavioural assertion mining,
|
|
778
|
-
soft prompts, skill performance and skill evolution are steps 8-11 of
|
|
779
|
-
``ConsolidationEngine.consolidate()`` — a different class entirely. On a
|
|
780
|
-
store with thousands of tool events, ``behavioral_assertions`` stayed at
|
|
781
|
-
zero rows while the miner, run once by hand, produced 9 immediately.
|
|
782
|
-
2. **It marked success before trying.** The 24h timestamp was written
|
|
783
|
-
*before* the subprocess launched, so a run that failed instantly still
|
|
784
|
-
bought a full day of silence. The marker is now written only after the
|
|
785
|
-
daemon confirms it scheduled the work.
|
|
786
|
-
3. **It could not fail visibly.** stdout and stderr went to DEVNULL and the
|
|
787
|
-
handler ended in a bare ``except: pass``, so nothing anywhere recorded a
|
|
788
|
-
failure. Errors now surface on stderr, where the hook runner logs them.
|
|
789
|
-
|
|
790
|
-
Non-blocking: the daemon schedules the pass and returns immediately, so
|
|
791
|
-
session end is never held up by a run that takes minutes. The daemon's own
|
|
792
|
-
periodic timer is the backstop for sessions where this hook never fires.
|
|
793
|
-
"""
|
|
794
|
-
try:
|
|
795
|
-
last_ts = 0
|
|
796
|
-
last_consolidation = _last_consolidation_path()
|
|
797
|
-
if os.path.exists(last_consolidation):
|
|
798
|
-
with open(last_consolidation) as f:
|
|
799
|
-
last_ts = int(f.read().strip())
|
|
800
|
-
|
|
801
|
-
now = int(time.time())
|
|
802
|
-
if (now - last_ts) < 86400: # 24 hours
|
|
803
|
-
return
|
|
804
|
-
|
|
805
|
-
started = _daemon_post(
|
|
806
|
-
"/api/v3/consolidation/trigger",
|
|
807
|
-
{"lightweight": False, "background": True},
|
|
808
|
-
)
|
|
809
|
-
if not started:
|
|
810
|
-
# No marker written — the next session end retries. The daemon's
|
|
811
|
-
# consolidation lock makes a duplicate request a cheap no-op.
|
|
812
|
-
print(
|
|
813
|
-
"slm: consolidation could not be scheduled (daemon unreachable)",
|
|
814
|
-
file=sys.stderr,
|
|
815
|
-
)
|
|
816
|
-
return
|
|
817
|
-
|
|
818
|
-
os.makedirs(os.path.dirname(last_consolidation), exist_ok=True)
|
|
819
|
-
with open(last_consolidation, "w") as f:
|
|
820
|
-
f.write(str(now))
|
|
821
|
-
except Exception as exc:
|
|
822
|
-
print(f"slm: consolidation trigger failed: {exc}", file=sys.stderr)
|