claude-mem-lite 2.1.0 → 2.1.2
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 +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.mcp.json +5 -2
- package/hook-memory.mjs +68 -0
- package/hooks/hooks.json +1 -1
- package/package.json +2 -1
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "claude-mem-lite",
|
|
13
|
-
"version": "2.
|
|
14
|
-
"source": "
|
|
13
|
+
"version": "2.1.2",
|
|
14
|
+
"source": "./",
|
|
15
15
|
"description": "Lightweight persistent memory system for Claude Code — FTS5 search, episode batching, error-triggered recall"
|
|
16
16
|
}
|
|
17
17
|
]
|
package/.mcp.json
CHANGED
package/hook-memory.mjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// claude-mem-lite — Semantic Memory Injection
|
|
2
|
+
// Search past observations for relevant memories to inject as context at user-prompt time.
|
|
3
|
+
|
|
4
|
+
import { sanitizeFtsQuery, debugCatch } from './utils.mjs';
|
|
5
|
+
|
|
6
|
+
const MAX_MEMORY_INJECTIONS = 2;
|
|
7
|
+
const MEMORY_LOOKBACK_MS = 14 * 86400000; // 14 days
|
|
8
|
+
const MEMORY_TYPE_BOOST = { bugfix: 1.5, decision: 1.3, discovery: 1.0, feature: 0.8, change: 0.5, refactor: 0.5 };
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Search for relevant past observations to inject as memory context.
|
|
12
|
+
* Strict quality gates: importance>=2, type-boosted, BM25-thresholded.
|
|
13
|
+
* @param {import('better-sqlite3').Database} db Memory database
|
|
14
|
+
* @param {string} userPrompt User's prompt text
|
|
15
|
+
* @param {string} project Current project
|
|
16
|
+
* @param {number[]} excludeIds Observation IDs already in Key Context
|
|
17
|
+
* @returns {object[]} Top memories (max 2) with {id, type, title}
|
|
18
|
+
*/
|
|
19
|
+
export function searchRelevantMemories(db, userPrompt, project, excludeIds = []) {
|
|
20
|
+
if (!db || !userPrompt || userPrompt.length < 5) return [];
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const ftsQuery = sanitizeFtsQuery(userPrompt);
|
|
24
|
+
if (!ftsQuery) return [];
|
|
25
|
+
|
|
26
|
+
const cutoff = Date.now() - MEMORY_LOOKBACK_MS;
|
|
27
|
+
const excludeSet = new Set(excludeIds);
|
|
28
|
+
|
|
29
|
+
const selectStmt = db.prepare(`
|
|
30
|
+
SELECT o.id, o.type, o.title, o.importance,
|
|
31
|
+
bm25(observations_fts) as relevance
|
|
32
|
+
FROM observations_fts
|
|
33
|
+
JOIN observations o ON o.id = observations_fts.rowid
|
|
34
|
+
WHERE observations_fts MATCH ?
|
|
35
|
+
AND o.project = ?
|
|
36
|
+
AND o.importance >= 2
|
|
37
|
+
AND o.created_at_epoch > ?
|
|
38
|
+
AND COALESCE(o.compressed_into, 0) = 0
|
|
39
|
+
ORDER BY bm25(observations_fts)
|
|
40
|
+
LIMIT 10
|
|
41
|
+
`);
|
|
42
|
+
const rows = selectStmt.all(ftsQuery, project, cutoff);
|
|
43
|
+
|
|
44
|
+
// Score: BM25 × type boost, filter by threshold, exclude Key Context IDs
|
|
45
|
+
const scored = rows
|
|
46
|
+
.filter(r => !excludeSet.has(r.id))
|
|
47
|
+
.map(r => ({
|
|
48
|
+
...r,
|
|
49
|
+
score: Math.abs(r.relevance) * (MEMORY_TYPE_BOOST[r.type] || 1.0),
|
|
50
|
+
}))
|
|
51
|
+
.sort((a, b) => b.score - a.score);
|
|
52
|
+
|
|
53
|
+
// Strict threshold: only inject if best match has meaningful score
|
|
54
|
+
if (scored.length === 0 || scored[0].score < 1.0) return [];
|
|
55
|
+
|
|
56
|
+
// Update access_count for injected memories
|
|
57
|
+
const result = scored.slice(0, MAX_MEMORY_INJECTIONS);
|
|
58
|
+
const updateStmt = db.prepare('UPDATE observations SET access_count = COALESCE(access_count, 0) + 1 WHERE id = ?');
|
|
59
|
+
for (const r of result) {
|
|
60
|
+
updateStmt.run(r.id);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return result;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
debugCatch(e, 'searchRelevantMemories');
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
}
|
package/hooks/hooks.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Lightweight persistent memory system for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"hook.mjs",
|
|
29
29
|
"hook-shared.mjs",
|
|
30
30
|
"hook-llm.mjs",
|
|
31
|
+
"hook-memory.mjs",
|
|
31
32
|
"hook-semaphore.mjs",
|
|
32
33
|
"hook-episode.mjs",
|
|
33
34
|
"hook-context.mjs",
|