superlocalmemory 3.6.16 → 3.6.18

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 (57) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +3 -2
  3. package/package.json +1 -1
  4. package/plugin/.claude-plugin/plugin.json +1 -1
  5. package/plugin/CLAUDE.md +3 -3
  6. package/plugin/agents/slm-memory-advisor.md +1 -1
  7. package/plugin/agents/slm-optimize-advisor.md +1 -1
  8. package/plugin/requirements.txt +1 -1
  9. package/plugin/skills/slm-cache/SKILL.md +1 -1
  10. package/plugin/skills/slm-compress/SKILL.md +1 -1
  11. package/plugin/skills/slm-graph/SKILL.md +1 -1
  12. package/plugin/skills/slm-recall/SKILL.md +1 -1
  13. package/plugin/skills/slm-remember/SKILL.md +1 -1
  14. package/plugin/skills/slm-session/SKILL.md +1 -1
  15. package/plugin/skills/slm-status/SKILL.md +1 -1
  16. package/plugin-src/agents/slm-memory-advisor.md +1 -1
  17. package/plugin-src/agents/slm-optimize-advisor.md +1 -1
  18. package/plugin-src/manifest.json +1 -1
  19. package/plugin-src/requirements.txt +1 -1
  20. package/plugin-src/rules/AGENTS.md +1 -1
  21. package/plugin-src/rules/CLAUDE.md.fragment +3 -3
  22. package/plugin-src/skills/slm-cache/SKILL.md +1 -1
  23. package/plugin-src/skills/slm-compress/SKILL.md +1 -1
  24. package/plugin-src/skills/slm-graph/SKILL.md +1 -1
  25. package/plugin-src/skills/slm-recall/SKILL.md +1 -1
  26. package/plugin-src/skills/slm-remember/SKILL.md +1 -1
  27. package/plugin-src/skills/slm-session/SKILL.md +1 -1
  28. package/plugin-src/skills/slm-status/SKILL.md +1 -1
  29. package/pyproject.toml +3 -2
  30. package/scripts/build-plugin.js +1 -1
  31. package/scripts/postinstall-interactive.js +94 -7
  32. package/src/superlocalmemory/__init__.py +1 -1
  33. package/src/superlocalmemory/cli/setup_wizard.py +34 -0
  34. package/src/superlocalmemory/core/embeddings.py +5 -0
  35. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +4 -0
  36. package/src/superlocalmemory/hooks/adapter_base.py +10 -3
  37. package/src/superlocalmemory/hooks/claude_code_hooks.py +40 -4
  38. package/src/superlocalmemory/hooks/copilot_adapter.py +78 -9
  39. package/src/superlocalmemory/hooks/hook_handlers.py +59 -1
  40. package/src/superlocalmemory/hooks/memory_protocol.py +102 -0
  41. package/src/superlocalmemory/hooks/post_tool_async_hook.py +23 -5
  42. package/src/superlocalmemory/infra/event_bus.py +4 -0
  43. package/src/superlocalmemory/learning/feedback.py +59 -0
  44. package/src/superlocalmemory/learning/outcome_queue.py +10 -2
  45. package/src/superlocalmemory/llm/backbone.py +8 -1
  46. package/src/superlocalmemory/retrieval/reranker.py +5 -0
  47. package/src/superlocalmemory/server/routes/learning.py +2 -0
  48. package/src/superlocalmemory/server/routes/v3_api.py +11 -0
  49. package/src/superlocalmemory/server/unified_daemon.py +78 -0
  50. package/src/superlocalmemory/storage/database.py +34 -7
  51. package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +79 -0
  52. package/src/superlocalmemory.egg-info/PKG-INFO +4 -3
  53. package/src/superlocalmemory.egg-info/SOURCES.txt +2 -0
  54. package/plugin-src/commands/slm-optimize.md +0 -22
  55. package/plugin-src/commands/slm-recall.md +0 -16
  56. package/plugin-src/commands/slm-remember.md +0 -16
  57. package/plugin-src/commands/slm-status.md +0 -15
@@ -12,7 +12,7 @@ Part of Qualixar | Author: Varun Pratap Bhardwaj
12
12
  """
13
13
  from __future__ import annotations
14
14
 
15
- import json, logging, sqlite3, threading, time
15
+ import json, logging, os, sqlite3, threading, time
16
16
  from contextlib import contextmanager
17
17
  from pathlib import Path
18
18
  from types import ModuleType
@@ -27,10 +27,16 @@ from superlocalmemory.storage.models import (
27
27
 
28
28
  logger = logging.getLogger(__name__)
29
29
 
30
- def _jl(raw: Any, default: Any = None) -> Any:
31
- """JSON-load a value, returning *default* on None/empty."""
30
+ _MISSING = object()
31
+
32
+ def _jl(raw: Any, default: Any = _MISSING) -> Any:
33
+ """JSON-load a value, returning *default* on None/empty.
34
+
35
+ _jl(raw) -> [] when raw is None/empty (list fields)
36
+ _jl(raw, None) -> None when raw is None/empty (optional fields)
37
+ """
32
38
  if raw is None or raw == "":
33
- return default if default is not None else []
39
+ return [] if default is _MISSING else default
34
40
  return json.loads(raw)
35
41
 
36
42
  def _jd(val: Any) -> str | None:
@@ -38,9 +44,30 @@ def _jd(val: Any) -> str | None:
38
44
  return json.dumps(val) if val is not None else None
39
45
 
40
46
 
41
- _BUSY_TIMEOUT_MS = 10_000 # 10 seconds wait for other writers
42
- _MAX_RETRIES = 5 # retry on transient SQLITE_BUSY
43
- _RETRY_BASE_DELAY = 0.1 # seconds — exponential backoff base
47
+ def _env_int(name: str, default: int) -> int:
48
+ """Read a positive int from the environment, falling back on bad/absent."""
49
+ try:
50
+ val = int(os.environ.get(name, "").strip())
51
+ return val if val > 0 else default
52
+ except (ValueError, AttributeError):
53
+ return default
54
+
55
+
56
+ def _env_float(name: str, default: float) -> float:
57
+ """Read a positive float from the environment, falling back on bad/absent."""
58
+ try:
59
+ val = float(os.environ.get(name, "").strip())
60
+ return val if val > 0 else default
61
+ except (ValueError, AttributeError):
62
+ return default
63
+
64
+
65
+ # SQLite endurance tuning. Defaults preserve prior hard-coded behaviour exactly;
66
+ # operators on slow/contended I/O can raise them via env (issue #53) without a
67
+ # code change. Unset env => byte-identical to the previous constants.
68
+ _BUSY_TIMEOUT_MS = _env_int("SLM_DB_BUSY_TIMEOUT_MS", 10_000) # wait for writers
69
+ _MAX_RETRIES = _env_int("SLM_DB_MAX_RETRIES", 5) # retry on SQLITE_BUSY
70
+ _RETRY_BASE_DELAY = _env_float("SLM_DB_RETRY_BASE_DELAY", 0.1) # backoff base (s)
44
71
 
45
72
 
46
73
  def _scope_where(
@@ -0,0 +1,79 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
+ # Part of SuperLocalMemory v3.6.18
4
+
5
+ """M017 — scope column on ccq_consolidated_blocks.
6
+
7
+ The cognitive-consolidation queue table (``ccq_consolidated_blocks``) was
8
+ created before the M016 multi-scope migration and therefore has no ``scope``
9
+ column. Without it, consolidation summaries are always stored as
10
+ ``personal`` regardless of the source facts' scope — a silent data-loss edge
11
+ case when a user has opted into global or shared memory.
12
+
13
+ Fix: add a ``scope TEXT NOT NULL DEFAULT 'personal'`` column plus a
14
+ ``(profile_id, scope)`` covering index for scope-filtered queries.
15
+
16
+ Deferred (like M006, M011, M013, M016): the CCQ table is created by the
17
+ engine, not by migration DDL, so we apply after engine init via
18
+ ``apply_deferred``.
19
+
20
+ Author: Varun Pratap Bhardwaj / Qualixar
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import sqlite3
26
+
27
+ NAME = "M017_ccq_scope_column"
28
+ DB_TARGET = "memory"
29
+
30
+ TABLE = "ccq_consolidated_blocks"
31
+
32
+ DDL = (
33
+ f"ALTER TABLE {TABLE} ADD COLUMN scope TEXT NOT NULL DEFAULT 'personal';"
34
+ f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_scope ON {TABLE}(scope);"
35
+ f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_profile_scope ON {TABLE}(profile_id, scope);"
36
+ )
37
+
38
+
39
+ def _table_exists(conn: sqlite3.Connection, table: str) -> bool:
40
+ return conn.execute(
41
+ "SELECT 1 FROM sqlite_master WHERE type='table' AND name=?", (table,)
42
+ ).fetchone() is not None
43
+
44
+
45
+ def _column_names(conn: sqlite3.Connection, table: str) -> set[str]:
46
+ return {r[1] for r in conn.execute(f"PRAGMA table_info({table})").fetchall()}
47
+
48
+
49
+ def apply(conn: sqlite3.Connection) -> None:
50
+ """Idempotently add scope column + indexes to ccq_consolidated_blocks.
51
+
52
+ Skips silently when the table doesn't exist yet (engine hasn't created it)
53
+ or when the column is already present (re-apply or fresh install).
54
+ """
55
+ if not _table_exists(conn, TABLE):
56
+ return
57
+ cols = _column_names(conn, TABLE)
58
+ if "scope" not in cols:
59
+ conn.execute(
60
+ f"ALTER TABLE {TABLE} ADD COLUMN scope TEXT NOT NULL DEFAULT 'personal'"
61
+ )
62
+ conn.execute(f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_scope ON {TABLE}(scope)")
63
+ conn.execute(
64
+ f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_profile_scope ON {TABLE}(profile_id, scope)"
65
+ )
66
+
67
+
68
+ def verify(conn: sqlite3.Connection) -> bool:
69
+ """Applied when ccq_consolidated_blocks has the scope column and index."""
70
+ if not _table_exists(conn, TABLE):
71
+ return True # table absent — apply() skips it; nothing to verify
72
+ cols = _column_names(conn, TABLE)
73
+ if "scope" not in cols:
74
+ return False
75
+ idx = conn.execute(
76
+ "SELECT 1 FROM sqlite_master WHERE type='index' AND name=?",
77
+ (f"idx_{TABLE}_scope",),
78
+ ).fetchone()
79
+ return idx is not None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superlocalmemory
3
- Version: 3.6.16
3
+ Version: 3.6.18
4
4
  Summary: Information-geometric agent memory with mathematical guarantees
5
5
  Author-email: Varun Pratap Bhardwaj <admin@superlocalmemory.com>
6
6
  License: AGPL-3.0-or-later
@@ -96,10 +96,10 @@ Dynamic: license-file
96
96
  <img src="https://superlocalmemory.com/assets/logo-mark.png" alt="SuperLocalMemory" width="200"/>
97
97
  </p>
98
98
 
99
- <h1 align="center">SuperLocalMemory V3.6.16</h1>
99
+ <h1 align="center">SuperLocalMemory V3.6.18</h1>
100
100
  <p align="center"><strong>Cache. Compress. Remember. Three surfaces — proxy, MCP tools, or skill. Every setup covered.</strong><br/>
101
101
  <em>To the best of our knowledge, the only zero-cloud agent memory that beats Mem0's zero-LLM score on LoCoMo. Mode A: 74.8% vs Mem0 64.2% — no GPU, no API key, on CPU.</em></p>
102
- <p align="center"><code>v3.6.16</code> — <strong>Plugin-native. Profile-aware. Distributed-ready.</strong><br/>
102
+ <p align="center"><code>v3.6.18</code> — <strong>Plugin-native. Profile-aware. Distributed-ready.</strong><br/>
103
103
  Proxy: <code>slm wrap claude</code> &nbsp;·&nbsp; MCP: add <code>slm_compress</code> to your config &nbsp;·&nbsp; Skill: zero-config</p>
104
104
  <p align="center"><strong>3 published research papers</strong> (arXiv preprints + Zenodo-archived) · <a href="https://arxiv.org/abs/2603.02240">arXiv:2603.02240</a> · <a href="https://arxiv.org/abs/2603.14588">arXiv:2603.14588</a> · <a href="https://arxiv.org/abs/2604.04514">arXiv:2604.04514</a></p>
105
105
 
@@ -401,6 +401,7 @@ slm dashboard # Opens at http://localhost:8765
401
401
 
402
402
  | Version | Codename | Key Features |
403
403
  |---|---|---|
404
+ | **v3.6.17** | Community | 8 contributor PRs (observability events, marker-bounded adapter writes, daemon port discovery, anthropic `api_base`, OpenMP workers, atomic-write rehash, `_jl` sentinel, LFS pointer); dashboard-feedback fix (#53/#59); env-tunable SQLite knobs + idle backoff; remote LLM test-probe (#40) |
404
405
  | **v3.6.16** | Docs | Corrected Claude Code plugin install — adds the required `/plugin marketplace add` step; clarifies plugin vs pip/npm delivery |
405
406
  | **v3.6.15** | Multi-scope | **Opt-in [shared memory](docs/shared-memory.md)** (personal/shared/global, off by default), default-deny scope at every read path, recall scope-race fix, contributor PRs #42/#43/#44, fixes #46–#49 |
406
407
  | **v3.6.14** | Plugin-native | Claude Code Plugin (WP-06), MCP profiles (WP-01), IDE connect (WP-08), asset consolidation, UI polish (WP-12) |
@@ -177,6 +177,7 @@ src/superlocalmemory/hooks/cursor_adapter.py
177
177
  src/superlocalmemory/hooks/hook_daemon.py
178
178
  src/superlocalmemory/hooks/hook_handlers.py
179
179
  src/superlocalmemory/hooks/ide_connector.py
180
+ src/superlocalmemory/hooks/memory_protocol.py
180
181
  src/superlocalmemory/hooks/portable_kit.py
181
182
  src/superlocalmemory/hooks/post_tool_async_hook.py
182
183
  src/superlocalmemory/hooks/post_tool_outcome_hook.py
@@ -434,6 +435,7 @@ src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py
434
435
  src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py
435
436
  src/superlocalmemory/storage/migrations/M015_add_pinned_column.py
436
437
  src/superlocalmemory/storage/migrations/M016_add_scope_support.py
438
+ src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py
437
439
  src/superlocalmemory/storage/migrations/__init__.py
438
440
  src/superlocalmemory/trust/__init__.py
439
441
  src/superlocalmemory/trust/gate.py
@@ -1,22 +0,0 @@
1
- ---
2
- description: Apply SLM context-optimization (compress large output / cache repeats) and report savings.
3
- argument-hint: [stats]
4
- allowed-tools: slm_compress, slm_cache_set, slm_cache_get, slm_optimize_stats, Bash
5
- ---
6
-
7
- Apply SuperLocalMemory context-optimization. Arguments: $ARGUMENTS
8
-
9
- If arguments are empty or "stats":
10
- - Call `slm_optimize_stats()` and report: cache_kv_hits, compress_runs, tokens_saved_compress.
11
-
12
- If there is large output to compress (>2000 chars):
13
- - Call `slm_compress(content=<output>, mode="auto", reversible=True)`.
14
- - Work from the compressed form; retain ccr_id if the result is lossy.
15
-
16
- Rules (apply strictly):
17
- - Rule 6 — NEVER compress/cache: code intended for Edit/Write; JSON being parsed; secrets/keys/tokens; ccr_ids; content <500 chars.
18
- - Rule 8 — FAIL-OPEN: if ok:false, continue with original; do not retry; do not surface the error unless the user asks.
19
-
20
- MCP unavailable → CLI fallback: `slm optimize status`.
21
-
22
- SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
@@ -1,16 +0,0 @@
1
- ---
2
- description: Recall relevant facts and decisions from SuperLocalMemory by query.
3
- argument-hint: <what to recall>
4
- allowed-tools: recall, search, Bash
5
- ---
6
-
7
- Recall from SuperLocalMemory using the query: $ARGUMENTS
8
-
9
- 1. Call `recall(query="$ARGUMENTS", limit=10)` via MCP.
10
- 2. If no confident match or count==0, also call `search("$ARGUMENTS", 10)`.
11
- 3. Present results concisely — fact, tags, importance, date. Never invent or fabricate a memory.
12
- 4. If MCP is unavailable, fall back to CLI:
13
- - `slm recall "$ARGUMENTS" --limit 10`
14
- - then `slm search "$ARGUMENTS"`
15
-
16
- SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
@@ -1,16 +0,0 @@
1
- ---
2
- description: Save an atomic fact or decision to SuperLocalMemory.
3
- argument-hint: <the fact> [#tag1,tag2]
4
- allowed-tools: recall, remember, Bash
5
- ---
6
-
7
- Save to SuperLocalMemory: $ARGUMENTS
8
-
9
- 1. First call `recall("$ARGUMENTS", 5)` — dedupe check. If a near-identical memory exists, tell the user and stop; delegate to slm-memory-advisor to update_memory if a correction is needed.
10
- 2. Extract tags from any trailing `#tag1,tag2` pattern in the arguments.
11
- 3. Determine importance: use 8 for blockers/security/architecture decisions; use 7 for conventions and constraints; use 5 for general facts.
12
- 4. Call `remember(content="$ARGUMENTS", tags=<extracted tags>, importance=<n>)`.
13
- 5. Confirm only on success:true. If success is not true, report the error — never claim "saved."
14
- 6. MCP unavailable → CLI fallback: `slm remember "$ARGUMENTS" --tags <tags>` (note: `--importance` is MCP-only, not a CLI flag).
15
-
16
- SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
@@ -1,15 +0,0 @@
1
- ---
2
- description: Show SuperLocalMemory health and optimization counters.
3
- argument-hint: (no arguments)
4
- allowed-tools: slm_optimize_stats, Bash
5
- ---
6
-
7
- Show SuperLocalMemory status and optimization counters.
8
-
9
- 1. Run `slm status` via Bash — this is the canonical health check (memory count, profile, daemon state, integrity).
10
- 2. Also call `slm_optimize_stats()` via MCP for Surface-B counters (cache_kv_hits, compress_runs, tokens_saved_compress). If ok:false, omit silently — do not surface the error.
11
- 3. Summarize both outputs in a concise report. Flag any integrity warnings from `slm status`.
12
-
13
- Note: MCP get_status is intentionally NOT used here — it is outside the core profile and would error. Use `slm status` (CLI) + `slm_optimize_stats` (MCP) only.
14
-
15
- SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later