superlocalmemory 3.6.17 → 3.6.19

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 (43) hide show
  1. package/README.md +2 -2
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/plugin/CLAUDE.md +3 -3
  5. package/plugin/agents/slm-memory-advisor.md +1 -1
  6. package/plugin/agents/slm-optimize-advisor.md +1 -1
  7. package/plugin/hooks/hooks.json +9 -0
  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/hooks/hooks.json +9 -0
  19. package/plugin-src/manifest.json +1 -1
  20. package/plugin-src/requirements.txt +1 -1
  21. package/plugin-src/rules/AGENTS.md +1 -1
  22. package/plugin-src/rules/CLAUDE.md.fragment +3 -3
  23. package/plugin-src/skills/slm-cache/SKILL.md +1 -1
  24. package/plugin-src/skills/slm-compress/SKILL.md +1 -1
  25. package/plugin-src/skills/slm-graph/SKILL.md +1 -1
  26. package/plugin-src/skills/slm-recall/SKILL.md +1 -1
  27. package/plugin-src/skills/slm-remember/SKILL.md +1 -1
  28. package/plugin-src/skills/slm-session/SKILL.md +1 -1
  29. package/plugin-src/skills/slm-status/SKILL.md +1 -1
  30. package/pyproject.toml +3 -2
  31. package/scripts/build-plugin.js +1 -1
  32. package/scripts/postinstall-interactive.js +94 -7
  33. package/src/superlocalmemory/__init__.py +1 -1
  34. package/src/superlocalmemory/cli/setup_wizard.py +34 -0
  35. package/src/superlocalmemory/hooks/claude_code_hooks.py +40 -4
  36. package/src/superlocalmemory/hooks/hook_handlers.py +33 -0
  37. package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +79 -0
  38. package/src/superlocalmemory.egg-info/PKG-INFO +3 -3
  39. package/src/superlocalmemory.egg-info/SOURCES.txt +1 -0
  40. package/plugin-src/commands/slm-optimize.md +0 -22
  41. package/plugin-src/commands/slm-recall.md +0 -16
  42. package/plugin-src/commands/slm-remember.md +0 -16
  43. package/plugin-src/commands/slm-status.md +0 -15
package/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
  <img src="https://superlocalmemory.com/assets/logo-mark.png" alt="SuperLocalMemory" width="200"/>
3
3
  </p>
4
4
 
5
- <h1 align="center">SuperLocalMemory V3.6.17</h1>
5
+ <h1 align="center">SuperLocalMemory V3.6.18</h1>
6
6
  <p align="center"><strong>Cache. Compress. Remember. Three surfaces — proxy, MCP tools, or skill. Every setup covered.</strong><br/>
7
7
  <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>
8
- <p align="center"><code>v3.6.17</code> — <strong>Plugin-native. Profile-aware. Distributed-ready.</strong><br/>
8
+ <p align="center"><code>v3.6.18</code> — <strong>Plugin-native. Profile-aware. Distributed-ready.</strong><br/>
9
9
  Proxy: <code>slm wrap claude</code> &nbsp;·&nbsp; MCP: add <code>slm_compress</code> to your config &nbsp;·&nbsp; Skill: zero-config</p>
10
10
  <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>
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "3.6.17",
3
+ "version": "3.6.19",
4
4
  "description": "Information-geometric agent memory with mathematical guarantees. 4-channel retrieval, Fisher-Rao similarity, zero-LLM mode, EU AI Act compliant. Works with Claude, Cursor, Windsurf, and 17+ AI tools.",
5
5
  "keywords": [
6
6
  "ai-memory",
@@ -16,5 +16,5 @@
16
16
  "mcpServers": "./.mcp.json",
17
17
  "name": "superlocalmemory",
18
18
  "repository": "https://github.com/qualixar/superlocalmemory",
19
- "version": "3.6.17"
19
+ "version": "3.6.19"
20
20
  }
package/plugin/CLAUDE.md CHANGED
@@ -1,4 +1,4 @@
1
- <!-- BEGIN SuperLocalMemory v3.6.17 -->
1
+ <!-- BEGIN SuperLocalMemory v3.6.18 -->
2
2
 
3
3
  ## SuperLocalMemory (SLM) — Agent Rules
4
4
 
@@ -39,6 +39,6 @@ slm-recall · slm-remember · slm-session · slm-status · slm-cache · slm-comp
39
39
  ### Subagents
40
40
  slm-memory-advisor (memory decisions, session hygiene) · slm-optimize-advisor (context compression + KV cache)
41
41
 
42
- <!-- END SuperLocalMemory v3.6.17 -->
42
+ <!-- END SuperLocalMemory v3.6.18 -->
43
43
 
44
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
44
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -41,4 +41,4 @@ recall→`slm recall "<q>" --limit N` (add `--include-global`/`--include-shared`
41
41
  # What NOT to do
42
42
  Never session_init twice; never forget dry_run=False without reporting preview; never dump a whole file into remember; never invent a memory; never claim "saved" without success:true / clean CLI exit.
43
43
 
44
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
44
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -35,4 +35,4 @@ stats→`slm optimize status`/`savings` · compress→`slm compress` · cache→
35
35
  # What NOT to do
36
36
  Never compress code-for-edit/JSON-to-parse/<500 chars; never store secrets/ccr_ids; never let optimize failure block/alter the task; never claim a specific savings %.
37
37
 
38
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
38
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "hooks": {
3
3
  "SessionStart": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "slm hook mandate 2>/dev/null || true",
9
+ "timeout": 5000
10
+ }
11
+ ]
12
+ },
4
13
  {
5
14
  "hooks": [
6
15
  {
@@ -1 +1 @@
1
- superlocalmemory==3.6.17
1
+ superlocalmemory==3.6.19
@@ -137,4 +137,4 @@ These subcommands control daemon-level cache settings. They do not read or write
137
137
 
138
138
  ---
139
139
 
140
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
140
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -140,4 +140,4 @@ Content over 1 MB (1 000 000 bytes UTF-8) is processed but `reversible` is force
140
140
 
141
141
  ---
142
142
 
143
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
143
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -297,4 +297,4 @@ Without this, the six graph tools are not registered and will appear as unknown
297
297
 
298
298
  ---
299
299
 
300
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
300
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -201,4 +201,4 @@ trusts that what you surface came from the store.
201
201
 
202
202
  ---
203
203
 
204
- *SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later*
204
+ *SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later*
@@ -191,4 +191,4 @@ slm remember "<content>" --scope shared --shared-with alice,bob
191
191
 
192
192
  ---
193
193
 
194
- *SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later*
194
+ *SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later*
@@ -204,4 +204,4 @@ slm doctor [--json] # preflight check including daemon and embedding worker
204
204
 
205
205
  ---
206
206
 
207
- *SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later*
207
+ *SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later*
@@ -146,4 +146,4 @@ Note: the `slm optimize` subcommands have known pre-existing parse-test failures
146
146
 
147
147
  ---
148
148
 
149
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
149
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -41,4 +41,4 @@ recall→`slm recall "<q>" --limit N` (add `--include-global`/`--include-shared`
41
41
  # What NOT to do
42
42
  Never session_init twice; never forget dry_run=False without reporting preview; never dump a whole file into remember; never invent a memory; never claim "saved" without success:true / clean CLI exit.
43
43
 
44
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
44
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -35,4 +35,4 @@ stats→`slm optimize status`/`savings` · compress→`slm compress` · cache→
35
35
  # What NOT to do
36
36
  Never compress code-for-edit/JSON-to-parse/<500 chars; never store secrets/ccr_ids; never let optimize failure block/alter the task; never claim a specific savings %.
37
37
 
38
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
38
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "hooks": {
3
3
  "SessionStart": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "slm hook mandate 2>/dev/null || true",
9
+ "timeout": 5000
10
+ }
11
+ ]
12
+ },
4
13
  {
5
14
  "hooks": [
6
15
  {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.6.17",
2
+ "version": "3.6.19",
3
3
  "pluginName": "superlocalmemory",
4
4
  "displayName": "SuperLocalMemory",
5
5
  "repository": "https://github.com/qualixar/superlocalmemory",
@@ -1 +1 @@
1
- superlocalmemory==3.6.17
1
+ superlocalmemory==3.6.19
@@ -88,4 +88,4 @@ When the SLM MCP server is unavailable, use these CLI equivalents:
88
88
  | `slm_cache_get` | `key` | KV cache get; returns hit, value |
89
89
  | `slm_optimize_stats` | `()` | Returns compress_runs, tokens_saved_compress, cache_kv_hits |
90
90
 
91
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
91
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -1,4 +1,4 @@
1
- <!-- BEGIN SuperLocalMemory v3.6.17 -->
1
+ <!-- BEGIN SuperLocalMemory v3.6.18 -->
2
2
 
3
3
  ## SuperLocalMemory (SLM) — Agent Rules
4
4
 
@@ -39,6 +39,6 @@ slm-recall · slm-remember · slm-session · slm-status · slm-cache · slm-comp
39
39
  ### Subagents
40
40
  slm-memory-advisor (memory decisions, session hygiene) · slm-optimize-advisor (context compression + KV cache)
41
41
 
42
- <!-- END SuperLocalMemory v3.6.17 -->
42
+ <!-- END SuperLocalMemory v3.6.18 -->
43
43
 
44
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
44
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -137,4 +137,4 @@ These subcommands control daemon-level cache settings. They do not read or write
137
137
 
138
138
  ---
139
139
 
140
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
140
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -140,4 +140,4 @@ Content over 1 MB (1 000 000 bytes UTF-8) is processed but `reversible` is force
140
140
 
141
141
  ---
142
142
 
143
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
143
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -297,4 +297,4 @@ Without this, the six graph tools are not registered and will appear as unknown
297
297
 
298
298
  ---
299
299
 
300
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
300
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
@@ -201,4 +201,4 @@ trusts that what you surface came from the store.
201
201
 
202
202
  ---
203
203
 
204
- *SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later*
204
+ *SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later*
@@ -191,4 +191,4 @@ slm remember "<content>" --scope shared --shared-with alice,bob
191
191
 
192
192
  ---
193
193
 
194
- *SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later*
194
+ *SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later*
@@ -204,4 +204,4 @@ slm doctor [--json] # preflight check including daemon and embedding worker
204
204
 
205
205
  ---
206
206
 
207
- *SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later*
207
+ *SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later*
@@ -146,4 +146,4 @@ Note: the `slm optimize` subcommands have known pre-existing parse-test failures
146
146
 
147
147
  ---
148
148
 
149
- SuperLocalMemory v3.6.17 · Qualixar · AGPL-3.0-or-later
149
+ SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "superlocalmemory"
3
- version = "3.6.17"
3
+ version = "3.6.19"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "AGPL-3.0-or-later"}
@@ -146,8 +146,9 @@ superlocalmemory = ["ui/**/*"]
146
146
  [tool.pytest.ini_options]
147
147
  testpaths = ["tests"]
148
148
  pythonpath = ["src"]
149
- addopts = "-m 'not slow and not ollama and not benchmark'"
149
+ addopts = "-p no:cacheprovider -p no:subtests -m 'not slow and not ollama and not benchmark'"
150
150
  asyncio_mode = "auto"
151
+ faulthandler_timeout = 0
151
152
  markers = [
152
153
  "slow: marks tests as slow — real engine/model loading (run with: pytest -m slow)",
153
154
  "ollama: marks tests that require a running Ollama instance",
@@ -30,7 +30,7 @@ import process from 'node:process';
30
30
  // ---------------------------------------------------------------------------
31
31
  // Constants
32
32
  // ---------------------------------------------------------------------------
33
- const VERSION = '3.6.17';
33
+ const VERSION = '3.6.19';
34
34
  const MANIFEST_REL = 'plugin-src/manifest.json';
35
35
  const GENERATED_BANNER = `# _GENERATED — DO NOT HAND-EDIT
36
36
 
@@ -489,19 +489,99 @@ async function runInteractiveFlow(rl, recommendedProfile) {
489
489
  // under 60 LOC per Stage-8 G2 scope.
490
490
  function printLivingBrainDelta() {
491
491
  console.log('');
492
- console.log('What\'s new in v3.4.21 FINAL:');
493
- console.log(' + Engagement reward model (action_outcomes populated)');
494
- console.log(' + Online LightGBM retrain (shadow-tested, auto-rollback)');
495
- console.log(' + Real consolidation (hnswlib, reversible merges)');
496
- console.log(' + Inline entity detection (<2 ms trigram lookup)');
497
- console.log(' + Opt-in skill evolution (Haiku 4.5 default)');
498
- console.log(' + Evo-Memory public benchmark');
492
+ console.log('What\'s new in v3.6.18:');
493
+ console.log(' + session_init mandate hook Claude calls ToolSearch→session_init first, every session');
494
+ console.log(' + Plugin auto-install on npm/pip install — skills, agents, hooks wired automatically');
495
+ console.log(' + M017 migration — ccq_consolidated_blocks gets scope column (no more silent CCQ scope drop)');
496
+ console.log(' + GC-safe test flags baked into pyproject.toml + Makefile (no more macOS ARM SIGSEGV)');
499
497
  console.log('What\'s unchanged:');
500
498
  console.log(' * Your memory.db — zero deletes, zero rewrites');
501
499
  console.log(' * Your profile settings');
502
500
  console.log(' * All CLI commands you already use');
503
501
  }
504
502
 
503
+ // T1-B: Auto-install the Claude Code plugin after pip/npm install.
504
+ // Best-effort: never fails the installer, never blocks the main flow.
505
+ // Checks for `claude` CLI, then runs:
506
+ // 1. claude plugin marketplace add qualixar/superlocalmemory
507
+ // 2. claude plugin install superlocalmemory@qualixar
508
+ // 3. slm hooks install
509
+ async function tryInstallClaudePlugin() {
510
+ const { execFile } = require('child_process');
511
+ const { promisify } = require('util');
512
+ const execFileAsync = promisify(execFile);
513
+
514
+ // Find claude binary — try PATH first, then common install locations.
515
+ const claudeCandidates = ['claude'];
516
+ if (process.platform !== 'win32') {
517
+ claudeCandidates.push(
518
+ '/usr/local/bin/claude',
519
+ process.env.HOME + '/.npm-global/bin/claude',
520
+ process.env.HOME + '/.local/bin/claude',
521
+ );
522
+ }
523
+
524
+ let claudeBin = null;
525
+ for (const candidate of claudeCandidates) {
526
+ try {
527
+ await execFileAsync(candidate, ['--version'], { timeout: 5000 });
528
+ claudeBin = candidate;
529
+ break;
530
+ } catch (_e) { /* keep looking */ }
531
+ }
532
+
533
+ if (!claudeBin) {
534
+ // Claude Code not installed — print guidance and skip.
535
+ console.log('SLM: Claude Code CLI not found — skipping plugin auto-install.');
536
+ console.log('SLM: To install the plugin manually after installing Claude Code:');
537
+ console.log('SLM: claude plugin marketplace add qualixar/superlocalmemory');
538
+ console.log('SLM: claude plugin install superlocalmemory@qualixar');
539
+ console.log('SLM: slm hooks install');
540
+ return;
541
+ }
542
+
543
+ console.log('SLM: Claude Code found — installing SLM plugin...');
544
+
545
+ // Step 1: Add marketplace
546
+ try {
547
+ await execFileAsync(claudeBin,
548
+ ['plugin', 'marketplace', 'add', 'qualixar/superlocalmemory'],
549
+ { timeout: 30000 });
550
+ console.log('SLM: marketplace added (qualixar/superlocalmemory)');
551
+ } catch (e) {
552
+ // "already exists" or network error — not fatal
553
+ console.log('SLM: marketplace add note: ' + (e.stderr || e.message || String(e)).trim().split('\n')[0]);
554
+ }
555
+
556
+ // Step 2: Install plugin
557
+ try {
558
+ await execFileAsync(claudeBin,
559
+ ['plugin', 'install', 'superlocalmemory@qualixar'],
560
+ { timeout: 30000 });
561
+ console.log('SLM: plugin installed (superlocalmemory@qualixar)');
562
+ } catch (e) {
563
+ console.log('SLM: plugin install note: ' + (e.stderr || e.message || String(e)).trim().split('\n')[0]);
564
+ }
565
+
566
+ // Step 3: Install hooks (only if not already current — avoids needless writes)
567
+ // `slm hooks install` uses atomic tmp-then-rename and only touches the SLM
568
+ // section of settings.json; all other Claude Code settings are preserved.
569
+ try {
570
+ const statusResult = await execFileAsync('slm', ['hooks', 'status', '--json'],
571
+ { timeout: 10000 }).catch(() => null);
572
+ const alreadyCurrent = statusResult &&
573
+ (() => { try { const s = JSON.parse(statusResult.stdout); return s.installed && !s.needs_upgrade; } catch { return false; } })();
574
+ if (!alreadyCurrent) {
575
+ await execFileAsync('slm', ['hooks', 'install'], { timeout: 15000 });
576
+ console.log('SLM: hooks installed into Claude Code settings');
577
+ } else {
578
+ console.log('SLM: hooks already current — skipped');
579
+ }
580
+ } catch (e) {
581
+ console.log('SLM: hooks install note: ' + (e.stderr || e.message || String(e)).trim().split('\n')[0]);
582
+ }
583
+ }
584
+
505
585
  function printFirstRunChecklist(config) {
506
586
  console.log('');
507
587
  console.log('SuperLocalMemory is configured.');
@@ -692,6 +772,13 @@ async function main() {
692
772
 
693
773
  // UX-G2: show the one-screen delta banner so upgraders see what shipped.
694
774
  printLivingBrainDelta();
775
+
776
+ // T1-B: Auto-install Claude Code plugin + hooks. Best-effort, non-blocking.
777
+ // Only runs on npm install (not --dry-run), when claude CLI is present.
778
+ if (!args.dryRun) {
779
+ await tryInstallClaudePlugin();
780
+ }
781
+
695
782
  printFirstRunChecklist(config);
696
783
  return 0;
697
784
  }
@@ -32,7 +32,7 @@ if "OMP_NUM_THREADS" not in os.environ:
32
32
  os.environ["OMP_NUM_THREADS"] = "2"
33
33
  # ---------------------------------------------------------------------------
34
34
 
35
- __version__ = "3.6.17"
35
+ __version__ = "3.6.19"
36
36
 
37
37
  _REQUIRED_VERSIONS = {
38
38
  "sentence_transformers": "5.3.0",
@@ -789,6 +789,40 @@ def _maybe_install_hooks_on_first_use() -> None:
789
789
  # Best-effort: parity-fallback, never block CLI.
790
790
  pass
791
791
 
792
+ # T1-B: Auto-install Claude Code plugin (skills, agents, hooks).
793
+ # Runs after hooks install, best-effort — never blocks CLI startup.
794
+ _try_install_claude_plugin()
795
+
796
+
797
+ def _try_install_claude_plugin() -> None:
798
+ """Auto-install the Claude Code plugin on first pip/uvx SLM install.
799
+
800
+ Runs ``claude plugin marketplace add qualixar/superlocalmemory`` then
801
+ ``claude plugin install superlocalmemory@qualixar`` if the ``claude``
802
+ CLI is found in PATH. Silent on any error — plugin install is a
803
+ convenience, not a hard requirement for SLM to function.
804
+ """
805
+ import shutil
806
+ import subprocess
807
+
808
+ claude = shutil.which("claude")
809
+ if not claude:
810
+ return # Claude Code not in PATH — skip silently
811
+
812
+ _run = lambda cmd: subprocess.run( # noqa: E731
813
+ cmd, capture_output=True, timeout=30, check=False
814
+ )
815
+
816
+ try:
817
+ _run([claude, "plugin", "marketplace", "add", "qualixar/superlocalmemory"])
818
+ except Exception:
819
+ pass
820
+
821
+ try:
822
+ _run([claude, "plugin", "install", "superlocalmemory@qualixar"])
823
+ except Exception:
824
+ pass
825
+
792
826
 
793
827
  # ---------------------------------------------------------------------------
794
828
  # Mode C provider config (preserved from original)
@@ -21,6 +21,7 @@ from __future__ import annotations
21
21
 
22
22
  import json
23
23
  import logging
24
+ import os
24
25
  import sys
25
26
  import tempfile
26
27
  from pathlib import Path
@@ -31,7 +32,7 @@ CLAUDE_SETTINGS = Path.home() / ".claude" / "settings.json"
31
32
  VERSION_DIR = Path.home() / ".superlocalmemory" / "hooks"
32
33
  VERSION_FILE = VERSION_DIR / ".version"
33
34
  DISABLED_FILE = VERSION_DIR / ".hooks-disabled"
34
- HOOKS_VERSION = "3.4.43"
35
+ HOOKS_VERSION = "3.6.18"
35
36
 
36
37
  # Cross-platform temp dir and marker paths
37
38
  _TMP = tempfile.gettempdir()
@@ -92,6 +93,19 @@ def _hook_definitions(include_gate: bool = False) -> dict[str, list]:
92
93
  """
93
94
  defs: dict[str, list] = {
94
95
  "SessionStart": [
96
+ # v3.6.18: mandate fires FIRST so session_init is never skipped.
97
+ # mcp__superlocalmemory__session_init is DEFERRED — Claude must call
98
+ # ToolSearch before it can invoke the tool. Without this hook,
99
+ # Claude responds before loading the schema → no 6-channel memory.
100
+ {
101
+ "hooks": [
102
+ {
103
+ "type": "command",
104
+ "command": _wrap_python_cmd("mandate"),
105
+ "timeout": 5000,
106
+ }
107
+ ]
108
+ },
95
109
  {
96
110
  "hooks": [
97
111
  {
@@ -100,7 +114,7 @@ def _hook_definitions(include_gate: bool = False) -> dict[str, list]:
100
114
  "timeout": 15000,
101
115
  }
102
116
  ]
103
- }
117
+ },
104
118
  ],
105
119
  "PostToolUse": [
106
120
  {
@@ -278,9 +292,31 @@ def _read_settings() -> dict:
278
292
 
279
293
 
280
294
  def _write_settings(settings: dict) -> None:
281
- """Write settings.json with pretty formatting."""
295
+ """Write settings.json atomically tmp file + rename.
296
+
297
+ Direct .write_text() would truncate the file on a crash mid-write,
298
+ destroying the user's entire Claude Code configuration. The tmp-then-rename
299
+ pattern is atomic on POSIX (os.replace) and near-atomic on Windows: either
300
+ the full new content lands or the original file is untouched.
301
+
302
+ Never overwrites non-SLM settings — _merge_hooks() guarantees that only
303
+ the SLM hooks entries change; all other keys are preserved from the read.
304
+ """
282
305
  CLAUDE_SETTINGS.parent.mkdir(parents=True, exist_ok=True)
283
- CLAUDE_SETTINGS.write_text(json.dumps(settings, indent=2) + "\n")
306
+ content = json.dumps(settings, indent=2) + "\n"
307
+ # Write to a sibling tmp file in the same directory so os.replace is atomic
308
+ # (cross-device rename would fail; same-dir rename is guaranteed atomic).
309
+ tmp_path = CLAUDE_SETTINGS.with_suffix(".json.slm_tmp")
310
+ try:
311
+ tmp_path.write_text(content, encoding="utf-8")
312
+ os.replace(tmp_path, CLAUDE_SETTINGS)
313
+ except Exception:
314
+ # Best-effort cleanup of the tmp file on failure
315
+ try:
316
+ tmp_path.unlink(missing_ok=True)
317
+ except Exception:
318
+ pass
319
+ raise
284
320
 
285
321
 
286
322
  # ---------------------------------------------------------------------------
@@ -120,6 +120,7 @@ def handle_hook(action: str) -> None:
120
120
  sys.exit(_main())
121
121
 
122
122
  handlers = {
123
+ "mandate": _hook_mandate,
123
124
  "start": _hook_start,
124
125
  "gate": _hook_gate,
125
126
  "init-done": _hook_init_done,
@@ -167,6 +168,38 @@ def _launch_post_session_evolution(
167
168
  )
168
169
 
169
170
 
171
+ # ---------------------------------------------------------------------------
172
+ # 0. MANDATE — first SessionStart hook; fires before start
173
+ # ---------------------------------------------------------------------------
174
+
175
+ _MANDATE_TEXT = """<MANDATORY_SESSION_INIT>
176
+ BEFORE writing any text or calling any other tool, you MUST execute these two steps in order:
177
+
178
+ STEP 1 — Load schema:
179
+ Call ToolSearch with query: "select:mcp__superlocalmemory__session_init"
180
+
181
+ STEP 2 — Initialize memory brain:
182
+ Call mcp__superlocalmemory__session_init with:
183
+ project_path = your current working directory
184
+ query = a short description of the session topic (derive from user's first message)
185
+
186
+ This is non-negotiable. SLM is the brain. Without session_init, you have no 6-channel memory context (Ebbinghaus decay, entity graph, FSRS, spreading activation all go cold).
187
+ DO NOT output any text until session_init has completed.
188
+ </MANDATORY_SESSION_INIT>"""
189
+
190
+
191
+ def _hook_mandate() -> None:
192
+ """Print the session_init mandate. MUST be the FIRST SessionStart hook.
193
+
194
+ mcp__superlocalmemory__session_init is DEFERRED at session start — Claude
195
+ cannot call it without ToolSearch first loading the schema. This hook
196
+ fires before `slm hook start` and injects the two-step protocol into the
197
+ system-reminder block so Claude's first action is always ToolSearch →
198
+ session_init, not a text response with no memory context.
199
+ """
200
+ print(_MANDATE_TEXT)
201
+
202
+
170
203
  # ---------------------------------------------------------------------------
171
204
  # 1. SESSION START — SessionStart hook
172
205
  # ---------------------------------------------------------------------------
@@ -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.17
3
+ Version: 3.6.19
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.17</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.17</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
 
@@ -435,6 +435,7 @@ src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py
435
435
  src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py
436
436
  src/superlocalmemory/storage/migrations/M015_add_pinned_column.py
437
437
  src/superlocalmemory/storage/migrations/M016_add_scope_support.py
438
+ src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py
438
439
  src/superlocalmemory/storage/migrations/__init__.py
439
440
  src/superlocalmemory/trust/__init__.py
440
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.17 · 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.17 · 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.17 · 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.17 · Qualixar · AGPL-3.0-or-later