superlocalmemory 4.1.13 → 4.1.14
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 +48 -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,776 +0,0 @@
|
|
|
1
|
-
/* ============================================================
|
|
2
|
-
od-graph.js — Knowledge Graph (Open Design port, live data)
|
|
3
|
-
Faithful port of open-design/graph.html: force-directed canvas
|
|
4
|
-
engine, 3-tier model (community > entity > episode), node inspector,
|
|
5
|
-
Ask-Memory chat.
|
|
6
|
-
|
|
7
|
-
Live data (NO invented values):
|
|
8
|
-
GET /api/graph?max_nodes=&min_importance= nodes/links/clusters
|
|
9
|
-
GET /api/entity/list?limit= tier-2 entities
|
|
10
|
-
POST /api/search Ask-Memory answers
|
|
11
|
-
Exposes window.odRenderGraph(container); the shell calls it on tab open.
|
|
12
|
-
============================================================ */
|
|
13
|
-
(function () {
|
|
14
|
-
'use strict';
|
|
15
|
-
|
|
16
|
-
var GRAPH_URL = '/api/graph';
|
|
17
|
-
var RECALL_URL = '/api/search'; /* POST {query, limit} -> {results:[...]} */
|
|
18
|
-
var MAX_NODES = 50; /* default budget; owner-set to 50; slider range 20-2000 */
|
|
19
|
-
/* Keep force-layout work bounded even when a user asks to render "All". */
|
|
20
|
-
var PHYSICS_MAX_NODES = 160;
|
|
21
|
-
var PRE_SETTLE_TICKS = 24;
|
|
22
|
-
|
|
23
|
-
/* ---- 16-colour categorical palette (Tableau-inspired, accessible) ---- */
|
|
24
|
-
var CAT_PALETTE = [
|
|
25
|
-
'#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F',
|
|
26
|
-
'#EDC948', '#B07AA1', '#FF9DA7', '#9C755F', '#BAB0AC',
|
|
27
|
-
'#52B2BF', '#D4A5A5', '#7EB0D5', '#FD7F6F', '#B2E061', '#FFBE7D'
|
|
28
|
-
];
|
|
29
|
-
/* fixed colours per entity type -- consistent across renders */
|
|
30
|
-
var ETYPE_COLORS = {
|
|
31
|
-
person: '#4E79A7',
|
|
32
|
-
org: '#F28E2B',
|
|
33
|
-
concept: '#59A14F',
|
|
34
|
-
event: '#E15759',
|
|
35
|
-
location: '#76B7B2',
|
|
36
|
-
tool: '#EDC948',
|
|
37
|
-
project: '#B07AA1',
|
|
38
|
-
skill: '#FF9DA7'
|
|
39
|
-
};
|
|
40
|
-
var EPISODE_COLOR = '#8899AA'; /* neutral-desaturated -- episodes are context */
|
|
41
|
-
|
|
42
|
-
/* module state (re-render safe) */
|
|
43
|
-
var mount = null, cv = null, ctx = null, stage = null;
|
|
44
|
-
var raf = null, running = false, fitFrames = 0;
|
|
45
|
-
/* settle-freeze: stop the rAF loop once kinetic energy drops below SETTLE_KE */
|
|
46
|
-
var frames = 0, _ke = 0;
|
|
47
|
-
var SETTLE_MIN = 30, SETTLE_KE = 0.2, SETTLE_MAX_FRAMES = 180;
|
|
48
|
-
/* Bounded wait for layout when the stage reports 0x0. ~3s at 60fps:
|
|
49
|
-
long enough for a cold load whose pane is laid out a beat after
|
|
50
|
-
mount, short enough that a hidden pane cannot hold the rAF loop
|
|
51
|
-
open indefinitely. */
|
|
52
|
-
var blindFrames = 0, BLIND_MAX_FRAMES = 180;
|
|
53
|
-
var NODES = [], LINKS = [], idx = {};
|
|
54
|
-
var tierVisible = { 1: true, 2: true, 3: true }; /* independent tier toggles */
|
|
55
|
-
var scale = 1, ox = 0, oy = 0, dpr = Math.max(1, window.devicePixelRatio || 1);
|
|
56
|
-
var W = 0, H = 0, selected = null, hover = null;
|
|
57
|
-
var dragNode = null, panning = false, last = null;
|
|
58
|
-
var PAL = {}, themeObs = null, sizeObs = null;
|
|
59
|
-
|
|
60
|
-
/* bound handlers kept so re-render can detach them */
|
|
61
|
-
var onMove = null, onUp = null;
|
|
62
|
-
|
|
63
|
-
/* ---------------- markup (from graph.html <main>) ---------------- */
|
|
64
|
-
function scaffold() {
|
|
65
|
-
return '' +
|
|
66
|
-
'<div class="graph-shell">' +
|
|
67
|
-
'<div class="graph-stage" id="odg-stage">' +
|
|
68
|
-
'<canvas id="odg-cv"></canvas>' +
|
|
69
|
-
'<div class="graph-overlay">' +
|
|
70
|
-
'<div class="graph-tools">' +
|
|
71
|
-
'<div class="seg" id="odg-tier">' +
|
|
72
|
-
'<button data-tier="1" class="active">Communities</button>' +
|
|
73
|
-
'<button data-tier="2" class="active">Entities</button>' +
|
|
74
|
-
'<button data-tier="3" class="active">Episodes</button>' +
|
|
75
|
-
'</div>' +
|
|
76
|
-
'<div class="seg" id="odg-layout">' +
|
|
77
|
-
'<button data-lay="fcose" class="active">Force</button>' +
|
|
78
|
-
'<button data-lay="concentric">By importance</button>' +
|
|
79
|
-
'</div>' +
|
|
80
|
-
'<label class="chip" style="gap:8px" title="How many nodes to show">' +
|
|
81
|
-
'<span data-ic="filter"></span> Nodes ' +
|
|
82
|
-
/* step=10, not 20: the default budget is 50, and a step-20 grid
|
|
83
|
-
starting at min=20 only permits 20/40/60/... so the browser
|
|
84
|
-
silently snapped the control to 60 while the label beside it
|
|
85
|
-
printed MAX_NODES as 50 — the control and its own label
|
|
86
|
-
disagreed on first paint. */
|
|
87
|
-
'<input id="odg-budget" type="range" min="20" max="2000" step="10" value="' + MAX_NODES + '" style="width:96px;accent-color:var(--violet)">' +
|
|
88
|
-
'<span class="cnt" id="odg-budgetv">' + MAX_NODES + '</span>' +
|
|
89
|
-
'</label>' +
|
|
90
|
-
'<button id="odg-showall" class="chip" style="padding:2px 10px;font-size:12px;cursor:pointer" title="Show all nodes (up to 2000)">All</button>' +
|
|
91
|
-
'<span class="badge neutral" id="odg-count">-- nodes</span>' +
|
|
92
|
-
'</div>' +
|
|
93
|
-
'<div class="graph-legend card glass" id="odg-legend"></div>' +
|
|
94
|
-
'<div class="graph-zoom card">' +
|
|
95
|
-
'<button id="odg-zin" aria-label="Zoom in">+</button>' +
|
|
96
|
-
'<button id="odg-zout" aria-label="Zoom out">-</button>' +
|
|
97
|
-
'<button id="odg-zfit" aria-label="Fit" title="Fit to view">⥂</button>' +
|
|
98
|
-
'</div>' +
|
|
99
|
-
/* odg-panel-toggle: below 1100 px the graph-shell collapses to a single
|
|
100
|
-
column and the inspector / Ask-your-memory / Quick Insights stack below
|
|
101
|
-
the 60vh stage — out of view with nothing indicating they are there.
|
|
102
|
-
This button floats at centre-bottom of the stage overlay, tells the
|
|
103
|
-
user the panel exists, and scrolls it into view on click or Enter.
|
|
104
|
-
CSS hides it at >1100px where the panel is already beside the stage
|
|
105
|
-
in the two-column grid (a permanent toggle there is clutter). */
|
|
106
|
-
'<button id="odg-panel-toggle" ' +
|
|
107
|
-
'aria-label="Show inspector and Ask your memory panel">' +
|
|
108
|
-
'Details & Chat ↓' +
|
|
109
|
-
'</button>' +
|
|
110
|
-
'</div>' +
|
|
111
|
-
'</div>' +
|
|
112
|
-
/* tabindex="-1" makes the inspector programmatically focusable so the
|
|
113
|
-
odg-panel-toggle onclick can re-anchor keyboard focus here after the
|
|
114
|
-
scroll, preventing the "focus is off-screen" accessibility gap.
|
|
115
|
-
tabindex="-1" is NOT a tab stop — it keeps the element out of the
|
|
116
|
-
natural tab order while allowing focus() from code only. */
|
|
117
|
-
'<aside class="inspector" tabindex="-1">' +
|
|
118
|
-
/* odg-back-btn: companion to #odg-panel-toggle. Visible only at ≤1100px
|
|
119
|
-
(same breakpoint). Appears at the very top of the stacked inspector so
|
|
120
|
-
keyboard users can return to the graph stage without tabbing through all
|
|
121
|
-
inspector content first. CSS hides it at >1100px. */
|
|
122
|
-
'<button class="odg-back-btn" aria-label="Back to graph canvas">' +
|
|
123
|
-
'↑ Graph' +
|
|
124
|
-
'</button>' +
|
|
125
|
-
'<div class="inspector-scroll" id="odg-insp">' +
|
|
126
|
-
'<div class="inspector-empty"><div style="font-size:34px;margin-bottom:8px">◇</div>' +
|
|
127
|
-
'Loading your knowledge graph…</div>' +
|
|
128
|
-
'</div>' +
|
|
129
|
-
// Quick Insight Actions — restored: 5 data-insight-action buttons + #insight-results.
|
|
130
|
-
// quick-actions.js (global, non-IIFE) defines fetchInsight(action) which calls
|
|
131
|
-
// GET /api/v3/insights/{action} and writes into #insight-results.
|
|
132
|
-
// Delegation wired in wireControls() so buttons survive re-renders.
|
|
133
|
-
'<div id="odg-insights-panel" style="border-top:1px solid var(--border);' +
|
|
134
|
-
'padding:10px 12px 8px">' +
|
|
135
|
-
'<div style="font-size:10.5px;font-weight:600;color:var(--fg-3);' +
|
|
136
|
-
'text-transform:uppercase;letter-spacing:0.06em;margin-bottom:7px">' +
|
|
137
|
-
'Quick Insights</div>' +
|
|
138
|
-
'<div style="display:flex;flex-wrap:wrap;gap:5px;margin-bottom:7px">' +
|
|
139
|
-
'<button class="chip" style="font-size:11px;padding:3px 9px;cursor:pointer" ' +
|
|
140
|
-
'data-insight-action="changed_this_week">Changed This Week</button>' +
|
|
141
|
-
'<button class="chip" style="font-size:11px;padding:3px 9px;cursor:pointer" ' +
|
|
142
|
-
'data-insight-action="opinions">Opinions</button>' +
|
|
143
|
-
'<button class="chip" style="font-size:11px;padding:3px 9px;cursor:pointer" ' +
|
|
144
|
-
'data-insight-action="contradictions">Contradictions</button>' +
|
|
145
|
-
'<button class="chip" style="font-size:11px;padding:3px 9px;cursor:pointer" ' +
|
|
146
|
-
'data-insight-action="health">Memory Health</button>' +
|
|
147
|
-
'<button class="chip" style="font-size:11px;padding:3px 9px;cursor:pointer" ' +
|
|
148
|
-
'data-insight-action="cross_project">Cross-Project</button>' +
|
|
149
|
-
'</div>' +
|
|
150
|
-
// #insight-results — quick-actions.js writes here via document.getElementById
|
|
151
|
-
'<div id="insight-results" ' +
|
|
152
|
-
'style="max-height:200px;overflow-y:auto;font-size:12px"></div>' +
|
|
153
|
-
'</div>' +
|
|
154
|
-
'<div class="ask">' +
|
|
155
|
-
'<div class="ask-head"><span data-ic="brain"></span> Ask your memory</div>' +
|
|
156
|
-
'<div class="ask-log" id="odg-log">' +
|
|
157
|
-
'<div class="msg a">Ask a question and I’ll answer from your own memory — with the facts I used as citations.</div>' +
|
|
158
|
-
'</div>' +
|
|
159
|
-
'<div class="ask-input">' +
|
|
160
|
-
'<input id="odg-ask" placeholder="Ask over your memory…" autocomplete="off">' +
|
|
161
|
-
'<button id="odg-send" data-ic="send" aria-label="Send"></button>' +
|
|
162
|
-
'</div>' +
|
|
163
|
-
'</div>' +
|
|
164
|
-
'</aside>' +
|
|
165
|
-
'</div>';
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function q(sel) { return mount ? mount.querySelector(sel) : null; }
|
|
169
|
-
|
|
170
|
-
/* ---- deterministic colour helpers ---- */
|
|
171
|
-
function hashStr(s) {
|
|
172
|
-
var h = 5381, i;
|
|
173
|
-
for (i = 0; i < s.length; i++) h = (((h << 5) + h) + s.charCodeAt(i)) | 0;
|
|
174
|
-
return (h >>> 0); /* unsigned 32-bit -- never negative */
|
|
175
|
-
}
|
|
176
|
-
function commColor(cid) {
|
|
177
|
-
return CAT_PALETTE[hashStr(String(cid)) % CAT_PALETTE.length];
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/* ---------------- data -> tiered graph (real fields only) ---------------- */
|
|
181
|
-
function shortWords(s, n) {
|
|
182
|
-
return String(s || '').trim().split(/\s+/).slice(0, n || 4).join(' ');
|
|
183
|
-
}
|
|
184
|
-
function catColor(cat) {
|
|
185
|
-
if (cat === 'episodic' || cat === 'temporal') return 'episode';
|
|
186
|
-
if (cat === 'semantic' || cat === 'opinion') return 'entity';
|
|
187
|
-
return 'community';
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function buildGraph(graph, entityResp) {
|
|
191
|
-
NODES = []; LINKS = []; idx = {};
|
|
192
|
-
function add(n) {
|
|
193
|
-
n.x = (Math.random() - 0.5) * 600; n.y = (Math.random() - 0.5) * 400;
|
|
194
|
-
n.vx = 0; n.vy = 0;
|
|
195
|
-
if (!n.r) n.r = 6 + (n.imp || 5) * 1.7; /* fallback radius */
|
|
196
|
-
NODES.push(n); idx[n.id] = n;
|
|
197
|
-
}
|
|
198
|
-
var rawNodes = (graph && graph.nodes) || [];
|
|
199
|
-
var rawLinks = (graph && graph.links) || [];
|
|
200
|
-
|
|
201
|
-
/* tier 1 -- communities from real community_id grouping */
|
|
202
|
-
var comm = {};
|
|
203
|
-
rawNodes.forEach(function (n) {
|
|
204
|
-
var cid = (n.community_id === 0 || n.community_id) ? String(n.community_id) : null;
|
|
205
|
-
if (!cid) return;
|
|
206
|
-
if (!comm[cid]) comm[cid] = { count: 0, imp: 0 };
|
|
207
|
-
comm[cid].count++;
|
|
208
|
-
comm[cid].imp = Math.max(comm[cid].imp, Math.round((n.importance || 0.5) * 10));
|
|
209
|
-
});
|
|
210
|
-
Object.keys(comm).forEach(function (cid) {
|
|
211
|
-
add({ id: 'comm:' + cid, label: 'Community · ' + comm[cid].count, tier: 1,
|
|
212
|
-
type: 'community', imp: Math.min(10, 5 + Math.round(comm[cid].count / 4)),
|
|
213
|
-
r: 14 + Math.min(16, comm[cid].count * 0.9), /* radius scales with member count */
|
|
214
|
-
members: comm[cid].count });
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
/* tier 2 -- entities from /api/entity/list */
|
|
218
|
-
var entByName = {};
|
|
219
|
-
var ents = (entityResp && entityResp.entities) || [];
|
|
220
|
-
ents.forEach(function (e) {
|
|
221
|
-
var id = 'ent:' + (e.entity_id || e.name);
|
|
222
|
-
var imp = Math.max(3, Math.min(10, Math.round((e.confidence || 0.5) * 10) + 2));
|
|
223
|
-
add({ id: id, label: e.name, tier: 2, type: 'entity',
|
|
224
|
-
etype: e.type || 'concept', facts: e.fact_count || 0,
|
|
225
|
-
imp: imp, r: 6 + imp * 2.2, /* radius scales with importance */
|
|
226
|
-
summary: e.summary_preview || '', lastSeen: (e.last_seen || '').slice(0, 10) });
|
|
227
|
-
if (e.name) entByName[String(e.name).toLowerCase()] = id;
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
/* tier 3 -- episodes = real memory nodes */
|
|
231
|
-
rawNodes.forEach(function (n) {
|
|
232
|
-
var id = String(n.id);
|
|
233
|
-
var content = n.content || n.content_preview || '';
|
|
234
|
-
var imp = Math.max(2, Math.round((n.importance || 0.5) * 10));
|
|
235
|
-
add({ id: id, label: shortWords(content, 4) + '…', tier: 3, type: 'episode',
|
|
236
|
-
ftype: n.category || 'memory', imp: imp, r: 4 + imp * 1.4, /* smallest tier */
|
|
237
|
-
comm: (n.community_id === 0 || n.community_id) ? 'comm:' + n.community_id : null,
|
|
238
|
-
content: content, created: (n.created_at || '').slice(0, 10),
|
|
239
|
-
project: n.project_name || '', entities: n.entities || [],
|
|
240
|
-
catKey: catColor(n.category) });
|
|
241
|
-
/* episode -> community (real grouping) */
|
|
242
|
-
if (idx['comm:' + n.community_id]) LINKS.push({ s: 'comm:' + n.community_id, t: id, rt: 'entity', w: 0.4 });
|
|
243
|
-
/* episode -> entity (real: node.entities names) */
|
|
244
|
-
(n.entities || []).forEach(function (nm) {
|
|
245
|
-
var eid = entByName[String(nm).toLowerCase()];
|
|
246
|
-
if (eid) LINKS.push({ s: eid, t: id, rt: 'entity', w: 0.3 });
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
/* real relationship edges -- keep the strongest to avoid hairball */
|
|
251
|
-
var rel = [];
|
|
252
|
-
rawLinks.forEach(function (l) {
|
|
253
|
-
var s = String(l.source), t = String(l.target);
|
|
254
|
-
if (idx[s] && idx[t]) rel.push({ s: s, t: t, rt: l.relationship_type || 'related', w: l.weight || 0.5 });
|
|
255
|
-
});
|
|
256
|
-
rel.sort(function (a, b) { return b.w - a.w; });
|
|
257
|
-
rel.slice(0, Math.round(NODES.length * 1.4)).forEach(function (l) { LINKS.push(l); });
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/* ---------------- palette + canvas sizing ---------------- */
|
|
261
|
-
function readPalette() {
|
|
262
|
-
var cs = getComputedStyle(document.documentElement);
|
|
263
|
-
function v(k) { return cs.getPropertyValue(k).trim(); }
|
|
264
|
-
PAL = { fg: v('--fg'), fg2: v('--fg-2'), border: v('--border-strong'), card: v('--card'),
|
|
265
|
-
danger: v('--danger'), cyan: v('--cyan') };
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/* categorical node colour -- deterministic, theme-independent */
|
|
269
|
-
function nodeColor(n) {
|
|
270
|
-
if (n.type === 'episode') return EPISODE_COLOR;
|
|
271
|
-
if (n.type === 'community') return commColor(n.id.replace('comm:', ''));
|
|
272
|
-
/* entity: fixed type colour if known, else hash the type name */
|
|
273
|
-
return ETYPE_COLORS[n.etype] || commColor(n.etype || 'unknown');
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function resize() {
|
|
277
|
-
if (!stage || !cv) return;
|
|
278
|
-
/* Read into locals and only COMMIT to W/H once they are real.
|
|
279
|
-
A stage that reports 0x0 is not yet laid out (hidden tab, off-screen
|
|
280
|
-
pane). Drawing into a zero-sized canvas produces the blank-on-cold-load
|
|
281
|
-
failure the owner reported. Equally important: writing 0 into W/H before
|
|
282
|
-
bailing would POISON the last-known-good size — a window resize while the
|
|
283
|
-
graph pane is hidden would zero them, and loop() would then have no valid
|
|
284
|
-
dimensions to work with. Keep the previous good values instead; the
|
|
285
|
-
ResizeObserver re-calls resize() the moment the stage has real pixels. */
|
|
286
|
-
var w = stage.clientWidth, h = stage.clientHeight;
|
|
287
|
-
if (!w || !h) return;
|
|
288
|
-
W = w; H = h;
|
|
289
|
-
cv.width = W * dpr; cv.height = H * dpr; cv.style.width = W + 'px'; cv.style.height = H + 'px';
|
|
290
|
-
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
291
|
-
}
|
|
292
|
-
function visible(n) { return !!tierVisible[n.tier]; }
|
|
293
|
-
function visLink(l) { return idx[l.s] && idx[l.t] && visible(idx[l.s]) && visible(idx[l.t]); }
|
|
294
|
-
|
|
295
|
-
/* ---------------- physics (ported from design) ---------------- */
|
|
296
|
-
function tick() {
|
|
297
|
-
/* Force repulsion is O(n^2). Render every requested node, but only
|
|
298
|
-
simulate a stable bounded subset so the dashboard remains interactive
|
|
299
|
-
for existing installs with very large graphs. */
|
|
300
|
-
var vis = NODES.filter(visible).slice(0, PHYSICS_MAX_NODES), simulated = {}, i, j;
|
|
301
|
-
vis.forEach(function (n) { simulated[n.id] = true; });
|
|
302
|
-
for (i = 0; i < vis.length; i++) {
|
|
303
|
-
var a = vis[i];
|
|
304
|
-
for (j = i + 1; j < vis.length; j++) {
|
|
305
|
-
var b = vis[j];
|
|
306
|
-
var dx = a.x - b.x, dy = a.y - b.y, d2 = dx * dx + dy * dy + 0.01, d = Math.sqrt(d2);
|
|
307
|
-
var f = 3600 / d2, fx = dx / d * f, fy = dy / d * f; /* repulsion */
|
|
308
|
-
a.vx += fx; a.vy += fy; b.vx -= fx; b.vy -= fy;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
LINKS.forEach(function (l) {
|
|
312
|
-
if (!visLink(l) || !simulated[l.s] || !simulated[l.t]) return;
|
|
313
|
-
var a = idx[l.s], b = idx[l.t];
|
|
314
|
-
var dx = b.x - a.x, dy = b.y - a.y, d = Math.sqrt(dx * dx + dy * dy) + 0.01;
|
|
315
|
-
var rest = (a.type === 'community' || b.type === 'community') ? 150 : 100;
|
|
316
|
-
var f = (d - rest) * 0.02, fx = dx / d * f, fy = dy / d * f;
|
|
317
|
-
a.vx += fx; a.vy += fy; b.vx -= fx; b.vy -= fy;
|
|
318
|
-
});
|
|
319
|
-
var mv2 = 0;
|
|
320
|
-
vis.forEach(function (n) {
|
|
321
|
-
if (n === dragNode) return;
|
|
322
|
-
n.vx += -n.x * 0.002; n.vy += -n.y * 0.002; /* gravity toward centre */
|
|
323
|
-
n.vx *= 0.86; n.vy *= 0.86; n.x += n.vx; n.y += n.vy;
|
|
324
|
-
if (!isFinite(n.x) || !isFinite(n.y)) { n.x = (Math.random() - 0.5) * 200; n.y = (Math.random() - 0.5) * 200; n.vx = 0; n.vy = 0; }
|
|
325
|
-
var v2 = n.vx * n.vx + n.vy * n.vy;
|
|
326
|
-
if (v2 > mv2) mv2 = v2;
|
|
327
|
-
});
|
|
328
|
-
_ke = mv2; /* max per-node kinetic energy */
|
|
329
|
-
}
|
|
330
|
-
function W2S(x, y) { return [x * scale + ox + W / 2, y * scale + oy + H / 2]; }
|
|
331
|
-
function S2W(px, py) { return [(px - ox - W / 2) / scale, (py - oy - H / 2) / scale]; }
|
|
332
|
-
|
|
333
|
-
function draw() {
|
|
334
|
-
if (!ctx) return;
|
|
335
|
-
ctx.clearRect(0, 0, W, H);
|
|
336
|
-
LINKS.forEach(function (l) {
|
|
337
|
-
if (!visLink(l)) return;
|
|
338
|
-
var a = W2S(idx[l.s].x, idx[l.s].y), b = W2S(idx[l.t].x, idx[l.t].y);
|
|
339
|
-
var contra = l.rt === 'contradiction' || l.rt === 'supersedes';
|
|
340
|
-
ctx.beginPath(); ctx.moveTo(a[0], a[1]); ctx.lineTo(b[0], b[1]);
|
|
341
|
-
ctx.strokeStyle = contra ? PAL.danger : PAL.border;
|
|
342
|
-
ctx.globalAlpha = contra ? 0.75 : 0.45; ctx.lineWidth = contra ? 1.6 : 1;
|
|
343
|
-
ctx.setLineDash(contra ? [4, 3] : []); ctx.stroke(); ctx.setLineDash([]); ctx.globalAlpha = 1;
|
|
344
|
-
});
|
|
345
|
-
NODES.forEach(function (n) {
|
|
346
|
-
if (!visible(n)) return;
|
|
347
|
-
var p = W2S(n.x, n.y), r = n.r * Math.sqrt(scale);
|
|
348
|
-
if (n === selected) { ctx.beginPath(); ctx.arc(p[0], p[1], r + 6, 0, 7); ctx.strokeStyle = PAL.cyan; ctx.lineWidth = 2; ctx.stroke(); }
|
|
349
|
-
ctx.beginPath(); ctx.arc(p[0], p[1], r, 0, 7);
|
|
350
|
-
ctx.fillStyle = nodeColor(n); ctx.globalAlpha = (n === hover || n === selected) ? 1 : 0.92; ctx.fill(); ctx.globalAlpha = 1;
|
|
351
|
-
ctx.lineWidth = 1.5; ctx.strokeStyle = PAL.card; ctx.stroke();
|
|
352
|
-
if (n.tier < 3 || n === hover || n === selected || scale > 1.6) {
|
|
353
|
-
ctx.fillStyle = PAL.fg;
|
|
354
|
-
ctx.font = (n.tier === 1 ? '650 ' : '500 ') + (n.tier === 1 ? 13 : 11.5) + 'px -apple-system,system-ui,sans-serif';
|
|
355
|
-
ctx.textAlign = 'center'; ctx.fillText(n.label, p[0], p[1] + r + 13);
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function loop() {
|
|
361
|
-
if (!running) return;
|
|
362
|
-
/* Blind frame: the stage has no size yet. Two failure modes to avoid, and
|
|
363
|
-
they pull in opposite directions —
|
|
364
|
-
(a) Spending the settle budget while blind. fit() derives scale/ox/oy
|
|
365
|
-
from W/H, so frames rendered at 0x0 park the camera off-screen:
|
|
366
|
-
measured 16,362 arc() calls, every one at x ~= -2,300, canvas
|
|
367
|
-
visually empty. That was the original "blank until I move the node
|
|
368
|
-
slider" bug.
|
|
369
|
-
(b) Idling forever. Re-scheduling rAF unconditionally kept a 60fps
|
|
370
|
-
callback alive on a hidden pane — the graph stays mounted after you
|
|
371
|
-
navigate away, so one window resize while hidden burned CPU
|
|
372
|
-
indefinitely.
|
|
373
|
-
So: retry for a BOUNDED window, then park. The retry covers a cold load
|
|
374
|
-
where layout lands a beat after mount (parking immediately there left the
|
|
375
|
-
first visit blank while re-visits worked). The bound means a hidden pane
|
|
376
|
-
can never hold the loop open — after ~3s it stops, and the ResizeObserver
|
|
377
|
-
calls wake() if the stage ever gains size. */
|
|
378
|
-
if (!W || !H) {
|
|
379
|
-
if (blindFrames++ < BLIND_MAX_FRAMES) { raf = requestAnimationFrame(loop); return; }
|
|
380
|
-
running = false; raf = null; blindFrames = 0; return;
|
|
381
|
-
}
|
|
382
|
-
blindFrames = 0;
|
|
383
|
-
tick();
|
|
384
|
-
if (fitFrames < 90) { fit(); fitFrames++; } /* keep settling cloud in view */
|
|
385
|
-
draw();
|
|
386
|
-
frames++;
|
|
387
|
-
if ((frames > SETTLE_MIN && _ke < SETTLE_KE) || frames > SETTLE_MAX_FRAMES) {
|
|
388
|
-
running = false; raf = null; return;
|
|
389
|
-
}
|
|
390
|
-
raf = requestAnimationFrame(loop);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/* wake: restart physics after a perturbation (drag, toggle, budget change) */
|
|
394
|
-
function wake() { frames = 0; if (!running) { running = true; loop(); } }
|
|
395
|
-
/* Window resize: resize() wipes the canvas, so re-fit and repaint after it.
|
|
396
|
-
Named (not an inline closure) so teardown() can actually remove it — the
|
|
397
|
-
previous inline `resize` binding was re-added on every mount and never
|
|
398
|
-
removed, so listeners accumulated one per pane visit. */
|
|
399
|
-
function onWinResize() { resize(); fitFrames = 0; wake(); }
|
|
400
|
-
/* redraw: single repaint when sim is frozen (pan/zoom/hover) */
|
|
401
|
-
function redraw() { if (!running) draw(); }
|
|
402
|
-
|
|
403
|
-
/* ---------------- interactions ---------------- */
|
|
404
|
-
function nodeAt(px, py) {
|
|
405
|
-
var w = S2W(px, py), best = null, bd = 1e9;
|
|
406
|
-
NODES.forEach(function (n) {
|
|
407
|
-
if (!visible(n)) return;
|
|
408
|
-
var dx = n.x - w[0], dy = n.y - w[1], d = Math.sqrt(dx * dx + dy * dy);
|
|
409
|
-
if (d < n.r + 6 && d < bd) { bd = d; best = n; }
|
|
410
|
-
});
|
|
411
|
-
return best;
|
|
412
|
-
}
|
|
413
|
-
function fit() {
|
|
414
|
-
var vis = NODES.filter(visible); if (!vis.length) return;
|
|
415
|
-
var xs = vis.map(function (n) { return n.x; }), ys = vis.map(function (n) { return n.y; });
|
|
416
|
-
var minx = Math.min.apply(0, xs), maxx = Math.max.apply(0, xs), miny = Math.min.apply(0, ys), maxy = Math.max.apply(0, ys);
|
|
417
|
-
var w = maxx - minx + 160, h = maxy - miny + 160;
|
|
418
|
-
scale = Math.max(0.35, Math.min(1.4, Math.min(W / w, H / h) || 1));
|
|
419
|
-
ox = -((minx + maxx) / 2) * scale; oy = -((miny + maxy) / 2) * scale;
|
|
420
|
-
}
|
|
421
|
-
function concentric() {
|
|
422
|
-
var vis = NODES.filter(visible).slice().sort(function (a, b) { return b.imp - a.imp; });
|
|
423
|
-
vis.forEach(function (n, i) { var ring = 10 - n.imp, ang = i * 2.399, rad = ring * 46 + 30; n.x = Math.cos(ang) * rad; n.y = Math.sin(ang) * rad; n.vx = 0; n.vy = 0; });
|
|
424
|
-
}
|
|
425
|
-
function updateCount() {
|
|
426
|
-
var c = q('#odg-count'); if (!c) return;
|
|
427
|
-
c.textContent = NODES.filter(visible).length + ' nodes · ' + LINKS.filter(visLink).length + ' edges';
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/* ---- dynamic legend: reflects what is actually on screen ---- */
|
|
431
|
-
function updateLegend() {
|
|
432
|
-
var el = q('#odg-legend'); if (!el) return;
|
|
433
|
-
var lines = [];
|
|
434
|
-
/* communities sorted by member count -- up to 8 entries */
|
|
435
|
-
if (tierVisible[1]) {
|
|
436
|
-
NODES.filter(function (n) { return n.type === 'community'; })
|
|
437
|
-
.sort(function (a, b) { return b.members - a.members; })
|
|
438
|
-
.slice(0, 8).forEach(function (cn) {
|
|
439
|
-
var cid = cn.id.replace('comm:', '');
|
|
440
|
-
lines.push('<div class="k"><b style="background:' + commColor(cid) + '"></b> Cluster ' + cid +
|
|
441
|
-
' <span style="opacity:0.55;font-size:10px">(' + cn.members + ')</span></div>');
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
/* entity types -- up to 4 most common */
|
|
445
|
-
if (tierVisible[2]) {
|
|
446
|
-
var etypes = {};
|
|
447
|
-
NODES.filter(function (n) { return n.type === 'entity'; })
|
|
448
|
-
.forEach(function (n) { etypes[n.etype] = (etypes[n.etype] || 0) + 1; });
|
|
449
|
-
var etArr = Object.keys(etypes).sort(function (a, b) { return etypes[b] - etypes[a]; }).slice(0, 4);
|
|
450
|
-
if (etArr.length) {
|
|
451
|
-
if (lines.length) lines.push('<hr style="border:none;border-top:1px solid var(--border);margin:5px 0">');
|
|
452
|
-
etArr.forEach(function (et) {
|
|
453
|
-
var col = ETYPE_COLORS[et] || commColor(et || 'unknown');
|
|
454
|
-
lines.push('<div class="k"><b style="background:' + col + '"></b> ' + esc(et || 'unknown') +
|
|
455
|
-
' <span style="opacity:0.55;font-size:10px">(' + etypes[et] + ')</span></div>');
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
/* episodes -- single entry */
|
|
460
|
-
if (tierVisible[3]) {
|
|
461
|
-
if (lines.length) lines.push('<hr style="border:none;border-top:1px solid var(--border);margin:5px 0">');
|
|
462
|
-
lines.push('<div class="k"><b style="background:' + EPISODE_COLOR + '"></b> Episode</div>');
|
|
463
|
-
}
|
|
464
|
-
if (!lines.length) lines.push('<div class="k" style="opacity:0.5">No tiers visible</div>');
|
|
465
|
-
el.innerHTML = lines.join('');
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/* ---------------- inspector ---------------- */
|
|
469
|
-
var ETNAME = { person: 'Person', org: 'Organization', concept: 'Concept', event: 'Event' };
|
|
470
|
-
function bar(v, max) {
|
|
471
|
-
return '<span style="display:inline-block;vertical-align:middle;width:70px;height:6px;border-radius:99px;background:var(--card-2);overflow:hidden;margin-right:7px"><span style="display:block;height:100%;width:' + (v / max * 100) + '%;background:linear-gradient(90deg,var(--cyan),var(--violet))"></span></span>';
|
|
472
|
-
}
|
|
473
|
-
function field(k, v) { return '<div class="field"><div class="k">' + k + '</div><div class="v">' + v + '</div></div>'; }
|
|
474
|
-
function esc(s) { return String(s == null ? '' : s).replace(/[&<>]/g, function (c) { return { '&': '&', '<': '<', '>': '>' }[c]; }); }
|
|
475
|
-
function escAttr(s) { return esc(s).replace(/"/g, '"'); }
|
|
476
|
-
|
|
477
|
-
function selectById(id) {
|
|
478
|
-
var n = idx[id];
|
|
479
|
-
if (n) {
|
|
480
|
-
/* if the node's tier is hidden, reveal it and sync the button */
|
|
481
|
-
if (!tierVisible[n.tier]) {
|
|
482
|
-
tierVisible[n.tier] = true;
|
|
483
|
-
var btn = mount ? mount.querySelector('#odg-tier button[data-tier="' + n.tier + '"]') : null;
|
|
484
|
-
if (btn) btn.classList.add('active');
|
|
485
|
-
updateCount(); updateLegend();
|
|
486
|
-
}
|
|
487
|
-
selected = n; renderInsp(n); redraw();
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
window.odgSelect = selectById;
|
|
491
|
-
|
|
492
|
-
function renderInsp(n) {
|
|
493
|
-
var el = q('#odg-insp'); if (!el) return;
|
|
494
|
-
var col = nodeColor(n);
|
|
495
|
-
var badge = '<span class="badge ' + (n.type === 'episode' ? 'cyan' : n.type === 'entity' ? 'violet' : 'warn') + '">' + n.type + '</span>';
|
|
496
|
-
var h = '<div style="display:flex;align-items:center;gap:11px;margin-bottom:14px">' +
|
|
497
|
-
'<span class="avatar" style="background:' + col + '">' + esc((n.label[0] || '#')) + '</span>' +
|
|
498
|
-
'<div><div style="font-weight:650;font-size:15px;line-height:1.2">' + esc(n.label.replace('…', '')) + '</div><div style="margin-top:4px">' + badge + '</div></div></div>';
|
|
499
|
-
if (n.type === 'episode') {
|
|
500
|
-
h += field('Content', '<span style="line-height:1.55">' + esc(n.content) + '</span>');
|
|
501
|
-
h += field('Fact type', '<span class="badge neutral">' + esc(n.ftype) + '</span>');
|
|
502
|
-
h += field('Importance', bar(n.imp, 10) + ' <b>' + n.imp + '</b>/10');
|
|
503
|
-
if (n.project) h += field('Project', '<span class="mono">' + esc(n.project) + '</span>');
|
|
504
|
-
if (n.created) h += field('Created', '<span class="mono">' + esc(n.created) + '</span>');
|
|
505
|
-
} else if (n.type === 'entity') {
|
|
506
|
-
h += field('Entity type', '<span class="badge neutral">' + esc(ETNAME[n.etype] || n.etype) + '</span>');
|
|
507
|
-
h += field('Facts about this', '<b>' + n.facts + '</b> atomic facts');
|
|
508
|
-
if (n.summary) h += field('Summary', '<span style="line-height:1.5">' + esc(n.summary) + '</span>');
|
|
509
|
-
if (n.lastSeen) h += field('Last seen', '<span class="mono">' + esc(n.lastSeen) + '</span>');
|
|
510
|
-
h += field('Connections', LINKS.filter(function (l) { return l.s === n.id || l.t === n.id; }).length + ' edges');
|
|
511
|
-
} else {
|
|
512
|
-
h += field('Members', '<b>' + (n.members || 0) + '</b> memories');
|
|
513
|
-
h += field('Importance', bar(n.imp, 10) + ' <b>' + n.imp + '</b>/10');
|
|
514
|
-
}
|
|
515
|
-
var nb = LINKS.filter(function (l) { return l.s === n.id || l.t === n.id; }).slice(0, 6).map(function (l) {
|
|
516
|
-
var o = idx[l.s === n.id ? l.t : l.s]; if (!o) return '';
|
|
517
|
-
return '<div class="list-row" style="padding:8px 0;cursor:pointer" data-act-click="odg-select" data-odg-id="' + escAttr(o.id) + '">' +
|
|
518
|
-
'<span style="width:9px;height:9px;border-radius:50%;background:' + nodeColor(o) + '"></span>' +
|
|
519
|
-
'<span style="flex:1;font-size:12.5px">' + esc(o.label.replace('…', '')) + '</span>' +
|
|
520
|
-
'<span class="badge neutral" style="font-size:10px">' + esc(l.rt) + '</span></div>';
|
|
521
|
-
}).join('');
|
|
522
|
-
if (nb) h += '<div class="field"><div class="k" style="margin-bottom:4px">Relationships</div>' + nb + '</div>';
|
|
523
|
-
el.innerHTML = h;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/* ---------------- Ask-Memory (real /api/search) ---------------- */
|
|
527
|
-
function push(cls, html) {
|
|
528
|
-
var log = q('#odg-log'); if (!log) return null;
|
|
529
|
-
var d = document.createElement('div'); d.className = 'msg ' + cls; d.innerHTML = html;
|
|
530
|
-
log.appendChild(d); log.scrollTop = log.scrollHeight; return d;
|
|
531
|
-
}
|
|
532
|
-
function sendAsk() {
|
|
533
|
-
var input = q('#odg-ask'); if (!input) return;
|
|
534
|
-
var query = input.value.trim(); if (!query) return; input.value = '';
|
|
535
|
-
push('q', esc(query));
|
|
536
|
-
var t = push('a', '<span class="typing"><i></i><i></i><i></i></span>');
|
|
537
|
-
fetch(RECALL_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: query, limit: 5 }) })
|
|
538
|
-
.then(function (r) { if (!r.ok) throw new Error(r.status); return r.json(); })
|
|
539
|
-
.then(function (data) {
|
|
540
|
-
var items = data.results || data.memories || data.facts || (Array.isArray(data) ? data : []);
|
|
541
|
-
if (!items.length) { t.innerHTML = 'No stored memory matched that yet.'; return; }
|
|
542
|
-
var top = items[0];
|
|
543
|
-
var ans = esc(top.content || top.text || top.summary || ('Found ' + items.length + ' related memories.'));
|
|
544
|
-
var cites = items.slice(0, 4).map(function (it) {
|
|
545
|
-
var id = String(it.id || it.fact_id || '');
|
|
546
|
-
var lbl = esc(shortWords(it.content || it.text || it.summary || 'fact', 4));
|
|
547
|
-
return '<span class="cite"' + (idx[id] ? ' data-act-click="odg-select" data-odg-id="' + escAttr(id) + '"' : '') + '>◈ ' + lbl + '</span>';
|
|
548
|
-
}).join('');
|
|
549
|
-
t.innerHTML = ans + (cites ? '<div style="margin-top:8px">' + cites + '</div>' : '');
|
|
550
|
-
})
|
|
551
|
-
.catch(function () { t.innerHTML = 'Could not reach recall right now. Try again in a moment.'; });
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/* ---------------- wiring ---------------- */
|
|
555
|
-
function wireControls() {
|
|
556
|
-
stage = q('#odg-stage'); cv = q('#odg-cv'); ctx = cv.getContext('2d');
|
|
557
|
-
|
|
558
|
-
/* On a cold tab load the graph pane is inside a CSS-hidden tab; the browser
|
|
559
|
-
reports clientWidth/clientHeight = 0 until the tab is actually shown.
|
|
560
|
-
resize() now refuses to commit to a 0×0 canvas (the root cause of the
|
|
561
|
-
"blank on first load, paints after slider drag" bug). ResizeObserver is
|
|
562
|
-
the platform-correct remedy: it fires exactly once when the stage first
|
|
563
|
-
acquires real pixel dimensions, without polling and without a fixed
|
|
564
|
-
setTimeout that cannot be proved race-free. */
|
|
565
|
-
sizeObs = new ResizeObserver(function (entries) {
|
|
566
|
-
var entry = entries[0];
|
|
567
|
-
if (!entry) return;
|
|
568
|
-
var rect = entry.contentRect;
|
|
569
|
-
if (rect.width > 0 && rect.height > 0) {
|
|
570
|
-
/* ALWAYS re-fit and repaint after a size change — never conditionally.
|
|
571
|
-
resize() assigns cv.width, and assigning a canvas's width WIPES it,
|
|
572
|
-
even when the value is unchanged. So any call to resize() that is
|
|
573
|
-
not followed by a repaint leaves a blank canvas on screen.
|
|
574
|
-
An earlier version of this handler only repainted when the canvas
|
|
575
|
-
had previously been blind. Returning to the pane then hit the other
|
|
576
|
-
branch: W/H were stale-but-non-zero, resize() wiped the canvas, and
|
|
577
|
-
nothing redrew it — measured as 53,083 painted pixels on the first
|
|
578
|
-
visit and exactly 0 on the second, with no draw calls issued at all.
|
|
579
|
-
Re-fitting also matters because the pane can come back at a
|
|
580
|
-
different size, and a camera fitted to the old bounds frames the
|
|
581
|
-
wrong region. The settle budget is bounded, so waking here is cheap. */
|
|
582
|
-
resize();
|
|
583
|
-
fitFrames = 0; frames = 0;
|
|
584
|
-
wake();
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
sizeObs.observe(stage);
|
|
588
|
-
|
|
589
|
-
/* tier buttons -- independent toggles: each click flips visibility + re-renders */
|
|
590
|
-
mount.querySelectorAll('#odg-tier button').forEach(function (b) {
|
|
591
|
-
b.onclick = function () {
|
|
592
|
-
b.classList.toggle('active');
|
|
593
|
-
tierVisible[+b.dataset.tier] = b.classList.contains('active');
|
|
594
|
-
updateCount(); updateLegend(); fit(); wake();
|
|
595
|
-
};
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
/* layout buttons -- switch layout AND restart sim / static redraw */
|
|
599
|
-
mount.querySelectorAll('#odg-layout button').forEach(function (b) {
|
|
600
|
-
b.onclick = function () {
|
|
601
|
-
mount.querySelectorAll('#odg-layout button').forEach(function (x) { x.classList.remove('active'); });
|
|
602
|
-
b.classList.add('active');
|
|
603
|
-
if (b.dataset.lay === 'concentric') {
|
|
604
|
-
concentric(); fit(); redraw(); /* static radial layout -- no physics */
|
|
605
|
-
} else {
|
|
606
|
-
fitFrames = 0; frames = 0; wake(); /* force -- restart physics from current pos */
|
|
607
|
-
}
|
|
608
|
-
};
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
var budget = q('#odg-budget');
|
|
612
|
-
if (budget) budget.oninput = function () {
|
|
613
|
-
q('#odg-budgetv').textContent = budget.value; MAX_NODES = +budget.value; load();
|
|
614
|
-
};
|
|
615
|
-
|
|
616
|
-
/* "All" button -- jump to 2000 nodes and reload */
|
|
617
|
-
var showall = q('#odg-showall');
|
|
618
|
-
if (showall) showall.onclick = function () {
|
|
619
|
-
var bgt = q('#odg-budget');
|
|
620
|
-
if (bgt) { bgt.value = '2000'; q('#odg-budgetv').textContent = '2000'; }
|
|
621
|
-
MAX_NODES = 2000; load();
|
|
622
|
-
};
|
|
623
|
-
|
|
624
|
-
q('#odg-zin').onclick = function () { scale = Math.min(4, scale * 1.2); redraw(); };
|
|
625
|
-
q('#odg-zout').onclick = function () { scale = Math.max(0.3, scale * 0.83); redraw(); };
|
|
626
|
-
q('#odg-zfit').onclick = function () { fit(); redraw(); };
|
|
627
|
-
q('#odg-send').onclick = sendAsk;
|
|
628
|
-
q('#odg-ask').addEventListener('keydown', function (e) { if (e.key === 'Enter') sendAsk(); });
|
|
629
|
-
|
|
630
|
-
/* odg-panel-toggle / odg-back-btn — narrow-viewport affordances (≤1100px).
|
|
631
|
-
Both buttons are display:none at >1100px (CSS), so clicks can never fire
|
|
632
|
-
on a wide desktop. scrollIntoView does NOT call resize() and does NOT assign
|
|
633
|
-
cv.width — the canvas is never wiped, the render loop is undisturbed. */
|
|
634
|
-
var panelToggle = q('#odg-panel-toggle');
|
|
635
|
-
var inspector = q('.inspector');
|
|
636
|
-
var backBtn = q('.odg-back-btn');
|
|
637
|
-
if (panelToggle && inspector) {
|
|
638
|
-
panelToggle.onclick = function () {
|
|
639
|
-
inspector.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
640
|
-
/* Re-anchor keyboard focus to the inspector so users are not left with
|
|
641
|
-
focus on an off-screen button after the scroll animation completes. */
|
|
642
|
-
inspector.focus({ preventScroll: true });
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
if (backBtn) {
|
|
646
|
-
backBtn.onclick = function () {
|
|
647
|
-
var st = q('#odg-stage');
|
|
648
|
-
if (st) st.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
649
|
-
/* Return focus to the panel toggle so the user can re-invoke it. */
|
|
650
|
-
if (panelToggle) panelToggle.focus({ preventScroll: true });
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
// Quick Insight Actions — delegated on mount so buttons survive od-graph.js re-renders.
|
|
655
|
-
// quick-actions.js:fetchInsight() is global (non-IIFE); it writes into #insight-results
|
|
656
|
-
// which is mounted inside odg-insights-panel above.
|
|
657
|
-
mount.addEventListener('click', function (e) {
|
|
658
|
-
var btn = e.target.closest('[data-insight-action]');
|
|
659
|
-
if (btn && typeof fetchInsight === 'function') {
|
|
660
|
-
fetchInsight(btn.getAttribute('data-insight-action'));
|
|
661
|
-
}
|
|
662
|
-
});
|
|
663
|
-
|
|
664
|
-
cv.addEventListener('mousedown', function (e) {
|
|
665
|
-
var r = cv.getBoundingClientRect(), n = nodeAt(e.clientX - r.left, e.clientY - r.top);
|
|
666
|
-
if (n) { dragNode = n; selected = n; renderInsp(n); wake(); } else { panning = true; }
|
|
667
|
-
last = [e.clientX, e.clientY];
|
|
668
|
-
});
|
|
669
|
-
onMove = function (e) {
|
|
670
|
-
var r = cv.getBoundingClientRect(), mx = e.clientX - r.left, my = e.clientY - r.top;
|
|
671
|
-
if (dragNode) { var w = S2W(mx, my); dragNode.x = w[0]; dragNode.y = w[1]; dragNode.vx = 0; dragNode.vy = 0; wake(); }
|
|
672
|
-
else if (panning && last) { ox += e.clientX - last[0]; oy += e.clientY - last[1]; last = [e.clientX, e.clientY]; redraw(); }
|
|
673
|
-
else { var wasHover = hover; hover = nodeAt(mx, my); cv.style.cursor = hover ? 'pointer' : 'grab'; if (hover !== wasHover) redraw(); }
|
|
674
|
-
};
|
|
675
|
-
onUp = function () { dragNode = null; panning = false; last = null; };
|
|
676
|
-
window.addEventListener('mousemove', onMove);
|
|
677
|
-
window.addEventListener('mouseup', onUp);
|
|
678
|
-
stage.addEventListener('wheel', function (e) {
|
|
679
|
-
e.preventDefault();
|
|
680
|
-
var r = cv.getBoundingClientRect(), mx = e.clientX - r.left, my = e.clientY - r.top, w = S2W(mx, my);
|
|
681
|
-
var f = e.deltaY < 0 ? 1.12 : 0.89; scale = Math.max(0.3, Math.min(4, scale * f));
|
|
682
|
-
var ns = W2S(w[0], w[1]); ox += mx - ns[0]; oy += my - ns[1];
|
|
683
|
-
redraw();
|
|
684
|
-
}, { passive: false });
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
function setInspectorEmpty() {
|
|
688
|
-
var el = q('#odg-insp');
|
|
689
|
-
if (el) el.innerHTML = '<div class="inspector-empty"><div style="font-size:34px;margin-bottom:8px">◇</div>Click any node to inspect it.<br>Drag to reposition · scroll to zoom.</div>';
|
|
690
|
-
}
|
|
691
|
-
function setInspectorMsg(msg) {
|
|
692
|
-
var el = q('#odg-insp');
|
|
693
|
-
if (el) el.innerHTML = '<div class="inspector-empty"><div style="font-size:34px;margin-bottom:8px">◇</div>' + esc(msg) + '</div>';
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
/* drawLoading: paint a placeholder on the canvas while /api/graph is in-flight.
|
|
697
|
-
Prevents the blank-canvas flicker on tab switch (graph fetch takes ~200-800 ms). */
|
|
698
|
-
function drawLoading() {
|
|
699
|
-
if (!ctx) return;
|
|
700
|
-
ctx.clearRect(0, 0, W, H);
|
|
701
|
-
ctx.save();
|
|
702
|
-
ctx.fillStyle = PAL.fg2 || '#8a8a8a';
|
|
703
|
-
ctx.font = '13px system-ui, -apple-system, sans-serif';
|
|
704
|
-
ctx.textAlign = 'center';
|
|
705
|
-
ctx.textBaseline = 'middle';
|
|
706
|
-
ctx.fillText('Loading knowledge graph…', W / 2, H / 2);
|
|
707
|
-
ctx.restore();
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
function load() {
|
|
711
|
-
drawLoading(); /* paint immediately -- prevents blank-canvas flicker */
|
|
712
|
-
/* scale entity fetch with node budget so the entity tier stays representative */
|
|
713
|
-
var entityLimit = Math.max(40, Math.round(MAX_NODES * 0.5));
|
|
714
|
-
var url = GRAPH_URL + '?max_nodes=' + MAX_NODES;
|
|
715
|
-
var entityUrl = '/api/entity/list?limit=' + entityLimit;
|
|
716
|
-
Promise.all([
|
|
717
|
-
fetch(url).then(function (r) { if (!r.ok) throw new Error('graph ' + r.status); return r.json(); }),
|
|
718
|
-
fetch(entityUrl).then(function (r) { return r.ok ? r.json() : { entities: [] }; }).catch(function () { return { entities: [] }; })
|
|
719
|
-
]).then(function (res) {
|
|
720
|
-
buildGraph(res[0], res[1]);
|
|
721
|
-
if (!NODES.length) {
|
|
722
|
-
setInspectorMsg('No memories in this scope yet. Store something to grow the graph.');
|
|
723
|
-
running = false; draw(); updateCount(); updateLegend(); return;
|
|
724
|
-
}
|
|
725
|
-
readPalette(); resize(); updateCount(); updateLegend(); selected = null; setInspectorEmpty();
|
|
726
|
-
for (var i = 0; i < PRE_SETTLE_TICKS; i++) tick(); /* bounded pre-settle keeps navigation responsive */
|
|
727
|
-
fitFrames = 0; frames = 0;
|
|
728
|
-
if (!running) { running = true; loop(); } else { wake(); }
|
|
729
|
-
}).catch(function (err) {
|
|
730
|
-
setInspectorMsg('Could not load the graph (' + ((err && err.message) || 'error') + ').');
|
|
731
|
-
running = false;
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
function teardown() {
|
|
736
|
-
running = false;
|
|
737
|
-
if (raf) { cancelAnimationFrame(raf); raf = null; }
|
|
738
|
-
if (onMove) { window.removeEventListener('mousemove', onMove); onMove = null; }
|
|
739
|
-
if (onUp) { window.removeEventListener('mouseup', onUp); onUp = null; }
|
|
740
|
-
if (themeObs) { themeObs.disconnect(); themeObs = null; }
|
|
741
|
-
if (sizeObs) { sizeObs.disconnect(); sizeObs = null; }
|
|
742
|
-
window.removeEventListener('resize', onWinResize);
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
/* Legacy compatibility — js/knowledge-graph.js was retired in 4.0.6 and it
|
|
746
|
-
owned window.loadGraph (it assigned loadGraphSigma). Several live callers
|
|
747
|
-
still invoke it, and two of them do so WITHOUT a typeof guard:
|
|
748
|
-
core.js:552 loadGraph() on every page init
|
|
749
|
-
event-delegation.js:42 'load-graph' action
|
|
750
|
-
(core.js:498, od-shell.js:481 and ng-shell.js:345 are guarded and would
|
|
751
|
-
have degraded quietly.) Without this shim those two would throw
|
|
752
|
-
ReferenceError on first paint. Re-fetching when the pane is mounted is the
|
|
753
|
-
honest equivalent of what the old function did; when nothing is mounted the
|
|
754
|
-
pane renders on activation via odRenderGraph, so there is nothing to do. */
|
|
755
|
-
window.loadGraph = function () { if (mount) load(); };
|
|
756
|
-
|
|
757
|
-
/* ---------------- public entry ---------------- */
|
|
758
|
-
window.odRenderGraph = function (container) {
|
|
759
|
-
teardown(); /* re-render safe */
|
|
760
|
-
tierVisible = { 1: true, 2: true, 3: true }; /* reset toggles on each mount */
|
|
761
|
-
mount = container;
|
|
762
|
-
container.classList.add('graph-content');
|
|
763
|
-
container.style.padding = '0'; /* full-bleed hero */
|
|
764
|
-
container.innerHTML = scaffold();
|
|
765
|
-
readPalette();
|
|
766
|
-
wireControls();
|
|
767
|
-
resize();
|
|
768
|
-
/* Same hazard as the ResizeObserver above: resize() wipes the canvas, so a
|
|
769
|
-
bare `resize` listener leaves the graph blank after a window resize until
|
|
770
|
-
something else happens to repaint. Re-fit and wake instead. */
|
|
771
|
-
window.addEventListener('resize', onWinResize);
|
|
772
|
-
themeObs = new MutationObserver(readPalette);
|
|
773
|
-
themeObs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
|
|
774
|
-
load();
|
|
775
|
-
};
|
|
776
|
-
})();
|