superlocalmemory 3.7.8 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/ATTRIBUTION.md +1 -3
  3. package/CHANGELOG.md +129 -0
  4. package/README.md +205 -123
  5. package/package.json +12 -3
  6. package/plugin/.claude-plugin/plugin.json +2 -3
  7. package/plugin/CLAUDE.md +8 -8
  8. package/plugin/agents/slm-governance-advisor.md +80 -0
  9. package/plugin/agents/slm-loop-runner.md +71 -0
  10. package/plugin/agents/slm-memory-advisor.md +10 -5
  11. package/plugin/agents/slm-optimize-advisor.md +9 -3
  12. package/plugin/commands/slm-loop.md +31 -0
  13. package/plugin/hooks/hooks.json +79 -0
  14. package/plugin/requirements.txt +1 -1
  15. package/plugin/scripts/slm-launch +46 -7
  16. package/plugin/settings.json +9 -0
  17. package/plugin/skills/slm-cache/SKILL.md +9 -1
  18. package/plugin/skills/slm-compress/SKILL.md +8 -1
  19. package/plugin/skills/slm-governance/SKILL.md +248 -0
  20. package/plugin/skills/slm-graph/SKILL.md +17 -3
  21. package/plugin/skills/slm-loop/SKILL.md +99 -0
  22. package/plugin/skills/slm-mesh/SKILL.md +282 -0
  23. package/plugin/skills/slm-profile/SKILL.md +148 -0
  24. package/plugin/skills/slm-recall/SKILL.md +46 -10
  25. package/plugin/skills/slm-remember/SKILL.md +48 -1
  26. package/plugin/skills/slm-scope/SKILL.md +176 -0
  27. package/plugin/skills/slm-session/SKILL.md +24 -1
  28. package/plugin/skills/slm-status/SKILL.md +18 -1
  29. package/plugin-src/rules/AGENTS.md +57 -18
  30. package/plugin-src/skills/slm-cache/SKILL.md +9 -1
  31. package/plugin-src/skills/slm-compress/SKILL.md +8 -1
  32. package/plugin-src/skills/slm-graph/SKILL.md +17 -3
  33. package/plugin-src/skills/slm-recall/SKILL.md +46 -10
  34. package/plugin-src/skills/slm-remember/SKILL.md +48 -1
  35. package/plugin-src/skills/slm-session/SKILL.md +24 -1
  36. package/plugin-src/skills/slm-status/SKILL.md +18 -1
  37. package/pyproject.toml +2 -1
  38. package/scripts/postinstall/validation.js +2 -0
  39. package/scripts/postinstall-interactive.js +74 -2
  40. package/src/superlocalmemory/__init__.py +1 -1
  41. package/src/superlocalmemory/access/__init__.py +3 -0
  42. package/src/superlocalmemory/access/rbac.py +477 -0
  43. package/src/superlocalmemory/cli/commands.py +228 -17
  44. package/src/superlocalmemory/cli/compress_cmd.py +17 -7
  45. package/src/superlocalmemory/cli/daemon.py +7 -0
  46. package/src/superlocalmemory/cli/loop_cmd.py +187 -0
  47. package/src/superlocalmemory/cli/main.py +49 -8
  48. package/src/superlocalmemory/cli/mesh_cmd.py +38 -0
  49. package/src/superlocalmemory/cli/optimize_cmd.py +3 -0
  50. package/src/superlocalmemory/cli/pending_store.py +49 -13
  51. package/src/superlocalmemory/cli/proxy_cmd.py +4 -0
  52. package/src/superlocalmemory/cli/scale_engine_cmd.py +6 -0
  53. package/src/superlocalmemory/cli/setup_wizard.py +22 -13
  54. package/src/superlocalmemory/cli/version_banner.py +17 -3
  55. package/src/superlocalmemory/compliance/audit.py +6 -0
  56. package/src/superlocalmemory/compliance/gdpr.py +128 -138
  57. package/src/superlocalmemory/compliance/retention.py +176 -45
  58. package/src/superlocalmemory/core/backend_orchestrator.py +23 -59
  59. package/src/superlocalmemory/core/community_summary.py +267 -0
  60. package/src/superlocalmemory/core/config.py +216 -3
  61. package/src/superlocalmemory/core/consolidation_engine.py +95 -22
  62. package/src/superlocalmemory/core/context_cache.py +61 -18
  63. package/src/superlocalmemory/core/embedding_worker.py +21 -7
  64. package/src/superlocalmemory/core/embeddings.py +131 -46
  65. package/src/superlocalmemory/core/engine.py +41 -22
  66. package/src/superlocalmemory/core/engine_ingestion.py +359 -43
  67. package/src/superlocalmemory/core/engine_wiring.py +13 -0
  68. package/src/superlocalmemory/core/entity_community.py +178 -0
  69. package/src/superlocalmemory/core/graph_analyzer.py +39 -2
  70. package/src/superlocalmemory/core/graph_pruner.py +13 -8
  71. package/src/superlocalmemory/core/ingestion_command.py +134 -25
  72. package/src/superlocalmemory/core/injection.py +12 -7
  73. package/src/superlocalmemory/core/key_expander.py +138 -0
  74. package/src/superlocalmemory/core/maintenance.py +23 -0
  75. package/src/superlocalmemory/core/maintenance_scheduler.py +17 -7
  76. package/src/superlocalmemory/core/modes.py +1 -1
  77. package/src/superlocalmemory/core/mutations.py +2 -2
  78. package/src/superlocalmemory/core/pii.py +105 -0
  79. package/src/superlocalmemory/core/progressive_abstraction.py +208 -0
  80. package/src/superlocalmemory/core/recall_pipeline.py +7 -3
  81. package/src/superlocalmemory/core/recall_worker.py +20 -6
  82. package/src/superlocalmemory/core/scale_engine.py +60 -1
  83. package/src/superlocalmemory/core/security_primitives.py +40 -2
  84. package/src/superlocalmemory/core/store_pipeline.py +186 -29
  85. package/src/superlocalmemory/core/worker_pool.py +21 -6
  86. package/src/superlocalmemory/encoding/entity_reflexion.py +200 -0
  87. package/src/superlocalmemory/encoding/entity_resolver.py +34 -24
  88. package/src/superlocalmemory/encoding/fact_extractor.py +26 -1
  89. package/src/superlocalmemory/encoding/temporal_validator.py +64 -1
  90. package/src/superlocalmemory/evolution/evolution_store.py +122 -45
  91. package/src/superlocalmemory/evolution/llm_dispatch.py +12 -1
  92. package/src/superlocalmemory/evolution/model_selection.py +160 -0
  93. package/src/superlocalmemory/evolution/mutation_generator.py +16 -0
  94. package/src/superlocalmemory/evolution/skill_evolver.py +127 -42
  95. package/src/superlocalmemory/evolution/triggers.py +22 -13
  96. package/src/superlocalmemory/graph/cozo_backend.py +43 -20
  97. package/src/superlocalmemory/hooks/adapter_base.py +5 -1
  98. package/src/superlocalmemory/hooks/auto_recall.py +13 -1
  99. package/src/superlocalmemory/hooks/claude_code_hooks.py +11 -0
  100. package/src/superlocalmemory/hooks/codex_assets.py +64 -5
  101. package/src/superlocalmemory/hooks/hook_daemon.py +20 -3
  102. package/src/superlocalmemory/hooks/hook_handlers.py +6 -1
  103. package/src/superlocalmemory/hooks/memory_protocol.py +54 -0
  104. package/src/superlocalmemory/hooks/portable_kit.py +148 -3
  105. package/src/superlocalmemory/infra/backup.py +12 -1
  106. package/src/superlocalmemory/infra/daemon_identity.py +40 -4
  107. package/src/superlocalmemory/infra/data_root.py +43 -4
  108. package/src/superlocalmemory/infra/event_bus.py +107 -24
  109. package/src/superlocalmemory/infra/rate_limiter.py +93 -0
  110. package/src/superlocalmemory/ingestion/adapter_manager.py +4 -1
  111. package/src/superlocalmemory/ingestion/credentials.py +1 -1
  112. package/src/superlocalmemory/learning/cross_project.py +28 -19
  113. package/src/superlocalmemory/learning/model_rollback.py +3 -0
  114. package/src/superlocalmemory/learning/ranker_retrain_online.py +2 -0
  115. package/src/superlocalmemory/learning/reward.py +50 -0
  116. package/src/superlocalmemory/learning/reward_proxy.py +42 -9
  117. package/src/superlocalmemory/learning/source_quality.py +523 -1
  118. package/src/superlocalmemory/loops/__init__.py +56 -0
  119. package/src/superlocalmemory/loops/budget.py +58 -0
  120. package/src/superlocalmemory/loops/engine.py +164 -0
  121. package/src/superlocalmemory/loops/ledger.py +263 -0
  122. package/src/superlocalmemory/loops/models.py +152 -0
  123. package/src/superlocalmemory/loops/rules.py +52 -0
  124. package/src/superlocalmemory/mcp/_daemon_proxy.py +3 -0
  125. package/src/superlocalmemory/mcp/_pool_adapter.py +2 -0
  126. package/src/superlocalmemory/mcp/profiles.py +103 -0
  127. package/src/superlocalmemory/mcp/server.py +32 -79
  128. package/src/superlocalmemory/mcp/tools_active.py +4 -7
  129. package/src/superlocalmemory/mcp/tools_code_graph.py +51 -5
  130. package/src/superlocalmemory/mcp/tools_core.py +12 -4
  131. package/src/superlocalmemory/mcp/tools_evolution.py +6 -3
  132. package/src/superlocalmemory/mcp/tools_learning.py +2 -2
  133. package/src/superlocalmemory/mcp/tools_loops.py +300 -0
  134. package/src/superlocalmemory/mcp/tools_mesh.py +140 -4
  135. package/src/superlocalmemory/mcp/tools_optimize.py +15 -8
  136. package/src/superlocalmemory/mesh/broker.py +237 -129
  137. package/src/superlocalmemory/mesh/remote_sync.py +50 -8
  138. package/src/superlocalmemory/optimize/NOTICE +1 -6
  139. package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +1 -4
  140. package/src/superlocalmemory/optimize/adapters/openai_adapter.py +1 -4
  141. package/src/superlocalmemory/optimize/cache/semantic.py +27 -19
  142. package/src/superlocalmemory/optimize/compress/align.py +32 -26
  143. package/src/superlocalmemory/optimize/compress/ccr.py +14 -71
  144. package/src/superlocalmemory/optimize/compress/router.py +105 -22
  145. package/src/superlocalmemory/optimize/config/defaults.py +1 -1
  146. package/src/superlocalmemory/optimize/config/schema.py +87 -4
  147. package/src/superlocalmemory/optimize/metrics/counters.py +13 -4
  148. package/src/superlocalmemory/optimize/metrics/estimator.py +0 -3
  149. package/src/superlocalmemory/optimize/proxy/_helpers.py +31 -4
  150. package/src/superlocalmemory/optimize/storage/db.py +38 -9
  151. package/src/superlocalmemory/optimize/storage/schema.py +10 -0
  152. package/src/superlocalmemory/parameterization/pattern_extractor.py +6 -3
  153. package/src/superlocalmemory/retrieval/agentic.py +1 -1
  154. package/src/superlocalmemory/retrieval/bm25_channel.py +68 -10
  155. package/src/superlocalmemory/retrieval/engine.py +221 -47
  156. package/src/superlocalmemory/retrieval/entity_channel.py +7 -5
  157. package/src/superlocalmemory/retrieval/hopfield_channel.py +9 -2
  158. package/src/superlocalmemory/retrieval/reranker.py +3 -4
  159. package/src/superlocalmemory/retrieval/semantic_channel.py +114 -21
  160. package/src/superlocalmemory/retrieval/spreading_activation.py +11 -2
  161. package/src/superlocalmemory/retrieval/temporal_channel.py +48 -9
  162. package/src/superlocalmemory/retrieval/temporal_frame.py +102 -0
  163. package/src/superlocalmemory/retrieval/temporal_validity_filter.py +135 -0
  164. package/src/superlocalmemory/retrieval/time_window.py +181 -0
  165. package/src/superlocalmemory/server/api.py +4 -4
  166. package/src/superlocalmemory/server/config_file.py +90 -0
  167. package/src/superlocalmemory/server/origin.py +50 -0
  168. package/src/superlocalmemory/server/profile_runtime.py +125 -8
  169. package/src/superlocalmemory/server/rbac_enforce.py +142 -0
  170. package/src/superlocalmemory/server/recall_health.py +24 -3
  171. package/src/superlocalmemory/server/recall_serializer.py +19 -1
  172. package/src/superlocalmemory/server/routes/abstraction.py +115 -0
  173. package/src/superlocalmemory/server/routes/agents.py +128 -38
  174. package/src/superlocalmemory/server/routes/backup.py +317 -70
  175. package/src/superlocalmemory/server/routes/behavioral.py +349 -71
  176. package/src/superlocalmemory/server/routes/brain.py +69 -12
  177. package/src/superlocalmemory/server/routes/chat.py +10 -5
  178. package/src/superlocalmemory/server/routes/compliance.py +171 -21
  179. package/src/superlocalmemory/server/routes/config_api.py +438 -0
  180. package/src/superlocalmemory/server/routes/data_io.py +30 -8
  181. package/src/superlocalmemory/server/routes/entity.py +108 -26
  182. package/src/superlocalmemory/server/routes/events.py +24 -8
  183. package/src/superlocalmemory/server/routes/evolution.py +189 -68
  184. package/src/superlocalmemory/server/routes/helpers.py +16 -1
  185. package/src/superlocalmemory/server/routes/ingest.py +7 -4
  186. package/src/superlocalmemory/server/routes/insights.py +3 -3
  187. package/src/superlocalmemory/server/routes/learning.py +289 -118
  188. package/src/superlocalmemory/server/routes/learning_telemetry.py +153 -0
  189. package/src/superlocalmemory/server/routes/lifecycle.py +59 -8
  190. package/src/superlocalmemory/server/routes/memories.py +182 -57
  191. package/src/superlocalmemory/server/routes/mesh.py +200 -31
  192. package/src/superlocalmemory/server/routes/optimize.py +33 -1
  193. package/src/superlocalmemory/server/routes/prewarm.py +2 -0
  194. package/src/superlocalmemory/server/routes/profiles.py +63 -17
  195. package/src/superlocalmemory/server/routes/ratelimit.py +132 -0
  196. package/src/superlocalmemory/server/routes/rbac.py +367 -0
  197. package/src/superlocalmemory/server/routes/stats.py +103 -158
  198. package/src/superlocalmemory/server/routes/tiers.py +11 -9
  199. package/src/superlocalmemory/server/routes/token.py +3 -13
  200. package/src/superlocalmemory/server/routes/v3_api.py +247 -89
  201. package/src/superlocalmemory/server/routes/ws.py +5 -2
  202. package/src/superlocalmemory/server/security_middleware.py +12 -5
  203. package/src/superlocalmemory/server/ui.py +20 -5
  204. package/src/superlocalmemory/server/unified_daemon.py +827 -72
  205. package/src/superlocalmemory/server/write_identity.py +38 -8
  206. package/src/superlocalmemory/storage/database.py +265 -53
  207. package/src/superlocalmemory/storage/migration_runner.py +132 -1
  208. package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +5 -0
  209. package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +108 -0
  210. package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +86 -0
  211. package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +194 -0
  212. package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +87 -0
  213. package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +90 -0
  214. package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +136 -0
  215. package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +163 -0
  216. package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +270 -0
  217. package/src/superlocalmemory/storage/migrations/M029_behavioral_history_indexes.py +137 -0
  218. package/src/superlocalmemory/storage/migrations/M030_entity_explorer_indexes.py +93 -0
  219. package/src/superlocalmemory/storage/migrations/__init__.py +4 -0
  220. package/src/superlocalmemory/storage/models.py +4 -0
  221. package/src/superlocalmemory/storage/schema.py +136 -1
  222. package/src/superlocalmemory/storage/schema_v32.py +2 -0
  223. package/src/superlocalmemory/storage/schema_v343.py +24 -12
  224. package/src/superlocalmemory/storage/schema_v347.py +4 -0
  225. package/src/superlocalmemory/trust/gate.py +49 -8
  226. package/src/superlocalmemory/ui/assets/slm-icon-white.svg +64 -0
  227. package/src/superlocalmemory/ui/assets/slm-icon.svg +36 -0
  228. package/src/superlocalmemory/ui/css/design-system.css +621 -0
  229. package/src/superlocalmemory/ui/css/neural-glass.css +6 -0
  230. package/src/superlocalmemory/ui/css/od-bridge.css +158 -0
  231. package/src/superlocalmemory/ui/favicon.svg +35 -4
  232. package/src/superlocalmemory/ui/index.html +303 -173
  233. package/src/superlocalmemory/ui/js/brain.js +5 -20
  234. package/src/superlocalmemory/ui/js/core.js +100 -41
  235. package/src/superlocalmemory/ui/js/dashboard.js +403 -65
  236. package/src/superlocalmemory/ui/js/event-delegation.js +102 -0
  237. package/src/superlocalmemory/ui/js/knowledge-graph.js +11 -11
  238. package/src/superlocalmemory/ui/js/math-health.js +1 -1
  239. package/src/superlocalmemory/ui/js/memories.js +15 -4
  240. package/src/superlocalmemory/ui/js/memory-chat.js +7 -7
  241. package/src/superlocalmemory/ui/js/ng-entities.js +6 -8
  242. package/src/superlocalmemory/ui/js/ng-ingestion.js +4 -4
  243. package/src/superlocalmemory/ui/js/ng-mesh.js +4 -9
  244. package/src/superlocalmemory/ui/js/ng-shell.js +8 -8
  245. package/src/superlocalmemory/ui/js/ng-skills.js +54 -2
  246. package/src/superlocalmemory/ui/js/od-agents.js +544 -0
  247. package/src/superlocalmemory/ui/js/od-auth-gate.js +257 -0
  248. package/src/superlocalmemory/ui/js/od-backup.js +871 -0
  249. package/src/superlocalmemory/ui/js/od-brain.js +816 -0
  250. package/src/superlocalmemory/ui/js/od-entities.js +579 -0
  251. package/src/superlocalmemory/ui/js/od-graph.js +600 -0
  252. package/src/superlocalmemory/ui/js/od-health.js +539 -0
  253. package/src/superlocalmemory/ui/js/od-mcp.js +508 -0
  254. package/src/superlocalmemory/ui/js/od-memories.js +929 -0
  255. package/src/superlocalmemory/ui/js/od-mesh.js +553 -0
  256. package/src/superlocalmemory/ui/js/od-operations.js +1250 -0
  257. package/src/superlocalmemory/ui/js/od-optimize.js +787 -0
  258. package/src/superlocalmemory/ui/js/od-settings.js +1107 -0
  259. package/src/superlocalmemory/ui/js/od-shell.js +809 -0
  260. package/src/superlocalmemory/ui/js/od-skills.js +600 -0
  261. package/src/superlocalmemory/ui/js/od-team.js +258 -0
  262. package/src/superlocalmemory/ui/js/profiles.js +159 -46
  263. package/src/superlocalmemory/ui/js/settings.js +17 -3
  264. package/src/superlocalmemory/ui/js/timeline.js +34 -5
  265. package/src/superlocalmemory/ui/js/trust-dashboard.js +2 -2
  266. package/src/superlocalmemory/vector/lancedb_backend.py +8 -6
  267. package/plugin-src/.mcp.json +0 -12
  268. package/plugin-src/agents/slm-memory-advisor.md +0 -44
  269. package/plugin-src/agents/slm-optimize-advisor.md +0 -38
  270. package/plugin-src/hooks/.gitkeep +0 -0
  271. package/plugin-src/hooks/hooks.json +0 -23
  272. package/plugin-src/manifest.json +0 -25
  273. package/plugin-src/requirements.txt +0 -1
  274. package/plugin-src/rules/CLAUDE.md.fragment +0 -44
  275. package/plugin-src/scripts/ensure-venv.bat +0 -122
  276. package/plugin-src/scripts/ensure-venv.sh +0 -105
  277. package/plugin-src/scripts/slm-launch +0 -23
  278. package/plugin-src/scripts/slm-launch.bat +0 -23
  279. package/plugin-src/settings.json +0 -16
  280. package/src/superlocalmemory/learning/behavioral_listener.py +0 -94
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en" data-bs-theme="dark">
2
+ <html lang="en" data-bs-theme="dark" data-theme="dark">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -23,12 +23,42 @@
23
23
 
24
24
  <!-- Legacy dashboard styles (v3.4.21 — extracted to external file, no rule changes) -->
25
25
  <link rel="stylesheet" href="static/css/legacy-dashboard.css?v=34422">
26
+ <!-- Open Design System v1.0 (app chrome, KPI strip, cards, sidebar, theme tokens) -->
27
+ <link rel="stylesheet" href="static/css/design-system.css">
28
+ <!-- OD-Bootstrap bridge: tab-pane visibility, mobile sidebar, responsive shims -->
29
+ <link rel="stylesheet" href="static/css/od-bridge.css">
26
30
  </head>
27
- <body style="background: #0a0e1a;">
28
- <!-- Pre-mount: elements ng-shell.js relocates into the sidebar + footer.
29
- Hidden on initial paint so there's no flash of the old Bootstrap
30
- navbar. ng-shell moves these into their final homes on mount. -->
31
- <div id="ng-premount" style="display: none;">
31
+ <body>
32
+
33
+ <!-- OD chrome v1.0 CSP-safe, single-page tab model -->
34
+ <div class="scrim" id="scrim"></div>
35
+ <div class="app">
36
+ <aside class="sidebar" id="sidebar"></aside>
37
+ <div class="main">
38
+ <header class="topbar">
39
+ <button class="btn icon ghost menu-btn" id="menuBtn" aria-label="Open menu">
40
+ <i class="bi bi-list" aria-hidden="true"></i>
41
+ </button>
42
+ <div>
43
+ <div class="crumb" id="topbar-crumb">Overview</div>
44
+ <h1 id="topbar-heading">Dashboard</h1>
45
+ </div>
46
+ <div class="spacer"></div>
47
+ <label class="search" for="q" style="display:none">
48
+ <i class="bi bi-search" aria-hidden="true"></i>
49
+ <input id="q" placeholder="Search memories…">
50
+ <span class="kbd">⌘K</span>
51
+ </label>
52
+ <span class="badge-local" title="All data stays on this machine. Nothing leaves your device.">
53
+ <i class="bi bi-lock-fill" aria-hidden="true"></i> LOCAL ONLY
54
+ </span>
55
+ <button class="btn icon ghost" data-theme-icon aria-label="Toggle theme"></button>
56
+ </header>
57
+ <main class="content" id="main-content">
58
+
59
+ <!-- Hidden ng-premount: profile-select + mode-badge moved here;
60
+ od-shell.js will relocate them into #od-profile-container in the sidebar. -->
61
+ <div id="ng-premount" style="display: none;" aria-hidden="true">
32
62
  <select class="form-select form-select-sm profile-select" id="profile-select" title="Switch profile">
33
63
  <option value="default">default</option>
34
64
  </select>
@@ -36,15 +66,13 @@
36
66
  <i class="bi bi-plus-lg"></i>
37
67
  </button>
38
68
  <span id="mode-badge" class="badge">...</span>
39
- <button class="btn btn-sm theme-toggle" id="refresh-dashboard-btn" onclick="refreshDashboard()" title="Refresh Dashboard" style="padding:4px 8px;">
69
+ <button class="btn btn-sm theme-toggle" id="refresh-dashboard-btn" data-act-click="refresh-dashboard" title="Refresh Dashboard" style="padding:4px 8px;">
40
70
  <i class="bi bi-arrow-clockwise" aria-hidden="true"></i>
41
71
  </button>
42
- <button class="theme-toggle" id="theme-toggle" onclick="toggleDarkMode()" aria-label="Toggle dark mode">
72
+ <button class="theme-toggle" id="theme-toggle" data-act-click="toggle-dark-mode" aria-label="Toggle dark mode">
43
73
  <i class="bi bi-sun-fill" id="theme-icon" aria-hidden="true"></i>
44
74
  </button>
45
75
  </div>
46
-
47
- <div class="container-fluid">
48
76
  <!-- Stats Overview — hidden until ng-shell.js relocates this block
49
77
  into the Dashboard pane. Prevents the flash of pre-glass stat
50
78
  cards at the top of the page on initial load (v3.4.21 FOUC fix). -->
@@ -109,102 +137,186 @@
109
137
  <li class="nav-item"><button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings-pane" type="button"></button></li>
110
138
  </ul>
111
139
 
112
- <!-- Privacy Notice & Feedback Progress (v2.7.4) -->
113
- <div id="privacy-notice"></div>
114
- <div id="feedback-progress" class="mb-3"></div>
140
+ <!-- Legacy privacy/learning banner removed in 3.7.9 OD redesign:
141
+ the Brain screen now shows learning progress in-context, and this
142
+ persistent strip leaked onto every pane. feedback.js null-guards
143
+ these ids, so removing the containers is a safe no-op there. -->
115
144
 
116
145
  <div class="tab-content">
117
146
  <!-- Graph Visualization -->
118
147
  <!-- V3 Dashboard -->
148
+ <!-- Dashboard — OD design v1.0 wired to real API endpoints.
149
+ KPI values come from GET /api/stats (loadDashboardStats in dashboard.js).
150
+ System card comes from GET /api/v3/dashboard (loadDashboard in dashboard.js).
151
+ Activity feed comes from GET /api/memories?limit=6 (loadDashboardFeed).
152
+ No hardcoded numbers — honest loading/empty states only. -->
119
153
  <div class="tab-pane fade show active" id="dashboard-pane">
120
- <div class="row g-3 mb-4">
121
- <!-- Mode Card -->
122
- <div class="col-md-4">
123
- <div class="card stat-card h-100">
124
- <div class="card-body">
125
- <div class="d-flex justify-content-between align-items-center mb-3">
126
- <h6 class="card-subtitle text-muted">Operating Mode</h6>
127
- <i class="bi bi-shield-check stat-icon text-primary"></i>
128
- </div>
129
- <h3 id="dashboard-mode" class="stat-value">Loading...</h3>
130
- <p id="dashboard-mode-desc" class="text-muted small mb-2">Connecting...</p>
131
- <div class="btn-group btn-group-sm" role="group">
132
- <button class="btn btn-outline-primary mode-btn" data-mode="a">A</button>
133
- <button class="btn btn-outline-primary mode-btn" data-mode="b">B</button>
134
- <button class="btn btn-outline-primary mode-btn" data-mode="c">C</button>
135
- </div>
136
- </div>
137
- </div>
138
- </div>
139
- <!-- Stats Card -->
140
- <div class="col-md-4">
141
- <div class="card stat-card h-100">
142
- <div class="card-body">
143
- <div class="d-flex justify-content-between align-items-center mb-3">
144
- <h6 class="card-subtitle text-muted">Memories</h6>
145
- <i class="bi bi-database stat-icon text-success"></i>
146
- </div>
147
- <h3 id="dashboard-memory-count" class="stat-value">0</h3>
148
- <p class="text-muted small mb-0">facts stored</p>
149
- </div>
150
- </div>
151
- </div>
152
- <!-- Provider Card -->
153
- <div class="col-md-4">
154
- <div class="card stat-card h-100">
155
- <div class="card-body">
156
- <div class="d-flex justify-content-between align-items-center mb-3">
157
- <h6 class="card-subtitle text-muted">LLM Provider</h6>
158
- <i class="bi bi-cloud stat-icon text-info"></i>
159
- </div>
160
- <h3 id="dashboard-provider" class="stat-value">Loading...</h3>
161
- <p id="dashboard-model" class="text-muted small mb-0"></p>
162
- </div>
163
- </div>
164
- </div>
154
+
155
+ <div class="page-head">
156
+ <h2>Your memory, at a glance</h2>
157
+ <p id="od-dash-subtitle" class="muted">Connecting to daemon...</p>
158
+ </div>
159
+
160
+ <!-- KPI strip — 4 cards, values populated by loadDashboardStats() -->
161
+ <section class="kpi-strip" style="margin-bottom:16px">
162
+ <div class="card kpi">
163
+ <div class="label"><i class="bi bi-journal-text" aria-hidden="true"></i> Total Memories</div>
164
+ <div class="value num" id="k-mem">—</div>
165
+ <div class="delta" id="k-mem-delta">&nbsp;</div>
166
+ <div class="spark" id="sp-mem"></div>
165
167
  </div>
166
- <!-- Quick Actions -->
167
- <div class="row g-3 mb-4">
168
- <div class="col-md-6">
169
- <div class="card">
170
- <div class="card-body">
171
- <h6><i class="bi bi-plus-circle"></i> Quick Store</h6>
172
- <div class="input-group">
173
- <input type="text" id="quick-store-input" class="form-control" placeholder="Type something to remember...">
174
- <button class="btn btn-primary" id="quick-store-btn">Store</button>
175
- </div>
176
- </div>
168
+ <div class="card kpi">
169
+ <div class="label"><i class="bi bi-diagram-2" aria-hidden="true"></i> Graph Nodes</div>
170
+ <div class="value num" id="k-nodes">—</div>
171
+ <div class="delta" id="k-nodes-delta">&nbsp;</div>
172
+ <div class="spark" id="sp-nodes"></div>
173
+ </div>
174
+ <div class="card kpi">
175
+ <div class="label"><i class="bi bi-arrows-angle-expand" aria-hidden="true"></i> Connections</div>
176
+ <div class="value num" id="k-edges">—</div>
177
+ <div class="delta" id="k-edges-delta">&nbsp;</div>
178
+ <div class="spark" id="sp-edges"></div>
179
+ </div>
180
+ <div class="card kpi">
181
+ <div class="label"><i class="bi bi-lightning-charge" aria-hidden="true"></i> Clusters</div>
182
+ <div class="value num" id="k-clu">—</div>
183
+ <div class="delta" id="k-clu-delta">&nbsp;</div>
184
+ <div class="spark" id="sp-clu"></div>
185
+ </div>
186
+ </section>
187
+
188
+ <!-- main grid: memory-growth card + system card -->
189
+ <div class="grid" style="grid-template-columns:1.6fr 1fr;align-items:start">
190
+
191
+ <!-- memory growth + quick actions -->
192
+ <div class="card">
193
+ <div class="card-head">
194
+ <h3>Memory activity</h3>
195
+ <span class="sub">facts added by day · past year</span>
196
+ <div class="spacer"></div>
197
+ </div>
198
+ <div class="card-pad">
199
+ <div id="sp-big"></div>
200
+ <div style="display:flex;gap:26px;margin-top:16px;flex-wrap:wrap">
201
+ <div>
202
+ <div class="muted" style="font-size:12px">Avg / day</div>
203
+ <div class="num" id="k-avg-day" style="font-size:19px;font-weight:650">—</div>
204
+ </div>
205
+ <div>
206
+ <div class="muted" style="font-size:12px">Total facts</div>
207
+ <div class="num" id="k-facts" style="font-size:19px;font-weight:650">—</div>
208
+ </div>
209
+ </div>
210
+ <!-- Quick store / recall -->
211
+ <div style="margin-top:20px;display:flex;flex-direction:column;gap:10px">
212
+ <div>
213
+ <div class="muted" style="font-size:12px;margin-bottom:4px">Quick store</div>
214
+ <div class="input-group input-group-sm" style="max-width:320px">
215
+ <input type="text" id="quick-store-input" class="form-control" placeholder="Type something to remember...">
216
+ <button class="btn btn-primary btn-sm" id="quick-store-btn">Store</button>
177
217
  </div>
178
- </div>
179
- <div class="col-md-6">
180
- <div class="card">
181
- <div class="card-body">
182
- <h6><i class="bi bi-search"></i> Quick Recall</h6>
183
- <div class="input-group">
184
- <input type="text" id="quick-recall-input" class="form-control" placeholder="Search your memories...">
185
- <button class="btn btn-success" id="quick-recall-btn">Recall</button>
186
- </div>
187
- <div id="quick-recall-results" class="mt-2 small"></div>
188
- </div>
218
+ </div>
219
+ <div>
220
+ <div class="muted" style="font-size:12px;margin-bottom:4px">Quick recall</div>
221
+ <div class="input-group input-group-sm" style="max-width:320px">
222
+ <input type="text" id="quick-recall-input" class="form-control" placeholder="Search your memories...">
223
+ <button class="btn btn-success btn-sm" id="quick-recall-btn">Recall</button>
189
224
  </div>
225
+ <div id="quick-recall-results" class="mt-1 small"></div>
226
+ </div>
190
227
  </div>
228
+ </div>
191
229
  </div>
192
- <!-- System Info -->
193
- <div class="row g-3">
194
- <div class="col-md-12">
195
- <div class="card">
196
- <div class="card-body">
197
- <h6><i class="bi bi-info-circle"></i> System</h6>
198
- <div class="row text-muted small">
199
- <div class="col-md-3">Version: <strong id="dashboard-version">...</strong></div>
200
- <div class="col-md-3">Profile: <strong id="dashboard-profile">default</strong></div>
201
- <div class="col-md-3">Base: <strong id="dashboard-basedir">~/.superlocalmemory</strong></div>
202
- <div class="col-md-3">Math Layers: <strong class="text-success">Active</strong></div>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
230
+
231
+ <!-- system health snapshot — wired to GET /api/v3/dashboard -->
232
+ <div class="card">
233
+ <div class="card-head">
234
+ <h3>System</h3>
235
+ <div class="spacer"></div>
236
+ <span class="badge ok" id="od-sys-badge"><span class="dot"></span> Healthy</span>
237
+ </div>
238
+ <div class="card-pad" style="display:flex;flex-direction:column;gap:2px">
239
+ <div class="list-row">
240
+ <span class="muted" style="width:120px">Mode</span>
241
+ <b id="dashboard-mode">...</b>
242
+ </div>
243
+ <div class="list-row">
244
+ <span class="muted" style="width:120px">Description</span>
245
+ <span class="mono" id="dashboard-mode-desc">...</span>
246
+ </div>
247
+ <div class="list-row">
248
+ <span class="muted" style="width:120px">LLM Provider</span>
249
+ <span class="mono" id="dashboard-provider">...</span>
250
+ </div>
251
+ <div class="list-row">
252
+ <span class="muted" style="width:120px">Model</span>
253
+ <span class="mono" id="dashboard-model">...</span>
254
+ </div>
255
+ <div class="list-row">
256
+ <span class="muted" style="width:120px">Math Layers</span>
257
+ <span class="badge cyan">Scoring · Consistency · Lifecycle</span>
258
+ </div>
259
+ <div class="list-row">
260
+ <span class="muted" style="width:120px">Base dir</span>
261
+ <span class="mono" id="dashboard-basedir">~/.superlocalmemory</span>
262
+ </div>
263
+ <div class="list-row">
264
+ <span class="muted" style="width:120px">Profile</span>
265
+ <span class="mono" id="dashboard-profile">default</span>
266
+ </div>
267
+ <div class="list-row">
268
+ <span class="muted" style="width:120px">Version</span>
269
+ <span class="mono" id="dashboard-version">...</span>
270
+ </div>
271
+ <div class="list-row" style="margin-top:8px">
272
+ <span class="muted" style="width:120px">Switch mode</span>
273
+ <div class="btn-group btn-group-sm" role="group">
274
+ <button class="btn btn-outline-primary mode-btn btn-sm" data-mode="a">A</button>
275
+ <button class="btn btn-outline-primary mode-btn btn-sm" data-mode="b">B</button>
276
+ <button class="btn btn-outline-primary mode-btn btn-sm" data-mode="c">C</button>
277
+ </div>
278
+ </div>
279
+ </div>
280
+ </div>
281
+ </div>
282
+
283
+ <!-- recent activity + capture sources -->
284
+ <div class="grid" style="grid-template-columns:1.6fr 1fr;align-items:start;margin-top:16px">
285
+ <div class="card">
286
+ <div class="card-head">
287
+ <h3>Recent activity</h3>
288
+ <span class="sub">live memory stream</span>
289
+ <div class="spacer"></div>
290
+ <span class="badge neutral" style="border-radius:99px">
291
+ <span class="dot" style="background:var(--ok)"></span> live
292
+ </span>
293
+ </div>
294
+ <!-- populated by loadDashboardFeed() in dashboard.js via GET /api/memories?limit=6 -->
295
+ <div class="card-pad" id="feed">
296
+ <div class="muted" style="padding:16px;text-align:center;font-size:13px">Loading activity...</div>
297
+ </div>
207
298
  </div>
299
+ <div class="card">
300
+ <div class="card-head"><h3>Where memories come from</h3></div>
301
+ <div class="card-pad">
302
+ <!-- populated by loadDashboardSources() from profile-scoped provenance -->
303
+ <div id="src">
304
+ <div class="muted" style="padding:16px;text-align:center;font-size:13px">Loading...</div>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ </div>
309
+
310
+ <!-- Hidden compat IDs: dashboard-memory-count is referenced by loadDashboard().
311
+ stat-memories, stat-facts, stat-nodes, stat-edges are NOT here —
312
+ they live in #stats-container (above tab-content) to avoid duplicate IDs.
313
+ core.js loadStats() writes to those IDs in stats-container.
314
+ loadDashboardStats() calls /api/stats independently and writes to #k-mem etc. -->
315
+ <div style="display:none" aria-hidden="true" id="legacy-compat-ids">
316
+ <!-- dashboard-memory-count: unique ID (old dashboard pane was replaced) -->
317
+ <span id="dashboard-memory-count">0</span>
318
+ </div>
319
+
208
320
  </div>
209
321
 
210
322
  <!-- Graph Visualization -->
@@ -217,10 +329,10 @@
217
329
  <div id="graph-stats" class="mt-2"></div>
218
330
  </div>
219
331
  <div class="col-md-4 text-end">
220
- <button class="btn btn-sm btn-outline-primary" onclick="loadGraph()" aria-label="Refresh graph data">
332
+ <button class="btn btn-sm btn-outline-primary" data-act-click="load-graph" aria-label="Refresh graph data">
221
333
  <i class="bi bi-arrow-clockwise"></i> Refresh
222
334
  </button>
223
- <select class="form-select form-select-sm d-inline-block w-auto" id="graph-max-nodes" onchange="loadGraph()" aria-label="Select maximum number of nodes to display">
335
+ <select class="form-select form-select-sm d-inline-block w-auto" id="graph-max-nodes" data-act-change="load-graph" aria-label="Select maximum number of nodes to display">
224
336
  <option value="50">50 nodes</option>
225
337
  <option value="100">100 nodes</option>
226
338
  <option value="200" selected>200 nodes</option>
@@ -245,16 +357,16 @@
245
357
  <span class="input-group-text"><i class="bi bi-search"></i></span>
246
358
  <input type="text" class="form-control" id="sigma-search-input"
247
359
  placeholder="Search memories in graph..." aria-label="Search graph nodes"
248
- oninput="sigmaSearch(this.value)">
360
+ data-act-input="sigma-search">
249
361
  <button class="btn btn-outline-secondary" type="button"
250
- onclick="sigmaClearSearch(); document.getElementById('sigma-search-input').value='';">
362
+ data-act-click="sigma-clear-search">
251
363
  <i class="bi bi-x-lg"></i>
252
364
  </button>
253
365
  </div>
254
366
  <div class="btn-group btn-group-sm">
255
- <button class="btn btn-outline-secondary" onclick="sigmaZoomIn()" title="Zoom In"><i class="bi bi-zoom-in"></i></button>
256
- <button class="btn btn-outline-secondary" onclick="sigmaZoomOut()" title="Zoom Out"><i class="bi bi-zoom-out"></i></button>
257
- <button class="btn btn-outline-secondary" onclick="sigmaResetView()" title="Reset View"><i class="bi bi-arrows-angle-expand"></i></button>
367
+ <button class="btn btn-outline-secondary" data-act-click="sigma-zoom-in" title="Zoom In"><i class="bi bi-zoom-in"></i></button>
368
+ <button class="btn btn-outline-secondary" data-act-click="sigma-zoom-out" title="Zoom Out"><i class="bi bi-zoom-out"></i></button>
369
+ <button class="btn btn-outline-secondary" data-act-click="sigma-reset-view" title="Reset View"><i class="bi bi-arrows-angle-expand"></i></button>
258
370
  </div>
259
371
  </div>
260
372
  </div>
@@ -273,20 +385,20 @@
273
385
  <h6 class="mb-2 d-flex justify-content-between align-items-center">
274
386
  <span><i class="bi bi-collection"></i> Communities</span>
275
387
  <div class="btn-group btn-group-sm" role="group" aria-label="Community source">
276
- <input type="radio" class="btn-check" name="community-source" id="community-live" checked onchange="handleCommunitySourceToggle('live')">
388
+ <input type="radio" class="btn-check" name="community-source" id="community-live" checked data-act-change="community-source" data-source="live">
277
389
  <label class="btn btn-outline-secondary py-0 px-1" style="font-size:0.65rem;" for="community-live">Live</label>
278
- <input type="radio" class="btn-check" name="community-source" id="community-backend" onchange="handleCommunitySourceToggle('backend')">
390
+ <input type="radio" class="btn-check" name="community-source" id="community-backend" data-act-change="community-source" data-source="backend">
279
391
  <label class="btn btn-outline-secondary py-0 px-1" style="font-size:0.65rem;" for="community-backend">Backend</label>
280
392
  </div>
281
393
  </h6>
282
394
  <div class="mb-1" id="community-resolution-container">
283
395
  <label class="form-label small mb-0">Resolution <span id="community-resolution-value" class="text-muted">1.0</span></label>
284
396
  <input type="range" class="form-range" id="community-resolution" min="0.1" max="3.0" step="0.1" value="1.0"
285
- oninput="handleResolutionChange(this.value)">
397
+ data-act-input="handle-resolution-change">
286
398
  </div>
287
399
  <div id="community-list-panel">
288
400
  <div class="text-muted small">No communities detected yet.</div>
289
- <button class="btn btn-sm btn-outline-primary w-100 mt-1" onclick="runCommunityDetection()">
401
+ <button class="btn btn-sm btn-outline-primary w-100 mt-1" data-act-click="run-community-detection">
290
402
  <i class="bi bi-cpu"></i> Detect
291
403
  </button>
292
404
  </div>
@@ -298,7 +410,7 @@
298
410
  <hr class="my-2">
299
411
  <h6 class="mb-2"><i class="bi bi-funnel"></i> Filter</h6>
300
412
  <select class="form-select form-select-sm mb-1" id="sigma-category-filter"
301
- onchange="sigmaFilterByCategory(this.value)">
413
+ data-act-change="sigma-filter-by-category">
302
414
  <option value="">All types</option>
303
415
  <option value="semantic">Semantic</option>
304
416
  <option value="episodic">Episodic</option>
@@ -387,7 +499,7 @@
387
499
  <div class="card p-3 mt-3">
388
500
  <div class="d-flex justify-content-between align-items-center mb-3">
389
501
  <h5 class="mb-0"><i class="bi bi-collection"></i> Knowledge Clusters</h5>
390
- <button class="btn btn-sm btn-outline-secondary" onclick="loadClusters()" title="Refresh clusters">
502
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="load-clusters" title="Refresh clusters">
391
503
  <i class="bi bi-arrow-clockwise"></i>
392
504
  </button>
393
505
  </div>
@@ -427,17 +539,14 @@
427
539
  </div>
428
540
  </div>
429
541
 
430
- <!-- Entity Explorer — standalone pane (v3.4.21c).
431
- Broken out of Graph per Varun's taxonomy: entities stand
432
- independently as a first-class concern. Same DOM IDs as the
433
- previous embedded version so ng-entities.js keeps working. -->
542
+ <!-- Entity Explorer — standalone pane (v3.4.21). -->
434
543
  <div class="tab-pane fade" id="entities-pane">
435
544
  <div class="d-flex justify-content-between align-items-center mb-3">
436
545
  <div>
437
546
  <h3 class="mb-0"><i class="bi bi-person-badge"></i> Entity Explorer</h3>
438
547
  <small class="text-muted">Compiled truth per entity &mdash; PageRank + Louvain communities</small>
439
548
  </div>
440
- <button class="btn btn-sm btn-outline-secondary" onclick="loadEntityExplorer()" title="Refresh entities">
549
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="load-entity-explorer" title="Refresh entities">
441
550
  <i class="bi bi-arrow-clockwise"></i> Refresh
442
551
  </button>
443
552
  </div>
@@ -450,6 +559,9 @@
450
559
  <div id="entity-detail-panel" class="mt-3" style="display:none"></div>
451
560
  </div>
452
561
 
562
+ <!-- Multi-Agent Memory — OD module renders into this pane via window.odRenderAgents -->
563
+ <div class="tab-pane fade" id="agents-pane"></div>
564
+
453
565
  <!-- Memories List -->
454
566
  <div class="tab-pane fade" id="memories-pane">
455
567
  <!-- Domain 4 (v3.4.21): Recall Lab is the primary search at
@@ -493,17 +605,17 @@
493
605
  <i class="bi bi-download"></i> Export
494
606
  </button>
495
607
  <ul class="dropdown-menu dropdown-menu-end">
496
- <li><a class="dropdown-item" href="#" onclick="exportAll('json'); return false;">
608
+ <li><a class="dropdown-item" href="#" data-act-click="export-all" data-format="json">
497
609
  <i class="bi bi-filetype-json"></i> Export All (JSON)
498
610
  </a></li>
499
- <li><a class="dropdown-item" href="#" onclick="exportAll('jsonl'); return false;">
611
+ <li><a class="dropdown-item" href="#" data-act-click="export-all" data-format="jsonl">
500
612
  <i class="bi bi-file-text"></i> Export All (JSONL)
501
613
  </a></li>
502
- <li><a class="dropdown-item" href="#" onclick="exportAll('csv'); return false;">
614
+ <li><a class="dropdown-item" href="#" data-act-click="export-all" data-format="csv">
503
615
  <i class="bi bi-filetype-csv"></i> Export All (CSV)
504
616
  </a></li>
505
617
  <li><hr class="dropdown-divider"></li>
506
- <li><a class="dropdown-item" href="#" id="export-search-btn" onclick="exportSearchResults(); return false;" style="display:none;">
618
+ <li><a class="dropdown-item" href="#" id="export-search-btn" data-act-click="export-search-results" style="display:none;">
507
619
  <i class="bi bi-funnel"></i> Export Search Results
508
620
  </a></li>
509
621
  </ul>
@@ -512,17 +624,17 @@
512
624
  </div>
513
625
  <div class="row g-2 mb-3">
514
626
  <div class="col-md-5">
515
- <select class="form-select" id="filter-category" onchange="searchMemories()">
627
+ <select class="form-select" id="filter-category" data-act-change="search-memories">
516
628
  <option value="">All categories</option>
517
629
  </select>
518
630
  </div>
519
631
  <div class="col-md-5">
520
- <select class="form-select" id="filter-project" onchange="searchMemories()">
632
+ <select class="form-select" id="filter-project" data-act-change="search-memories">
521
633
  <option value="">All projects</option>
522
634
  </select>
523
635
  </div>
524
636
  <div class="col-md-2">
525
- <button class="btn btn-outline-secondary w-100" onclick="searchMemories()" title="Refresh list">
637
+ <button class="btn btn-outline-secondary w-100" data-act-click="search-memories" title="Refresh list">
526
638
  <i class="bi bi-arrow-clockwise"></i> Refresh
527
639
  </button>
528
640
  </div>
@@ -534,14 +646,14 @@
534
646
  <button type="button"
535
647
  class="btn btn-sm btn-outline-success mem-filter-pill"
536
648
  data-filter="high_reward"
537
- onclick="setMemoryFilter('high_reward')"
649
+ data-act-click="set-memory-filter" data-filter="high_reward"
538
650
  title="Facts with reward ≥ 0.7 in last 30 days">
539
651
  ⭐ High-reward (30d)
540
652
  </button>
541
653
  <button type="button"
542
654
  class="btn btn-sm btn-outline-warning mem-filter-pill ms-2"
543
655
  data-filter="being_forgotten"
544
- onclick="setMemoryFilter('being_forgotten')"
656
+ data-act-click="set-memory-filter" data-filter="being_forgotten"
545
657
  title="Archived or cold with no positive reward in 60 days">
546
658
  🕯️ Being forgotten
547
659
  </button>
@@ -599,11 +711,11 @@
599
711
  Operations pane. -->
600
712
  <div class="card p-2 mb-3" id="health-subnav">
601
713
  <div class="d-flex flex-wrap gap-1 small">
602
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-daemon').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-heart-pulse"></i> Daemon</button>
603
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-events').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-broadcast"></i> Events</button>
604
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-agents').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-robot"></i> Agents</button>
605
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-ides').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-plug"></i> IDEs</button>
606
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('health-section-math').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-calculator"></i> Math</button>
714
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="health-section-daemon"><i class="bi bi-heart-pulse"></i> Daemon</button>
715
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="health-section-events"><i class="bi bi-broadcast"></i> Events</button>
716
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="health-section-agents"><i class="bi bi-robot"></i> Agents</button>
717
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="health-section-ides"><i class="bi bi-plug"></i> IDEs</button>
718
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="health-section-math"><i class="bi bi-calculator"></i> Math</button>
607
719
  </div>
608
720
  </div>
609
721
 
@@ -611,7 +723,7 @@
611
723
  <section id="health-section-daemon" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
612
724
  <div class="d-flex justify-content-between align-items-center mb-3">
613
725
  <h5 class="mb-0"><i class="bi bi-heart-pulse"></i> Daemon health</h5>
614
- <button class="btn btn-sm btn-outline-secondary" onclick="loadHealthMonitor()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
726
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="load-health-monitor"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
615
727
  </div>
616
728
  <div id="health-overview"></div>
617
729
  <div class="row g-3">
@@ -642,7 +754,7 @@
642
754
  </div>
643
755
  <div>
644
756
  <span id="event-connection-status" class="badge bg-secondary me-2">Connecting...</span>
645
- <select class="form-select form-select-sm d-inline-block w-auto" id="event-type-filter" onchange="filterEvents()">
757
+ <select class="form-select form-select-sm d-inline-block w-auto" id="event-type-filter" data-act-change="filter-events">
646
758
  <option value="">All events</option>
647
759
  <option value="memory.created">Memory created</option>
648
760
  <option value="memory.updated">Memory updated</option>
@@ -650,7 +762,7 @@
650
762
  <option value="memory.recalled">Memory recalled</option>
651
763
  <option value="agent.connected">Agent connected</option>
652
764
  </select>
653
- <button class="btn btn-sm btn-outline-secondary ms-1" onclick="clearEventStream()">
765
+ <button class="btn btn-sm btn-outline-secondary ms-1" data-act-click="clear-event-stream">
654
766
  <i class="bi bi-trash"></i> Clear
655
767
  </button>
656
768
  </div>
@@ -677,7 +789,7 @@
677
789
  <h5 class="mb-0"><i class="bi bi-robot"></i> Connected agents</h5>
678
790
  <small class="text-muted">AI tools that interact with your memory</small>
679
791
  </div>
680
- <button class="btn btn-sm btn-outline-secondary" onclick="loadAgents()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
792
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="load-agents"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
681
793
  </div>
682
794
  <div class="row g-2 mb-3" id="agent-stats-row">
683
795
  <div class="col-md-3"><div class="border rounded p-2 text-center"><div class="fw-bold" id="agent-stat-total">0</div><small class="text-muted">Total agents</small></div></div>
@@ -713,7 +825,7 @@
713
825
  <!-- ===== SECTION: Math Health ===== -->
714
826
  <section id="health-section-math" class="card p-3 mb-3" style="scroll-margin-top: 80px;">
715
827
  <h5 class="mb-2"><i class="bi bi-calculator"></i> Mathematical layer health</h5>
716
- <p class="text-muted small mb-3">Status of Fisher-Rao, sheaf cohomology, and Langevin dynamics.</p>
828
+ <p class="text-muted small mb-3">Status of mathematical scoring layers.</p>
717
829
  <div class="row g-3" id="math-health-cards"></div>
718
830
  </section>
719
831
  </div>
@@ -732,10 +844,10 @@
732
844
  </div>
733
845
  <div class="card p-2 mb-3" id="operations-subnav">
734
846
  <div class="d-flex flex-wrap gap-1 small">
735
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-ingestion').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-cloud-download"></i> Ingestion</button>
736
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-lifecycle').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-hourglass-split"></i> Lifecycle</button>
737
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-trust').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-shield-check"></i> Trust</button>
738
- <button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('ops-section-compliance').scrollIntoView({behavior:'smooth',block:'start'})"><i class="bi bi-shield-lock"></i> Compliance</button>
847
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="ops-section-ingestion"><i class="bi bi-cloud-download"></i> Ingestion</button>
848
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="ops-section-lifecycle"><i class="bi bi-hourglass-split"></i> Lifecycle</button>
849
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="ops-section-trust"><i class="bi bi-shield-check"></i> Trust</button>
850
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-act-click="scroll-into" data-target="ops-section-compliance"><i class="bi bi-shield-lock"></i> Compliance</button>
739
851
  </div>
740
852
  </div>
741
853
 
@@ -746,7 +858,7 @@
746
858
  <h5 class="mb-0"><i class="bi bi-cloud-download"></i> Ingestion status</h5>
747
859
  <small class="text-muted">Gmail, Calendar, Transcript adapters &mdash; all opt-in</small>
748
860
  </div>
749
- <button class="btn btn-sm btn-outline-secondary" onclick="loadIngestionStatus()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
861
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="load-ingestion-status"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
750
862
  </div>
751
863
  <div id="ingestion-overview"></div>
752
864
  <div id="ingestion-adapters" class="mb-3"></div>
@@ -762,9 +874,9 @@
762
874
  <h5 class="mb-0"><i class="bi bi-hourglass-split text-warning"></i> Memory lifecycle</h5>
763
875
  <div>
764
876
  <span class="badge bg-secondary me-2" id="lifecycle-profile-badge">default</span>
765
- <button class="btn btn-sm btn-outline-success" onclick="evaluateTiersNow()"><i class="bi bi-arrow-repeat"></i> Evaluate tiers</button>
766
- <button class="btn btn-sm btn-outline-info ms-1" onclick="compactDryRun()"><i class="bi bi-funnel"></i> Preview compaction</button>
767
- <button class="btn btn-sm btn-outline-warning ms-1" onclick="compactExecute()"><i class="bi bi-lightning"></i> Compact now</button>
877
+ <button class="btn btn-sm btn-outline-success" data-act-click="evaluate-tiers-now"><i class="bi bi-arrow-repeat"></i> Evaluate tiers</button>
878
+ <button class="btn btn-sm btn-outline-info ms-1" data-act-click="compact-dry-run"><i class="bi bi-funnel"></i> Preview compaction</button>
879
+ <button class="btn btn-sm btn-outline-warning ms-1" data-act-click="compact-execute"><i class="bi bi-lightning"></i> Compact now</button>
768
880
  </div>
769
881
  </div>
770
882
  <div class="row g-3 mb-3" id="lifecycle-states-row">
@@ -856,13 +968,13 @@
856
968
  <div class="col-md-2"><input type="number" class="form-control form-control-sm" id="cp-retention-days" placeholder="Days" value="90"></div>
857
969
  <div class="col-md-2"><input type="text" class="form-control form-control-sm" id="cp-category" placeholder="Category (optional)"></div>
858
970
  <div class="col-md-2"><select class="form-select form-select-sm" id="cp-action"><option value="archive">Archive</option><option value="tombstone">Tombstone</option><option value="notify">Notify only</option></select></div>
859
- <div class="col-md-3"><button class="btn btn-sm btn-success w-100" onclick="createRetentionPolicy()"><i class="bi bi-shield-plus"></i> Create policy</button></div>
971
+ <div class="col-md-3"><button class="btn btn-sm btn-success w-100" data-act-click="create-retention-policy"><i class="bi bi-shield-plus"></i> Create policy</button></div>
860
972
  </div>
861
973
  <h6 class="mb-2">Active retention policies</h6>
862
974
  <div class="mb-3" id="compliance-policies-content"><span class="text-muted">Loading...</span></div>
863
975
  <div class="d-flex justify-content-between align-items-center mb-2">
864
976
  <h6 class="mb-0">Audit trail</h6>
865
- <select class="form-select form-select-sm" id="cp-audit-filter" style="width: auto;" onchange="loadCompliance()">
977
+ <select class="form-select form-select-sm" id="cp-audit-filter" style="width: auto;" data-act-change="load-compliance">
866
978
  <option value="">All events</option>
867
979
  <option value="recall">Recall</option>
868
980
  <option value="remember">Remember</option>
@@ -883,7 +995,7 @@
883
995
  <div class="ng-content-title"><i class="bi bi-lightning-charge"></i> Skill Evolution</div>
884
996
  <div class="ng-content-subtitle">Track skill performance, evolution history, and health status</div>
885
997
  </div>
886
- <button class="ng-btn" onclick="loadSkillEvolution()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
998
+ <button class="ng-btn" data-act-click="load-skill-evolution"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
887
999
  </div>
888
1000
  <div id="skills-overview-cards"></div>
889
1001
  <div id="skills-list" style="margin-top:24px">
@@ -903,7 +1015,7 @@
903
1015
  <div class="ng-content-title"><i class="bi bi-share"></i> Mesh Peers</div>
904
1016
  <div class="ng-content-subtitle">P2P agent communication network — real-time status</div>
905
1017
  </div>
906
- <button class="ng-btn" onclick="loadMeshPeers()"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
1018
+ <button class="ng-btn" data-act-click="load-mesh-peers"><i class="bi bi-arrow-clockwise"></i> Refresh</button>
907
1019
  </div>
908
1020
  <div id="mesh-status-cards"></div>
909
1021
  <div style="margin-top:24px">
@@ -1154,7 +1266,7 @@
1154
1266
  <input type="text" class="form-control" id="new-profile-name" placeholder="e.g. work, personal, project-x" maxlength="32">
1155
1267
  </div>
1156
1268
  <div class="col-md-3">
1157
- <button class="btn btn-primary w-100" onclick="createProfile()">
1269
+ <button class="btn btn-primary w-100" data-act-click="create-profile">
1158
1270
  <i class="bi bi-plus-circle"></i> Create Profile
1159
1271
  </button>
1160
1272
  </div>
@@ -1200,10 +1312,10 @@
1200
1312
  <label class="form-check-label" for="backup-enabled">Auto-backup enabled</label>
1201
1313
  </div>
1202
1314
  <div class="d-flex gap-2">
1203
- <button class="btn btn-primary" onclick="saveBackupConfig()">
1315
+ <button class="btn btn-primary" data-act-click="save-backup-config">
1204
1316
  <i class="bi bi-save"></i> Save Settings
1205
1317
  </button>
1206
- <button class="btn btn-outline-success" onclick="createBackupNow()">
1318
+ <button class="btn btn-outline-success" data-act-click="create-backup-now">
1207
1319
  <i class="bi bi-download"></i> Backup Now
1208
1320
  </button>
1209
1321
  </div>
@@ -1220,16 +1332,16 @@
1220
1332
  <div class="text-muted small">Loading cloud destinations...</div>
1221
1333
  </div>
1222
1334
  <div class="d-flex gap-2 flex-wrap">
1223
- <button class="btn btn-outline-primary btn-sm" onclick="connectGoogleDrive()">
1335
+ <button class="btn btn-outline-primary btn-sm" data-act-click="connect-google-drive">
1224
1336
  <i class="bi bi-google"></i> Connect Google Drive
1225
1337
  </button>
1226
- <button class="btn btn-outline-dark btn-sm" onclick="connectGitHub()">
1338
+ <button class="btn btn-outline-dark btn-sm" data-act-click="connect-git-hub">
1227
1339
  <i class="bi bi-github"></i> Connect GitHub
1228
1340
  </button>
1229
- <button class="btn btn-outline-success btn-sm" onclick="syncCloudNow()">
1341
+ <button class="btn btn-outline-success btn-sm" data-act-click="sync-cloud-now">
1230
1342
  <i class="bi bi-cloud-upload"></i> Sync Now
1231
1343
  </button>
1232
- <button class="btn btn-outline-info btn-sm" onclick="exportBackup()">
1344
+ <button class="btn btn-outline-info btn-sm" data-act-click="export-backup">
1233
1345
  <i class="bi bi-file-earmark-zip"></i> Export Backup
1234
1346
  </button>
1235
1347
  </div>
@@ -1244,10 +1356,10 @@
1244
1356
  </p>
1245
1357
  <div id="learning-data-stats" class="mb-3"></div>
1246
1358
  <div class="d-flex gap-2">
1247
- <button class="btn btn-outline-danger" onclick="resetLearningData()">
1359
+ <button class="btn btn-outline-danger" data-act-click="reset-learning-data">
1248
1360
  <i class="bi bi-arrow-counterclockwise"></i> Reset Learning Data
1249
1361
  </button>
1250
- <button class="btn btn-outline-info" onclick="backupLearningDb()">
1362
+ <button class="btn btn-outline-info" data-act-click="backup-learning-db">
1251
1363
  <i class="bi bi-download"></i> Backup Learning DB
1252
1364
  </button>
1253
1365
  </div>
@@ -1340,8 +1452,12 @@
1340
1452
  </div>
1341
1453
  </div>
1342
1454
  </div>
1455
+ <div class="tab-pane fade" id="mcp-pane"></div>
1456
+ <div class="tab-pane fade" id="backup-pane"></div>
1343
1457
  </div>
1344
- </div>
1458
+ </main><!-- /.content -->
1459
+ </div><!-- /.main -->
1460
+ </div><!-- /.app -->
1345
1461
 
1346
1462
  <!-- Memory Detail Modal -->
1347
1463
  <div class="modal fade" id="memoryDetailModal" tabindex="-1" aria-labelledby="memoryDetailModalLabel" aria-hidden="true">
@@ -1363,10 +1479,10 @@
1363
1479
  </div>
1364
1480
  <div class="modal-footer justify-content-between">
1365
1481
  <div>
1366
- <button class="btn btn-sm btn-outline-secondary" onclick="copyMemoryToClipboard()" title="Copy to clipboard">
1482
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="copy-memory-to-clipboard" title="Copy to clipboard">
1367
1483
  <i class="bi bi-clipboard"></i> Copy
1368
1484
  </button>
1369
- <button class="btn btn-sm btn-outline-secondary" onclick="exportMemoryAsMarkdown()" title="Download as Markdown">
1485
+ <button class="btn btn-sm btn-outline-secondary" data-act-click="export-memory-as-markdown" title="Download as Markdown">
1370
1486
  <i class="bi bi-markdown"></i> Export .md
1371
1487
  </button>
1372
1488
  </div>
@@ -1391,6 +1507,12 @@
1391
1507
  <!-- Modular JS (v2.5 — split from monolith app.js) -->
1392
1508
  <script src="static/js/core.js"></script>
1393
1509
 
1510
+ <!-- Product-wide login gate (v3.8.0): personal mode = no gate; company mode
1511
+ = first-run create-admin / sign-in over the HttpOnly session cookie.
1512
+ Loads right after core.js so it can paint its overlay before any
1513
+ dashboard content renders to an unauthenticated operator. -->
1514
+ <script src="static/js/od-auth-gate.js?v=380"></script>
1515
+
1394
1516
  <!-- v3.4.1: Event bus (must load before graph + chat) -->
1395
1517
  <script src="static/js/graph-event-bus.js"></script>
1396
1518
  <!-- v3.4.1: Sigma.js Knowledge Graph (defines globals: filterState, loadGraph, renderGraph) -->
@@ -1416,14 +1538,14 @@
1416
1538
  <script src="static/js/events.js"></script>
1417
1539
  <script src="static/js/agents.js"></script>
1418
1540
  <!-- Brain tab (v3.4.21 — XSS-safe DOM, token-gated, strict CSP on /api/v3/brain) -->
1419
- <script src="static/js/brain.js?v=34421" defer></script>
1541
+ <script src="static/js/brain.js?v=380" defer></script>
1420
1542
  <script src="static/js/feedback.js"></script>
1421
1543
  <script src="static/js/lifecycle.js"></script>
1422
1544
  <script src="static/js/compliance.js"></script>
1423
1545
  <script src="static/js/init.js?v=34421fix"></script>
1424
1546
  <script src="static/js/dashboard.js"></script>
1425
1547
  <script src="static/js/recall-lab.js"></script>
1426
- <script src="static/js/trust-dashboard.js?v=34421"></script>
1548
+ <script src="static/js/trust-dashboard.js?v=380"></script>
1427
1549
  <script src="static/js/math-health.js"></script>
1428
1550
  <script src="static/js/auto-settings.js"></script>
1429
1551
  <script src="static/js/ide-status.js"></script>
@@ -1435,9 +1557,30 @@
1435
1557
  <script src="static/js/ng-entities.js?v=3410"></script>
1436
1558
  <script src="static/js/ng-skills.js?v=3411"></script>
1437
1559
  <script src="static/js/ng-mesh.js?v=345"></script>
1438
- <script src="static/js/ng-shell.js?v=34421g"></script>
1560
+ <!-- OD Shell v1.0 — replaces ng-shell.js; CSP-safe single-page tab switching -->
1561
+ <script src="static/js/od-shell.js?v=380"></script>
1439
1562
  <!-- Optimize tab (v3.6.0) — runtime config for cache + compress + proxy -->
1440
1563
  <script src="static/js/optimize.js?v=360"></script>
1564
+ <!-- B2 (v3.7.9): CSP-safe event delegation — replaces inline on*= handlers -->
1565
+ <script src="static/js/event-delegation.js?v=379"></script>
1566
+ <!-- OD screen modules (v3.7.9): approved-design panes wired to live data.
1567
+ Load LAST so their window.load<Screen> overrides win over the legacy loaders. -->
1568
+ <script src="static/js/od-brain.js?v=379"></script>
1569
+ <script src="static/js/od-health.js?v=380"></script>
1570
+ <script src="static/js/od-operations.js?v=380"></script>
1571
+ <script src="static/js/od-team.js?v=379"></script>
1572
+ <script src="static/js/od-graph.js?v=379"></script>
1573
+ <script src="static/js/od-memories.js?v=379"></script>
1574
+ <script src="static/js/od-entities.js?v=379"></script>
1575
+ <!-- Multi-Agent Memory pane (v3.8.0): visualises memory written by multiple agents -->
1576
+ <script src="static/js/od-agents.js?v=380"></script>
1577
+ <script src="static/js/od-skills.js?v=379"></script>
1578
+ <script src="static/js/od-mesh.js?v=379"></script>
1579
+ <script src="static/js/od-optimize.js?v=379"></script>
1580
+ <script src="static/js/od-settings.js?v=380"></script>
1581
+ <script src="static/js/od-backup.js?v=379"></script>
1582
+ <!-- MCP & Integrations pane (v3.8.0): shows exposed MCP tool profile + counts -->
1583
+ <script src="static/js/od-mcp.js?v=380"></script>
1441
1584
 
1442
1585
  <!-- Aggressive compression warning modal (v3.6.0 M-03) -->
1443
1586
  <div class="modal fade" id="optimizeAggressiveModal" tabindex="-1" aria-labelledby="optimizeAggressiveModalLabel" aria-hidden="true">
@@ -1464,19 +1607,6 @@
1464
1607
  </div>
1465
1608
  </div>
1466
1609
 
1467
- <footer style="text-align:center; padding:24px; border-top:1px solid var(--bs-border-color); font-size:0.8125rem;">
1468
- <div style="display:flex; align-items:center; justify-content:center; gap:8px; margin-bottom:8px;">
1469
- <span style="display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:6px; background:linear-gradient(135deg, #667eea 0%, #764ba2 100%); color:#fff; font-size:0.7rem;">&#x2B26;</span>
1470
- <strong>SuperLocalMemory</strong> by <a href="https://qualixar.com" style="font-weight:600;">Qualixar</a>
1471
- </div>
1472
- <p style="margin:4px 0;">Built by <a href="https://github.com/varun369">Varun Pratap Bhardwaj</a> · <a href="https://qualixar.com">qualixar.com</a></p>
1473
- <p style="margin:4px 0;">
1474
- <a href="https://github.com/qualixar/superlocalmemory"><i class="bi bi-github"></i> GitHub</a> ·
1475
- <a href="https://www.npmjs.com/package/superlocalmemory"><i class="bi bi-box-seam"></i> npm</a> ·
1476
- <a href="https://pypi.org/project/superlocalmemory/"><i class="bi bi-box"></i> PyPI</a> ·
1477
- AGPL-3.0-or-later ·
1478
- <a href="https://github.com/qualixar/superlocalmemory/stargazers">⭐ Star us on GitHub</a>
1479
- </p>
1480
- </footer>
1610
+ <!-- Footer injected into #main-content by od-shell.js slmShell() -->
1481
1611
  </body>
1482
1612
  </html>