superlocalmemory 3.6.13 → 3.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +17 -0
- package/README.md +187 -741
- package/package.json +12 -5
- package/plugin/.claude-plugin/plugin.json +20 -0
- package/plugin/.mcp.json +12 -0
- package/plugin/CLAUDE.md +43 -0
- package/plugin/_GENERATED.md +6 -0
- package/plugin/agents/slm-memory-advisor.md +43 -0
- package/plugin/agents/slm-optimize-advisor.md +38 -0
- package/plugin/hooks/hooks.json +14 -0
- package/plugin/requirements.txt +1 -0
- package/plugin/scripts/ensure-venv.bat +122 -0
- package/plugin/scripts/ensure-venv.sh +105 -0
- package/plugin/scripts/slm-launch +15 -0
- package/plugin/scripts/slm-launch.bat +17 -0
- package/plugin/settings.json +16 -0
- package/plugin/skills/slm-cache/SKILL.md +140 -0
- package/plugin/skills/slm-compress/SKILL.md +143 -0
- package/plugin/skills/slm-graph/SKILL.md +300 -0
- package/plugin/skills/slm-recall/SKILL.md +196 -0
- package/plugin/skills/slm-remember/SKILL.md +182 -0
- package/plugin/skills/slm-session/SKILL.md +207 -0
- package/plugin/skills/slm-status/SKILL.md +149 -0
- package/plugin-src/.mcp.json +12 -0
- package/plugin-src/agents/slm-memory-advisor.md +43 -0
- package/plugin-src/agents/slm-optimize-advisor.md +38 -0
- package/plugin-src/commands/slm-optimize.md +22 -0
- package/plugin-src/commands/slm-recall.md +16 -0
- package/plugin-src/commands/slm-remember.md +16 -0
- package/plugin-src/commands/slm-status.md +15 -0
- package/plugin-src/hooks/.gitkeep +0 -0
- package/plugin-src/hooks/hooks.json +14 -0
- package/plugin-src/manifest.json +25 -0
- package/plugin-src/requirements.txt +1 -0
- package/plugin-src/rules/AGENTS.md +90 -0
- package/plugin-src/rules/CLAUDE.md.fragment +43 -0
- package/plugin-src/scripts/ensure-venv.bat +122 -0
- package/plugin-src/scripts/ensure-venv.sh +105 -0
- package/plugin-src/scripts/slm-launch +15 -0
- package/plugin-src/scripts/slm-launch.bat +17 -0
- package/plugin-src/settings.json +16 -0
- package/plugin-src/skills/slm-cache/SKILL.md +140 -0
- package/plugin-src/skills/slm-compress/SKILL.md +143 -0
- package/plugin-src/skills/slm-graph/SKILL.md +300 -0
- package/plugin-src/skills/slm-recall/SKILL.md +196 -0
- package/plugin-src/skills/slm-remember/SKILL.md +182 -0
- package/plugin-src/skills/slm-session/SKILL.md +207 -0
- package/plugin-src/skills/slm-status/SKILL.md +149 -0
- package/pyproject.toml +6 -2
- package/scripts/__tests__/build-plugin.test.mjs +613 -0
- package/scripts/_savings_math.py +270 -0
- package/scripts/build-plugin.js +742 -0
- package/scripts/dogfood_savings.py +490 -0
- package/scripts/install-skills.ps1 +4 -334
- package/scripts/install-skills.sh +4 -435
- package/scripts/postinstall-interactive.js +0 -27
- package/scripts/postinstall.js +21 -2
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/_lazy_init.py +115 -0
- package/src/superlocalmemory/cli/commands.py +348 -39
- package/src/superlocalmemory/cli/main.py +47 -4
- package/src/superlocalmemory/cli/setup_wizard.py +20 -6
- package/src/superlocalmemory/core/config.py +79 -9
- package/src/superlocalmemory/core/embeddings.py +10 -5
- package/src/superlocalmemory/core/engine.py +2 -2
- package/src/superlocalmemory/hooks/claude_code_hooks.py +27 -3
- package/src/superlocalmemory/hooks/portable_kit.py +506 -0
- package/src/superlocalmemory/infra/cloud_backup.py +99 -23
- package/src/superlocalmemory/mcp/cli_fallback.py +602 -0
- package/src/superlocalmemory/mcp/server.py +75 -4
- package/src/superlocalmemory/mcp/tools_code_graph.py +3 -3
- package/src/superlocalmemory/mcp/tools_core.py +12 -4
- package/src/superlocalmemory/optimize/cache/boundary_store.py +25 -6
- package/src/superlocalmemory/optimize/cache/centroid_store.py +27 -4
- package/src/superlocalmemory/optimize/cache/manager.py +92 -6
- package/src/superlocalmemory/optimize/cache/semantic.py +20 -1
- package/src/superlocalmemory/optimize/compress/ccr.py +12 -0
- package/src/superlocalmemory/optimize/compress/router.py +46 -13
- package/src/superlocalmemory/optimize/config/schema.py +6 -0
- package/src/superlocalmemory/optimize/proxy/_helpers.py +111 -8
- package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +14 -4
- package/src/superlocalmemory/optimize/proxy/gemini_surface.py +23 -6
- package/src/superlocalmemory/optimize/proxy/openai_surface.py +10 -4
- package/src/superlocalmemory/optimize/proxy/server.py +11 -0
- package/src/superlocalmemory/optimize/proxy/vertex_surface.py +246 -0
- package/src/superlocalmemory/optimize/storage/db.py +30 -0
- package/src/superlocalmemory/server/recall_serializer.py +3 -1
- package/src/superlocalmemory/server/unified_daemon.py +24 -6
- package/src/superlocalmemory/ui/css/legacy-dashboard.css +18 -0
- package/src/superlocalmemory/ui/css/neural-glass.css +5 -0
- package/src/superlocalmemory/ui/index.html +2 -2
- package/src/superlocalmemory/ui/js/core.js +98 -0
- package/src/superlocalmemory/ui/js/dashboard.js +8 -1
- package/src/superlocalmemory/ui/js/ide-status.js +16 -3
- package/src/superlocalmemory/ui/js/math-health.js +15 -3
- package/src/superlocalmemory/ui/js/optimize.js +18 -2
- package/src/superlocalmemory/ui/js/trust-dashboard.js +10 -1
- package/src/superlocalmemory.egg-info/PKG-INFO +189 -742
- package/src/superlocalmemory.egg-info/SOURCES.txt +6 -9
- package/src/superlocalmemory.egg-info/requires.txt +1 -0
- package/ide/skills/slm-build-graph/SKILL.md +0 -423
- package/ide/skills/slm-list-recent/SKILL.md +0 -348
- package/ide/skills/slm-recall/SKILL.md +0 -326
- package/ide/skills/slm-remember/SKILL.md +0 -194
- package/ide/skills/slm-show-patterns/SKILL.md +0 -224
- package/ide/skills/slm-status/SKILL.md +0 -363
- package/ide/skills/slm-switch-profile/SKILL.md +0 -442
- package/skills/slm-build-graph/SKILL.md +0 -423
- package/skills/slm-list-recent/SKILL.md +0 -348
- package/skills/slm-optimize/README.md +0 -55
- package/skills/slm-optimize/SKILL.md +0 -139
- package/skills/slm-recall/SKILL.md +0 -343
- package/skills/slm-remember/SKILL.md +0 -194
- package/skills/slm-show-patterns/SKILL.md +0 -224
- package/skills/slm-status/SKILL.md +0 -363
- package/skills/slm-switch-profile/SKILL.md +0 -442
- package/src/superlocalmemory/cli/doctor_cmd.py +0 -152
- package/src/superlocalmemory/skills/slm-build-graph/SKILL.md +0 -423
- package/src/superlocalmemory/skills/slm-list-recent/SKILL.md +0 -348
- package/src/superlocalmemory/skills/slm-recall/SKILL.md +0 -343
- package/src/superlocalmemory/skills/slm-remember/SKILL.md +0 -194
- package/src/superlocalmemory/skills/slm-show-patterns/SKILL.md +0 -224
- package/src/superlocalmemory/skills/slm-status/SKILL.md +0 -363
- package/src/superlocalmemory/skills/slm-switch-profile/SKILL.md +0 -442
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-compress
|
|
3
|
+
description: Compress large text, tool output, or transcripts to reduce context-window usage while keeping the full 1M window intact — call slm_compress(content, mode, reversible, ttl_seconds) to shrink content; if the result is lossy a ccr_id is returned so you can call slm_retrieve(ccr_id) later to recover the exact original; always fail-open (ok:false → continue with the original).
|
|
4
|
+
when_to_use: "compress context, shrink output, save tokens, context window full, long transcript, compress tool result, reduce tokens, large output, compress text"
|
|
5
|
+
allowed-tools: slm_compress, slm_retrieve, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# slm-compress — Reversible Context Compression (Surface B)
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
When a tool output, transcript, or accumulated context grows large enough to crowd out working space, `slm_compress` reduces it in-place. The compressed form is used for the remainder of the session; the exact original is recoverable on demand via `slm_retrieve`. This works without a proxy and without touching `ANTHROPIC_BASE_URL`, so the full 1M context window is never sacrificed.
|
|
13
|
+
|
|
14
|
+
## Primary MCP Tool: slm_compress
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
slm_compress(
|
|
18
|
+
content: str, # required — text to compress (max 1 MB)
|
|
19
|
+
mode: str = "auto", # "normalize" | "auto" | "aggressive"
|
|
20
|
+
reversible: bool = True, # store original in CCR for later retrieval
|
|
21
|
+
ttl_seconds: int = 86400, # CCR lifetime in seconds (default 24 h)
|
|
22
|
+
) -> dict
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Return dict (all keys always present)
|
|
26
|
+
|
|
27
|
+
| Key | Type | Meaning |
|
|
28
|
+
|-----|------|---------|
|
|
29
|
+
| `ok` | bool | `True` on success; `False` on internal error or empty input |
|
|
30
|
+
| `compressed` | str | Compressed text (or original on failure) |
|
|
31
|
+
| `strategy` | str | Which strategy was applied (e.g. `"normalize"`, `"none"`) |
|
|
32
|
+
| `tokens_before` | int | Word-count estimate of the input |
|
|
33
|
+
| `tokens_after` | int | Word-count estimate of the output |
|
|
34
|
+
| `ratio` | float | `tokens_after / tokens_before` (lower = more compact) |
|
|
35
|
+
| `lossy` | bool | Whether information was removed |
|
|
36
|
+
| `ccr_id` | str \| None | UUID4 session token; present only when `lossy=True` and `reversible=True` |
|
|
37
|
+
| `note` | str \| None | Human-readable note (e.g. warnings, recovery hint) |
|
|
38
|
+
|
|
39
|
+
### Mode semantics (verified from source)
|
|
40
|
+
|
|
41
|
+
- **`"normalize"`** — lossless whitespace collapse; no daemon dependency; `lossy: false`, `ccr_id: null`.
|
|
42
|
+
- **`"auto"`** — delegates to `CompressRouter`; may be lossy depending on daemon config; default.
|
|
43
|
+
- **`"aggressive"`** — requests aggressive compression from the daemon; daemon must have `compress_mode=aggressive` set in config; note field will warn if daemon config does not match.
|
|
44
|
+
|
|
45
|
+
## Recovery Tool: slm_retrieve
|
|
46
|
+
|
|
47
|
+
When `slm_compress` returns `lossy: true`, the original is stored under the `ccr_id`. Use `slm_retrieve` to get it back:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
slm_retrieve(ccr_id: str) -> dict
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| Key | Type | Meaning |
|
|
54
|
+
|-----|------|---------|
|
|
55
|
+
| `ok` | bool | `True` when content was found |
|
|
56
|
+
| `content` | str \| None | Original text, decoded from UTF-8 (or Latin-1 fallback) |
|
|
57
|
+
| `size_bytes` | int | Byte length of the stored original |
|
|
58
|
+
| `error` | str \| None | Error message on failure; `None` on success |
|
|
59
|
+
|
|
60
|
+
`ccr_id` must be a valid UUID4. Non-UUID4 strings return `ok: false` immediately.
|
|
61
|
+
|
|
62
|
+
### CCR security rule
|
|
63
|
+
|
|
64
|
+
`ccr_id` values are **unguessable session tokens**. Treat them like short-lived credentials:
|
|
65
|
+
- Never log them.
|
|
66
|
+
- Never share them across agents.
|
|
67
|
+
- Never pass them as tool arguments to any tool other than `slm_retrieve`.
|
|
68
|
+
- Never compress a `ccr_id` string itself.
|
|
69
|
+
- They expire after `ttl_seconds` (default 24 h); `slm_retrieve` returns `ok: false` after expiry.
|
|
70
|
+
|
|
71
|
+
## Decision: When to Compress
|
|
72
|
+
|
|
73
|
+
**Compress when:**
|
|
74
|
+
- A single tool output or transcript exceeds approximately 2 000 characters.
|
|
75
|
+
- You are accumulating repeated context (e.g. full file reads across multiple steps).
|
|
76
|
+
- Context is nearing the point where recall quality or response quality degrades.
|
|
77
|
+
|
|
78
|
+
**Do NOT compress:**
|
|
79
|
+
- Code you are about to read, edit, or diff — you need every character.
|
|
80
|
+
- JSON you will parse programmatically — compression may alter structure.
|
|
81
|
+
- Secrets, credentials, or `ccr_id` strings.
|
|
82
|
+
- Anything under ~500 characters — overhead exceeds benefit.
|
|
83
|
+
- The compressed form of content already compressed this session.
|
|
84
|
+
|
|
85
|
+
## Fail-Open Guarantee
|
|
86
|
+
|
|
87
|
+
`slm_compress` never raises an exception. On any internal error it returns:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{ "ok": false, "compressed": "<original input>", "ratio": 1.0, ... }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**When `ok` is `false`, continue with the original content.** Never block a task waiting for compression to succeed.
|
|
94
|
+
|
|
95
|
+
## Worked Example
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
# Step 1: compress a large tool output
|
|
99
|
+
result = await slm_compress(
|
|
100
|
+
content=long_log_text,
|
|
101
|
+
mode="auto",
|
|
102
|
+
reversible=True,
|
|
103
|
+
ttl_seconds=3600,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
if result["ok"]:
|
|
107
|
+
working_text = result["compressed"]
|
|
108
|
+
ccr_id = result["ccr_id"] # None if lossless
|
|
109
|
+
else:
|
|
110
|
+
working_text = long_log_text # fail-open
|
|
111
|
+
ccr_id = None
|
|
112
|
+
|
|
113
|
+
# ... work with working_text ...
|
|
114
|
+
|
|
115
|
+
# Step 2: restore original when needed (e.g. before final summary)
|
|
116
|
+
if ccr_id:
|
|
117
|
+
restore = await slm_retrieve(ccr_id=ccr_id)
|
|
118
|
+
if restore["ok"]:
|
|
119
|
+
original_text = restore["content"]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Secondary CLI (fallback when MCP is unavailable)
|
|
123
|
+
|
|
124
|
+
The `slm compress` subcommand exists but has known pre-existing parse-test failures. Prefer the MCP tools above. If you must use CLI:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
slm compress status [--json]
|
|
128
|
+
slm compress mode safe|aggressive [--json]
|
|
129
|
+
slm compress code on|off [--json]
|
|
130
|
+
slm compress prose on|off [--json]
|
|
131
|
+
slm compress ccr on|off [--json]
|
|
132
|
+
slm compress align on|off [--json]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
These subcommands control daemon-level compression settings — they do not compress content inline. For inline compression, use `slm_compress` via MCP.
|
|
136
|
+
|
|
137
|
+
## Size Cap
|
|
138
|
+
|
|
139
|
+
Content over 1 MB (1 000 000 bytes UTF-8) is processed but `reversible` is forced to `False` and `ccr_id` will be `None`. The `note` field will state `"content over 1MB: ccr skipped"`.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
SuperLocalMemory v3.6.14 · Qualixar · AGPL-3.0-or-later
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-graph
|
|
3
|
+
description: >
|
|
4
|
+
Index and query a codebase as a structural graph — build the code graph, trace blast radius of a
|
|
5
|
+
change, find callers/callees/inheritors, semantic code search by meaning, assemble PR review
|
|
6
|
+
context, and detect what changed since last index. Use when the user asks how code connects, what
|
|
7
|
+
breaks if X changes, what calls a function, what a class inherits from, how to navigate an
|
|
8
|
+
unfamiliar codebase, or to understand risk before editing.
|
|
9
|
+
when_to_use: |
|
|
10
|
+
- what calls X
|
|
11
|
+
- what breaks if I change Y
|
|
12
|
+
- what does Z inherit from
|
|
13
|
+
- find code that handles authentication
|
|
14
|
+
- impact analysis before editing
|
|
15
|
+
- code navigation in unfamiliar repos
|
|
16
|
+
- blast radius before a PR
|
|
17
|
+
- pre-commit change detection
|
|
18
|
+
allowed-tools: build_code_graph, query_graph, get_blast_radius, semantic_search_code, get_review_context, detect_changes, Bash
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# slm-graph — Code Intelligence Skill
|
|
22
|
+
|
|
23
|
+
Index any repo as a code knowledge graph and answer structural questions about it: callers, callees, impact radius, semantic search, and review context. Requires the `code` MCP profile (set `SLM_MCP_PROFILE=code` in your plugin `.mcp.json`).
|
|
24
|
+
|
|
25
|
+
**Prerequisite rule:** every tool except `build_code_graph` self-guards — if the graph is not built it returns `{"success": false, "error": "Code graph not built. Run build_code_graph first."}`. Always index first.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Tool Reference
|
|
30
|
+
|
|
31
|
+
### 1. `build_code_graph` — index a repository
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
build_code_graph(
|
|
35
|
+
repo_path: str,
|
|
36
|
+
languages: str = "",
|
|
37
|
+
exclude_patterns: str = "",
|
|
38
|
+
) -> {success, files_parsed, nodes, edges, flows, communities, duration_ms}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Parses all supported source files, extracts functions/classes/imports, builds the call graph, detects execution flows, and identifies code communities. Replaces any previous index for the same repo.
|
|
42
|
+
|
|
43
|
+
- `repo_path` — absolute path to the repository root. Must exist.
|
|
44
|
+
- `languages` — comma-separated language filter, e.g. `"python,typescript"`. Empty string = index all supported languages.
|
|
45
|
+
- `exclude_patterns` — comma-separated glob patterns to exclude, e.g. `"**/node_modules/**,**/.venv/**"`. Empty = no exclusions.
|
|
46
|
+
|
|
47
|
+
When to (re)build:
|
|
48
|
+
- Before using any other graph tool for the first time on a repo.
|
|
49
|
+
- After significant changes to the codebase (pull, merge, large refactor).
|
|
50
|
+
- When `detect_changes` or `query_graph` returns stale/unexpected results.
|
|
51
|
+
- Rebuild is safe and idempotent — it replaces the previous index atomically per file.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
# Index the full repo
|
|
55
|
+
build_code_graph(repo_path="/abs/path/to/myrepo")
|
|
56
|
+
|
|
57
|
+
# Index only Python, skip tests and generated code
|
|
58
|
+
build_code_graph(
|
|
59
|
+
repo_path="/abs/path/to/myrepo",
|
|
60
|
+
languages="python",
|
|
61
|
+
exclude_patterns="**/tests/**,**/generated/**"
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### 2. `query_graph` — traverse relationships
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
query_graph(
|
|
71
|
+
pattern: str,
|
|
72
|
+
target: str = "",
|
|
73
|
+
limit: int = 20,
|
|
74
|
+
) -> {success, pattern, target, results: [{qualified_name, kind, file_path, name}]}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Query the graph for structural relationships. `pattern` is required and must be one of the eight valid values below. `target` is a qualified name, partial name, or node ID — matched with exact-then-LIKE fallback.
|
|
78
|
+
|
|
79
|
+
Valid patterns:
|
|
80
|
+
|
|
81
|
+
| pattern | returns |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `callers_of` | functions/methods that call `target` |
|
|
84
|
+
| `callees_of` | functions/methods that `target` calls |
|
|
85
|
+
| `imports_of` | modules/symbols that `target` imports |
|
|
86
|
+
| `imported_by` | who imports `target` |
|
|
87
|
+
| `tests_for` | test nodes associated with `target` |
|
|
88
|
+
| `inherits_from` | base classes of `target` |
|
|
89
|
+
| `inherited_by` | subclasses of `target` |
|
|
90
|
+
| `contains` | symbols defined inside `target` (e.g. methods in a class) |
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
# Who calls the auth handler?
|
|
94
|
+
query_graph(pattern="callers_of", target="authenticate_user")
|
|
95
|
+
|
|
96
|
+
# What does the payment processor import?
|
|
97
|
+
query_graph(pattern="imports_of", target="PaymentProcessor", limit=30)
|
|
98
|
+
|
|
99
|
+
# What classes inherit from BaseModel?
|
|
100
|
+
query_graph(pattern="inherited_by", target="BaseModel")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### 3. `get_blast_radius` — impact analysis
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
get_blast_radius(
|
|
109
|
+
changed_files: str,
|
|
110
|
+
max_depth: int = 2,
|
|
111
|
+
max_nodes: int = 500,
|
|
112
|
+
) -> {success, changed_nodes, impacted_nodes, impacted_files, edges, depth_reached, truncated}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Computes the full impact radius for one or more changed files using bidirectional BFS (callers and callees). Returns every node and file reachable within `max_depth` hops. Use this before editing to understand risk surface.
|
|
116
|
+
|
|
117
|
+
- `changed_files` — comma-separated file paths relative to the repo root, e.g. `"src/auth/handler.py,src/auth/models.py"`.
|
|
118
|
+
- `max_depth` — BFS depth. Default 2. Increase to 3–4 for deep call chains; lower to 1 for a quick first-degree check.
|
|
119
|
+
- `max_nodes` — caps the result set. If `truncated=true` in the response, the real blast radius is larger.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
# What breaks if I change the auth handler?
|
|
123
|
+
get_blast_radius(changed_files="src/auth/handler.py")
|
|
124
|
+
|
|
125
|
+
# Deeper analysis across two files
|
|
126
|
+
get_blast_radius(
|
|
127
|
+
changed_files="src/payments/gateway.py,src/payments/models.py",
|
|
128
|
+
max_depth=3,
|
|
129
|
+
max_nodes=200
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If `truncated` is `true`, narrow the scope with `max_nodes` or reduce `max_depth` to get a reliable result.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### 4. `semantic_search_code` — find code by meaning
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
semantic_search_code(
|
|
141
|
+
query: str,
|
|
142
|
+
kind: str = "",
|
|
143
|
+
limit: int = 20,
|
|
144
|
+
) -> {success, results: [{qualified_name, kind, file_path, score, line_start, name}]}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Hybrid FTS5 + vector search over all indexed code entities. Use when you know what the code *does* but not what it's *called*.
|
|
148
|
+
|
|
149
|
+
- `query` — natural language description, e.g. `"retry logic for HTTP requests"` or `"parse JWT token from header"`.
|
|
150
|
+
- `kind` — optional filter: `"Function"`, `"Class"`, `"File"`, or `"Test"`. Empty = all kinds. Case-insensitive match in the engine.
|
|
151
|
+
- `limit` — max results. Default 20.
|
|
152
|
+
|
|
153
|
+
Results include a `score` field (higher = more relevant).
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
# Find where authentication is handled
|
|
157
|
+
semantic_search_code(query="authenticate user from request token")
|
|
158
|
+
|
|
159
|
+
# Find only test functions that cover database writes
|
|
160
|
+
semantic_search_code(query="database write transaction rollback", kind="Test")
|
|
161
|
+
|
|
162
|
+
# Find the rate limiter class
|
|
163
|
+
semantic_search_code(query="rate limiting middleware", kind="Class", limit=5)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
### 5. `get_review_context` — assemble PR review context
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
get_review_context(
|
|
172
|
+
changed_files: str,
|
|
173
|
+
include_source: bool = True,
|
|
174
|
+
) -> {success, summary, review_items, test_gaps, risk_score}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Produces a token-optimized review package for a set of changed files: a plain-language summary, a ranked list of review items with per-node risk scores, and a list of changed symbols that have no associated test coverage.
|
|
178
|
+
|
|
179
|
+
- `changed_files` — comma-separated file paths relative to the repo root.
|
|
180
|
+
- `include_source` — whether to include source code snippets in the context (default `True`). Set `False` to reduce token usage when you only need the risk analysis.
|
|
181
|
+
|
|
182
|
+
`risk_score` is a float 0–1 on the overall changeset. `review_items[].risk_score` is per-node.
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
# Get review context for a PR touching two files
|
|
186
|
+
get_review_context(changed_files="src/auth/handler.py,src/auth/utils.py")
|
|
187
|
+
|
|
188
|
+
# Risk summary only, no source snippets
|
|
189
|
+
get_review_context(
|
|
190
|
+
changed_files="src/payments/gateway.py",
|
|
191
|
+
include_source=False
|
|
192
|
+
)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### 6. `detect_changes` — what changed since last index
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
detect_changes(
|
|
201
|
+
base: str = "HEAD~1",
|
|
202
|
+
) -> {success, summary, risk_score, changed_functions, test_gaps, review_priorities}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Runs `git diff` against `base`, maps the changed hunks to graph nodes, and returns a risk-scored list of changed functions, test gaps, and review priorities. Requires the repo to be a git repository.
|
|
206
|
+
|
|
207
|
+
- `base` — git ref to diff against. Default `"HEAD~1"` (one commit back). Any valid git ref works: `"main"`, `"v3.6.13"`, a commit SHA, etc.
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
# What changed in the last commit?
|
|
211
|
+
detect_changes()
|
|
212
|
+
|
|
213
|
+
# What changed since the release branch?
|
|
214
|
+
detect_changes(base="release/v3.6.13")
|
|
215
|
+
|
|
216
|
+
# What changed relative to main?
|
|
217
|
+
detect_changes(base="main")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Returns `error` if the repo root is not a git repository or if git is not available.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Realistic Workflow
|
|
225
|
+
|
|
226
|
+
### Explore an unfamiliar codebase
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
# 1. Index it
|
|
230
|
+
build_code_graph(repo_path="/abs/path/to/repo")
|
|
231
|
+
|
|
232
|
+
# 2. Find the entry point by meaning
|
|
233
|
+
semantic_search_code(query="request router entry point", kind="Function")
|
|
234
|
+
|
|
235
|
+
# 3. Trace what it calls
|
|
236
|
+
query_graph(pattern="callees_of", target="handle_request")
|
|
237
|
+
|
|
238
|
+
# 4. See who else calls the same core function
|
|
239
|
+
query_graph(pattern="callers_of", target="authenticate_user")
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Before editing a function
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
# 1. Know what you are touching
|
|
246
|
+
semantic_search_code(query="retry HTTP requests with backoff")
|
|
247
|
+
|
|
248
|
+
# 2. Understand blast radius before making the change
|
|
249
|
+
get_blast_radius(changed_files="src/http/client.py")
|
|
250
|
+
|
|
251
|
+
# 3. Check test gaps
|
|
252
|
+
get_review_context(changed_files="src/http/client.py")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Pre-commit / PR review
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
# 1. What changed in this branch vs main?
|
|
259
|
+
detect_changes(base="main")
|
|
260
|
+
|
|
261
|
+
# 2. Full impact analysis for the changed files
|
|
262
|
+
get_blast_radius(changed_files="src/auth/handler.py,src/auth/models.py")
|
|
263
|
+
|
|
264
|
+
# 3. Assemble review context
|
|
265
|
+
get_review_context(changed_files="src/auth/handler.py,src/auth/models.py")
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Error Handling
|
|
271
|
+
|
|
272
|
+
All tools return `{"success": false, "error": "<message>"}` on failure — they never raise.
|
|
273
|
+
|
|
274
|
+
| Error message | Cause | Fix |
|
|
275
|
+
|---|---|---|
|
|
276
|
+
| `Code graph not built. Run build_code_graph first.` | No index exists | Call `build_code_graph(repo_path=...)` first |
|
|
277
|
+
| `Repository path does not exist: <path>` | Bad `repo_path` in build | Pass an absolute path that exists |
|
|
278
|
+
| `Git not available or not a git repository: ...` | `detect_changes` needs git | Only works in git repos with git installed |
|
|
279
|
+
| `Invalid pattern '...'` | Wrong `pattern` in `query_graph` | Use one of the 8 valid pattern strings |
|
|
280
|
+
| `No node found matching '<target>'` | Target not in index | Rebuild or check the qualified name via `semantic_search_code` |
|
|
281
|
+
|
|
282
|
+
If `build_code_graph` returns `files_parsed: 0`, no supported source files were found — check `repo_path` and `exclude_patterns`.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Profile Requirement
|
|
287
|
+
|
|
288
|
+
This skill uses graph tools that are only active under the `code` MCP profile. Your plugin `.mcp.json` must include:
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
"env": {
|
|
292
|
+
"SLM_MCP_PROFILE": "code"
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Without this, the six graph tools are not registered and will appear as unknown tools. Run `slm status` to confirm the active profile.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
SuperLocalMemory v3.6.14 · Qualixar · AGPL-3.0-or-later
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-recall
|
|
3
|
+
description: Search and retrieve facts, decisions, and past context from SuperLocalMemory. Use when the user asks to recall, find, search, or "what did we decide/say about X". Triggers multi-channel semantic retrieval with reranking; always call before storing anything new.
|
|
4
|
+
when_to_use: |
|
|
5
|
+
- "What did we decide about X?"
|
|
6
|
+
- "Recall anything about Y"
|
|
7
|
+
- "Do we have context on the Z feature?"
|
|
8
|
+
- "Find stored information about authentication / the database / error handling"
|
|
9
|
+
- "Search for what I said about Y"
|
|
10
|
+
- Automatically before any non-trivial task, to surface prior context
|
|
11
|
+
allowed-tools: recall, search, fetch, list_recent, Bash
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# slm-recall — Search & Retrieve Memory
|
|
15
|
+
|
|
16
|
+
Retrieve stored facts, decisions, and past context from SuperLocalMemory using
|
|
17
|
+
multi-channel retrieval. The golden rule: **recall before you remember**.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## When to use recall vs search vs fetch vs list_recent
|
|
22
|
+
|
|
23
|
+
| Situation | Tool |
|
|
24
|
+
|-----------|------|
|
|
25
|
+
| Conceptual or paraphrase query ("what did we agree on for auth?") | `recall` — full multi-channel retrieval + rerank |
|
|
26
|
+
| Exact keyword match needed ("find facts containing BM25") | `search` — FTS5 BM25 only, lower latency |
|
|
27
|
+
| You have a specific `fact_id` from a prior result | `fetch` — exact lookup, full detail |
|
|
28
|
+
| Browse newest entries without a query | `list_recent` |
|
|
29
|
+
|
|
30
|
+
Use `recall` as the default. `search` is a fallback for zero-result recall on a
|
|
31
|
+
known exact term. `fetch` is for when you already know the ID.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Recall-before-remember discipline
|
|
36
|
+
|
|
37
|
+
Before storing anything new, always call `recall` first. If a near-duplicate
|
|
38
|
+
fact already exists, call `update_memory(fact_id, content)` to refine it
|
|
39
|
+
rather than creating a duplicate. Duplicates degrade retrieval quality for
|
|
40
|
+
every future session.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## MCP-first workflow
|
|
45
|
+
|
|
46
|
+
### 1. Standard recall
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
recall(
|
|
50
|
+
query="authentication strategy decision",
|
|
51
|
+
limit=20, # default 20; reduce to 5 for quick pre-task checks
|
|
52
|
+
session_id="<sid>", # pass the session_id returned by session_init
|
|
53
|
+
fast=False, # default False; True skips SpreadingActivation channel
|
|
54
|
+
)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Real response shape (`--json` equivalent):
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"success": true,
|
|
61
|
+
"results": [
|
|
62
|
+
{
|
|
63
|
+
"fact_id": "f8a2bc91",
|
|
64
|
+
"content": "Decided to use JWT with 1h expiry for API auth (2026-06-10)",
|
|
65
|
+
"score": 0.87,
|
|
66
|
+
"confidence": 0.91,
|
|
67
|
+
"trust_score": 0.84,
|
|
68
|
+
"fact_type": "decision",
|
|
69
|
+
"channel_scores": {
|
|
70
|
+
"semantic": 0.88,
|
|
71
|
+
"lexical": 0.61,
|
|
72
|
+
"temporal": 0.72,
|
|
73
|
+
"structural": 0.55
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"count": 1,
|
|
78
|
+
"query_type": "semantic",
|
|
79
|
+
"channel_weights": {
|
|
80
|
+
"semantic": 0.4,
|
|
81
|
+
"lexical": 0.2,
|
|
82
|
+
"temporal": 0.2,
|
|
83
|
+
"structural": 0.2
|
|
84
|
+
},
|
|
85
|
+
"retrieval_time_ms": 134,
|
|
86
|
+
"no_confident_match": false
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Always check `no_confident_match`.** When `true`, no result cleared the
|
|
91
|
+
evidence floor. Do not invent a memory — tell the user nothing was found and
|
|
92
|
+
offer to search more broadly or store a new fact.
|
|
93
|
+
|
|
94
|
+
### 2. Passing session_id
|
|
95
|
+
|
|
96
|
+
Pass the `session_id` returned by `session_init`. It threads engagement signals
|
|
97
|
+
through to the ranker so each recall contributes to improving retrieval for
|
|
98
|
+
your project over time. Omitting it degrades the learning loop — recall works
|
|
99
|
+
correctly, but feedback is not attributed to the session.
|
|
100
|
+
|
|
101
|
+
### 3. Fast mode
|
|
102
|
+
|
|
103
|
+
Use `fast=True` for pre-tool-call checks where sub-second response matters.
|
|
104
|
+
This skips the SpreadingActivation channel. The remaining channels — semantic,
|
|
105
|
+
lexical, temporal, and structural — still run.
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
recall(query="rate limiting approach", limit=5, session_id="<sid>", fast=True)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 4. Keyword fallback via search
|
|
112
|
+
|
|
113
|
+
When `recall` returns zero results on a specific term, try `search`:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
search(query="BM25 indexing", limit=10, profile_id="")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`profile_id=""` uses the active profile. Response has `success`, `results`,
|
|
120
|
+
and `count` but no `channel_scores` or `query_type`.
|
|
121
|
+
|
|
122
|
+
### 5. Pull full detail for a known fact
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
fetch(fact_ids="f8a2bc91,d4c1e203")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Returns the full record for each ID: `entities`, `lifecycle`, `access_count`,
|
|
129
|
+
`importance`, `observation_date`, `referenced_date`. Use this when the recall
|
|
130
|
+
summary (120-char truncation in `list_recent`) is not enough.
|
|
131
|
+
|
|
132
|
+
### 6. Browse recent memories
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
list_recent(limit=20, profile_id="")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Returns facts newest-first. Content is truncated to 120 chars. Use `fetch`
|
|
139
|
+
once you have the `fact_id` for full content.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## How multi-channel retrieval works
|
|
144
|
+
|
|
145
|
+
`recall` runs four channels in parallel — semantic vector similarity, lexical
|
|
146
|
+
BM25, temporal recency, and structural/graph — then fuses them with Reciprocal
|
|
147
|
+
Rank Fusion (RRF) and applies a reranker. The `channel_weights` field in the
|
|
148
|
+
response shows how each channel contributed for that query. Weights adapt over
|
|
149
|
+
time based on engagement signals attributed via `session_id`.
|
|
150
|
+
|
|
151
|
+
To inspect per-channel scores for a real query against your own data:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
slm trace "<query>" [--limit N] [--json]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
No benchmark numbers are cited here; performance is workload-dependent.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## CLI fallback (when MCP is unavailable)
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Multi-channel semantic recall
|
|
165
|
+
slm recall "<query>" [--limit N] [--fast] [--json]
|
|
166
|
+
|
|
167
|
+
# Keyword/FTS5 search (alias: slm search)
|
|
168
|
+
slm search "<query>" [--limit N] [--json]
|
|
169
|
+
|
|
170
|
+
# Per-channel score breakdown
|
|
171
|
+
slm trace "<query>" [--limit N] [--json]
|
|
172
|
+
|
|
173
|
+
# Browse recent memories
|
|
174
|
+
slm list [--limit N] [--json]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Flags verified in source (main.py):
|
|
178
|
+
- `slm recall`: `--limit`, `--fast`, `--json`
|
|
179
|
+
- `slm search`: `--limit`, `--json`
|
|
180
|
+
- `slm trace`: `--limit`, `--json`
|
|
181
|
+
- `slm list`: `--limit` / `-n`, `--json`
|
|
182
|
+
|
|
183
|
+
**Flags that do NOT exist** (fabricated in old skills — never write these):
|
|
184
|
+
`--min-score`, `--format`, `--project`, `--tags` on recall or search.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Never fabricate a memory
|
|
189
|
+
|
|
190
|
+
If `results` is empty or `no_confident_match` is `true`, report it plainly.
|
|
191
|
+
Never construct a response as if a memory was found when it was not. The user
|
|
192
|
+
trusts that what you surface came from the store.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
*SuperLocalMemory v3.6.14 · Qualixar · AGPL-3.0-or-later*
|