superlocalmemory 3.4.21 → 3.4.23

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 (114) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/package.json +1 -1
  3. package/pyproject.toml +2 -2
  4. package/scripts/build_entry.py +1 -1
  5. package/scripts/release_manifest.py +2 -2
  6. package/skills/slm-build-graph/SKILL.md +1 -1
  7. package/skills/slm-list-recent/SKILL.md +1 -1
  8. package/skills/slm-recall/SKILL.md +3 -3
  9. package/skills/slm-remember/SKILL.md +1 -1
  10. package/skills/slm-status/SKILL.md +1 -1
  11. package/skills/slm-switch-profile/SKILL.md +1 -1
  12. package/src/superlocalmemory/__init__.py +3 -0
  13. package/src/superlocalmemory/cli/commands.py +40 -5
  14. package/src/superlocalmemory/cli/context_commands.py +1 -1
  15. package/src/superlocalmemory/cli/db_migrate.py +1 -1
  16. package/src/superlocalmemory/cli/escape_hatch.py +1 -1
  17. package/src/superlocalmemory/cli/main.py +3 -3
  18. package/src/superlocalmemory/core/context_cache.py +2 -2
  19. package/src/superlocalmemory/core/ram_lock.py +1 -1
  20. package/src/superlocalmemory/core/recall_pipeline.py +5 -5
  21. package/src/superlocalmemory/core/security_primitives.py +2 -2
  22. package/src/superlocalmemory/core/shadow_router.py +2 -2
  23. package/src/superlocalmemory/core/slm_disabled.py +1 -1
  24. package/src/superlocalmemory/core/slmignore.py +1 -1
  25. package/src/superlocalmemory/core/topic_signature.py +3 -3
  26. package/src/superlocalmemory/evolution/budget.py +1 -1
  27. package/src/superlocalmemory/evolution/llm_dispatch.py +2 -2
  28. package/src/superlocalmemory/hooks/_outcome_common.py +1 -1
  29. package/src/superlocalmemory/hooks/adapter_base.py +1 -1
  30. package/src/superlocalmemory/hooks/antigravity_adapter.py +1 -1
  31. package/src/superlocalmemory/hooks/context_payload.py +2 -2
  32. package/src/superlocalmemory/hooks/copilot_adapter.py +1 -1
  33. package/src/superlocalmemory/hooks/cross_platform_connector.py +1 -1
  34. package/src/superlocalmemory/hooks/cursor_adapter.py +1 -1
  35. package/src/superlocalmemory/hooks/hook_handlers.py +1 -1
  36. package/src/superlocalmemory/hooks/ide_connector.py +2 -2
  37. package/src/superlocalmemory/hooks/post_tool_async_hook.py +1 -1
  38. package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +1 -1
  39. package/src/superlocalmemory/hooks/prewarm_auth.py +1 -1
  40. package/src/superlocalmemory/hooks/session_registry.py +1 -1
  41. package/src/superlocalmemory/hooks/stop_outcome_hook.py +1 -1
  42. package/src/superlocalmemory/hooks/sync_loop.py +2 -2
  43. package/src/superlocalmemory/hooks/user_prompt_hook.py +1 -1
  44. package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +1 -1
  45. package/src/superlocalmemory/learning/arm_catalog.py +1 -1
  46. package/src/superlocalmemory/learning/bandit.py +1 -1
  47. package/src/superlocalmemory/learning/bandit_cache.py +1 -1
  48. package/src/superlocalmemory/learning/consolidation_cycle.py +4 -4
  49. package/src/superlocalmemory/learning/consolidation_worker.py +1 -1
  50. package/src/superlocalmemory/learning/database.py +5 -5
  51. package/src/superlocalmemory/learning/dedup_hnsw.py +1 -1
  52. package/src/superlocalmemory/learning/ensemble.py +2 -2
  53. package/src/superlocalmemory/learning/fact_outcome_joins.py +1 -1
  54. package/src/superlocalmemory/learning/forgetting_scheduler.py +2 -2
  55. package/src/superlocalmemory/learning/hnsw_dedup.py +2 -2
  56. package/src/superlocalmemory/learning/labeler.py +3 -3
  57. package/src/superlocalmemory/learning/legacy_migration.py +1 -1
  58. package/src/superlocalmemory/learning/memory_merge.py +1 -1
  59. package/src/superlocalmemory/learning/model_cache.py +1 -1
  60. package/src/superlocalmemory/learning/model_rollback.py +2 -2
  61. package/src/superlocalmemory/learning/outcome_queue.py +2 -2
  62. package/src/superlocalmemory/learning/pattern_miner.py +1 -1
  63. package/src/superlocalmemory/learning/pattern_miner_constants.py +1 -1
  64. package/src/superlocalmemory/learning/ranker.py +3 -3
  65. package/src/superlocalmemory/learning/ranker_common.py +1 -1
  66. package/src/superlocalmemory/learning/ranker_retrain_legacy.py +3 -3
  67. package/src/superlocalmemory/learning/ranker_retrain_online.py +4 -4
  68. package/src/superlocalmemory/learning/reward.py +1 -1
  69. package/src/superlocalmemory/learning/reward_archive.py +2 -2
  70. package/src/superlocalmemory/learning/reward_boost.py +2 -2
  71. package/src/superlocalmemory/learning/reward_proxy.py +4 -4
  72. package/src/superlocalmemory/learning/shadow_test.py +1 -1
  73. package/src/superlocalmemory/learning/signal_worker.py +2 -2
  74. package/src/superlocalmemory/learning/signals.py +2 -2
  75. package/src/superlocalmemory/learning/trigram_index.py +1 -1
  76. package/src/superlocalmemory/mcp/tools_context.py +1 -1
  77. package/src/superlocalmemory/mcp/tools_core.py +2 -2
  78. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +3 -3
  79. package/src/superlocalmemory/server/bandit_loops.py +2 -2
  80. package/src/superlocalmemory/server/middleware/__init__.py +2 -2
  81. package/src/superlocalmemory/server/middleware/security_headers.py +3 -3
  82. package/src/superlocalmemory/server/routes/brain.py +10 -10
  83. package/src/superlocalmemory/server/routes/prewarm.py +1 -1
  84. package/src/superlocalmemory/server/security_middleware.py +21 -3
  85. package/src/superlocalmemory/server/unified_daemon.py +111 -9
  86. package/src/superlocalmemory/skills/slm-build-graph/SKILL.md +423 -0
  87. package/src/superlocalmemory/skills/slm-list-recent/SKILL.md +348 -0
  88. package/src/superlocalmemory/skills/slm-recall/SKILL.md +343 -0
  89. package/src/superlocalmemory/skills/slm-remember/SKILL.md +194 -0
  90. package/src/superlocalmemory/skills/slm-show-patterns/SKILL.md +224 -0
  91. package/src/superlocalmemory/skills/slm-status/SKILL.md +363 -0
  92. package/src/superlocalmemory/skills/slm-switch-profile/SKILL.md +442 -0
  93. package/src/superlocalmemory/storage/migration_runner.py +4 -4
  94. package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +1 -1
  95. package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +2 -2
  96. package/src/superlocalmemory/storage/migrations/M003_migration_log.py +1 -1
  97. package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +1 -1
  98. package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +1 -1
  99. package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +1 -1
  100. package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +1 -1
  101. package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +1 -1
  102. package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +2 -2
  103. package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +1 -1
  104. package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +1 -1
  105. package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +2 -2
  106. package/src/superlocalmemory/storage/migrations/__init__.py +3 -3
  107. package/src/superlocalmemory/ui/index.html +4 -0
  108. package/src/superlocalmemory/ui/js/core.js +96 -1
  109. package/src/superlocalmemory.egg-info/PKG-INFO +655 -0
  110. package/src/superlocalmemory.egg-info/SOURCES.txt +426 -0
  111. package/src/superlocalmemory.egg-info/dependency_links.txt +1 -0
  112. package/src/superlocalmemory.egg-info/entry_points.txt +2 -0
  113. package/src/superlocalmemory.egg-info/requires.txt +58 -0
  114. package/src/superlocalmemory.egg-info/top_level.txt +1 -0
@@ -3,6 +3,97 @@
3
3
  // Security: All dynamic text MUST pass through escapeHtml() before DOM insertion.
4
4
  // Data originates from our own trusted local SQLite database (localhost only).
5
5
 
6
+ // ============================================================================
7
+ // v3.4.23 — slmFetch(): fetch with 15s abort timeout
8
+ // ----------------------------------------------------------------------------
9
+ // Bare fetch() never resolves when the daemon dies mid-request (socket kept
10
+ // open, Promise pending). That leaves dashboard spinners running forever and
11
+ // stacks up orphan fetches that make hard-refresh hang. slmFetch wraps every
12
+ // request in an AbortController with a 15 s ceiling, so a dead daemon
13
+ // surfaces as a normal rejection and the UI can show a clear error.
14
+ // ============================================================================
15
+
16
+ window.SLM_FETCH_TIMEOUT_MS = 15000;
17
+
18
+ // Global fetch patch: apply the abort timeout to every relative-URL request
19
+ // automatically. 17 UI modules call bare fetch() — patching here avoids
20
+ // touching each one and guarantees no future callsite can regress to an
21
+ // un-timed fetch that holds the spinner forever. Absolute URLs (external
22
+ // resources) are passed through unchanged. Callers that already supply
23
+ // `signal` keep their own behavior. `init.timeoutMs` lets callers override
24
+ // the default per-request.
25
+ (function patchFetch() {
26
+ if (window.__slmFetchPatched) return;
27
+ window.__slmFetchPatched = true;
28
+ var _origFetch = window.fetch.bind(window);
29
+ window.fetch = function (input, init) {
30
+ init = init || {};
31
+ var urlStr = typeof input === 'string' ? input : (input && input.url) || '';
32
+ var isRelative = !(/^https?:\/\//i.test(urlStr));
33
+ if (!isRelative || init.signal) {
34
+ return _origFetch(input, init);
35
+ }
36
+ var controller = new AbortController();
37
+ var timeoutMs = init.timeoutMs || window.SLM_FETCH_TIMEOUT_MS;
38
+ var timer = setTimeout(function () { controller.abort(); }, timeoutMs);
39
+ init.signal = controller.signal;
40
+ return _origFetch(input, init).finally(function () { clearTimeout(timer); });
41
+ };
42
+ })();
43
+
44
+ // Thin named wrapper for callsites that want explicit timeout control.
45
+ // Equivalent to the patched fetch above but accepts `init.timeoutMs`.
46
+ async function slmFetch(input, init) {
47
+ return fetch(input, init || {});
48
+ }
49
+
50
+ // ============================================================================
51
+ // v3.4.23 — version fingerprint + auto-reload on daemon upgrade
52
+ // ----------------------------------------------------------------------------
53
+ // index.html ships with <meta name="slm-version" content="__SLM_VERSION__">
54
+ // that the server fills in at serve time. After page load we ask the daemon
55
+ // for its current version via /api/version; on mismatch we clear localStorage
56
+ // and hard-reload once, so a stale tab never lingers after `slm restart` or
57
+ // a package upgrade. Guarded by sessionStorage to avoid reload loops.
58
+ // ============================================================================
59
+
60
+ async function checkVersionFingerprint() {
61
+ try {
62
+ var metaEl = document.querySelector('meta[name="slm-version"]');
63
+ var pageVersion = metaEl ? metaEl.getAttribute('content') : null;
64
+ if (!pageVersion || pageVersion === '__SLM_VERSION__') return;
65
+ var resp = await slmFetch('/api/version', { timeoutMs: 5000 });
66
+ if (!resp.ok) return;
67
+ var data = await resp.json();
68
+ var serverVersion = data && data.version;
69
+ if (!serverVersion || serverVersion === pageVersion) return;
70
+ try {
71
+ if (sessionStorage.getItem('slm-version-reload-done') === serverVersion) {
72
+ console.warn('[slm] version mismatch persists after reload:',
73
+ pageVersion, '!=', serverVersion);
74
+ return;
75
+ }
76
+ sessionStorage.setItem('slm-version-reload-done', serverVersion);
77
+ } catch (e) {
78
+ // sessionStorage blocked (private mode, quota, etc.) — fall through
79
+ // to reload. Worst case: we reload twice instead of once, still
80
+ // safe because server version converges on second attempt.
81
+ }
82
+ try {
83
+ // Preserve theme; drop everything else that might be stale.
84
+ var theme = localStorage.getItem('slm-theme');
85
+ localStorage.clear();
86
+ if (theme) localStorage.setItem('slm-theme', theme);
87
+ } catch (e) { /* localStorage may be blocked */ }
88
+ console.info('[slm] daemon upgraded', pageVersion, '->', serverVersion,
89
+ '— reloading');
90
+ location.reload();
91
+ } catch (err) {
92
+ // Network error or daemon down: don't reload, just log.
93
+ console.debug('[slm] version check skipped:', err && err.message);
94
+ }
95
+ }
96
+
6
97
  // ============================================================================
7
98
  // Dark Mode
8
99
  // ============================================================================
@@ -180,7 +271,7 @@ function formatDateFull(dateString) {
180
271
 
181
272
  async function loadStats() {
182
273
  try {
183
- var response = await fetch('/api/stats');
274
+ var response = await slmFetch('/api/stats');
184
275
  var data = await response.json();
185
276
  var ov = data.overview || {};
186
277
  animateCounter('stat-memories', ov.total_memories || 0);
@@ -235,6 +326,10 @@ function populateFilters(categories, projects) {
235
326
 
236
327
  window.addEventListener('DOMContentLoaded', function() {
237
328
  initDarkMode();
329
+ // v3.4.23: version check runs first and non-blocking. If a mismatch is
330
+ // detected it triggers location.reload(), so the rest of init on the
331
+ // stale page becomes a no-op.
332
+ checkVersionFingerprint();
238
333
  loadProfiles();
239
334
  loadStats();
240
335
  loadGraph();