claude-recall 0.18.7 → 0.18.8
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/hooks/search_enforcer.py +0 -0
- package/.claude/settings.json +1 -48
- package/.claude/skills/auto-corrections/SKILL.md +4 -1
- package/.claude/skills/auto-corrections/manifest.json +7 -4
- package/.claude/skills/auto-failure-lessons/SKILL.md +1 -3
- package/.claude/skills/auto-failure-lessons/manifest.json +3 -5
- package/.claude/skills/auto-preferences/SKILL.md +11 -6
- package/.claude/skills/auto-preferences/manifest.json +13 -8
- package/LICENSE +0 -0
- package/dist/hooks/bash-failure-watcher.js +4 -4
- package/dist/hooks/correction-detector.js +1 -1
- package/dist/hooks/memory-stop-hook.js +13 -2
- package/dist/hooks/shared.js +11 -0
- package/dist/mcp/tools/memory-tools.js +17 -2
- package/dist/services/outcome-storage.js +16 -0
- package/dist/services/promotion-engine.js +20 -9
- package/package.json +1 -1
|
File without changes
|
package/.claude/settings.json
CHANGED
|
@@ -1,48 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"PreToolUse": [
|
|
4
|
-
{
|
|
5
|
-
"matcher": ".*",
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "python3 /home/ebiarao/repos-wsl/personal-projects/claude-recall/.claude/hooks/search_enforcer.py"
|
|
10
|
-
}
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
],
|
|
14
|
-
"UserPromptSubmit": [
|
|
15
|
-
{
|
|
16
|
-
"hooks": [
|
|
17
|
-
{
|
|
18
|
-
"type": "command",
|
|
19
|
-
"command": "node /home/ebiarao/repos-wsl/personal-projects/claude-recall/dist/cli/claude-recall-cli.js hook run correction-detector"
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
}
|
|
23
|
-
],
|
|
24
|
-
"Stop": [
|
|
25
|
-
{
|
|
26
|
-
"hooks": [
|
|
27
|
-
{
|
|
28
|
-
"type": "command",
|
|
29
|
-
"command": "node /home/ebiarao/repos-wsl/personal-projects/claude-recall/dist/cli/claude-recall-cli.js hook run memory-stop",
|
|
30
|
-
"timeout": 30
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"PreCompact": [
|
|
36
|
-
{
|
|
37
|
-
"hooks": [
|
|
38
|
-
{
|
|
39
|
-
"type": "command",
|
|
40
|
-
"command": "node /home/ebiarao/repos-wsl/personal-projects/claude-recall/dist/cli/claude-recall-cli.js hook run precompact-preserve",
|
|
41
|
-
"timeout": 60
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
},
|
|
47
|
-
"hooksVersion": "6.0.0"
|
|
48
|
-
}
|
|
1
|
+
{"hooks": {}, "hooksVersion": "1.0.0"}
|
|
@@ -8,7 +8,7 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Corrections
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 20 memories. Last updated: 2026-03-22.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
@@ -22,8 +22,11 @@ Auto-generated from 17 memories. Last updated: 2026-03-21.
|
|
|
22
22
|
- CORRECTION: Memory with complex metadata
|
|
23
23
|
- CORRECTION: Memory with complex metadata
|
|
24
24
|
- CORRECTION: Memory with complex metadata
|
|
25
|
+
- CORRECTION: Memory with complex metadata
|
|
26
|
+
- CORRECTION: License copyright should include user's name instead of 'Claude Recall Contributors'
|
|
25
27
|
- CORRECTION: Replace expired access token with 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
|
|
26
28
|
- CORRECTION: use spaces not tabs for indentation
|
|
29
|
+
- CORRECTION: License copyright should list your name instead of 'Claude Recall Contributors'
|
|
27
30
|
- CORRECTION: cited (loaded 5+ times): 19
|
|
28
31
|
- CORRECTION: cited (loaded 5+ times): 19
|
|
29
32
|
- CORRECTION: cited (loaded 5+ times): 19
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "corrections",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-03-
|
|
3
|
+
"sourceHash": "be94895a3ad6a5999508be2c149a1a2742178fff9f9adc97b5da6185c9a30398",
|
|
4
|
+
"memoryCount": 20,
|
|
5
|
+
"generatedAt": "2026-03-22T15:58:29.733Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1774195109722_gij039r4m",
|
|
8
|
+
"memory_1774191618092_vuxyvq3mw",
|
|
7
9
|
"memory_1774106331272_kg5w7ztfj",
|
|
8
10
|
"memory_1774104588311_65kg08e05",
|
|
9
|
-
"memory_1774020789453_x9xkjhbug",
|
|
10
11
|
"memory_1773140547102_2wmy0cfga",
|
|
11
12
|
"memory_1773065886725_rscm7v2qx",
|
|
12
13
|
"memory_1773063478046_x0ryr9bk4",
|
|
@@ -14,8 +15,10 @@
|
|
|
14
15
|
"memory_1772641994141_ddvzwdkd9",
|
|
15
16
|
"memory_1772641570519_wmnb2b08w",
|
|
16
17
|
"memory_1772641026962_tqm8ow04r",
|
|
18
|
+
"hook_correction_1774180798682_9b5a2hadq",
|
|
17
19
|
"hook_correction_1772101108419_le80cln1w",
|
|
18
20
|
"hook_correction_1771112125882_99ihypf8x",
|
|
21
|
+
"hook_correction_1774180805192_4ft4zhfsa",
|
|
19
22
|
"hook_correction_1772638229134_otn9za2il",
|
|
20
23
|
"hook_correction_1772636083381_th3eluwzv",
|
|
21
24
|
"hook_correction_1772635851763_y91ugnjgy",
|
|
@@ -8,14 +8,12 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Failure Lessons
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 24 memories. Last updated: 2026-03-22.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
-
- Check command syntax, file paths, and prerequisites before running
|
|
16
15
|
- SQLite query syntax error: LIKE clause requires single quotes around string literal, not double quotes
|
|
17
16
|
- Avoid: Command failed: claude-recall outcomes 2>&1 → Instead: Check command syntax, file paths, and prerequisites before running
|
|
18
|
-
- Avoid: Command failed: npx jest tests/unit/outcome-storage.test.ts tests/unit/promotion-engine.test.ts tests/unit/memory... → Instead: Check command syntax, file paths, and prerequisites before running
|
|
19
17
|
- Avoid: Command failed: npm whoami 2>&1 && npm config get registry 2>&1 → Instead: Check command syntax, file paths, and prerequisites before running
|
|
20
18
|
- npm install -g claude-recall@0.15.36 failed with notarget error
|
|
21
19
|
- claude-recall@0.15.36 does not exist on npm registry (ETARGET error)
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "failure-lessons",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-03-
|
|
3
|
+
"sourceHash": "00deb7a6c6d99c26e0d29a6a707b4c303dcb19731d27a8ce41db09fd2ff3eb55",
|
|
4
|
+
"memoryCount": 24,
|
|
5
|
+
"generatedAt": "2026-03-22T15:00:18.049Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
-
"promoted_1774019382782_acm9j0h8u",
|
|
8
7
|
"hook_failure_1772637584921_0tj4rrxnt",
|
|
9
8
|
"hook_failure_non-zero-exit_1774020949485_6ubuoswae",
|
|
10
|
-
"hook_failure_non-zero-exit_1773999564001_82kcdp0ag",
|
|
11
9
|
"hook_failure_non-zero-exit_1773409269877_ful451241",
|
|
12
10
|
"hook_failure_1773410916808_5k1r6zo4u",
|
|
13
11
|
"hook_failure_1773410916789_xtrb8j9nw",
|
|
@@ -8,10 +8,19 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Preferences
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 21 memories. Last updated: 2026-03-22.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
+
- Test preference 1774195109742-2
|
|
16
|
+
- Test preference 1774195109742-1
|
|
17
|
+
- Test preference 1774195109742-0
|
|
18
|
+
- Test memory content
|
|
19
|
+
- Test preference 1774191618111-2
|
|
20
|
+
- Test preference 1774191618111-1
|
|
21
|
+
- Test preference 1774191618111-0
|
|
22
|
+
- Test memory content
|
|
23
|
+
- a normal preference
|
|
15
24
|
- Session test preference 1774106331339
|
|
16
25
|
- Test preference 1774106331283-2
|
|
17
26
|
- Test preference 1774106331283-1
|
|
@@ -23,11 +32,7 @@ Auto-generated from 16 memories. Last updated: 2026-03-21.
|
|
|
23
32
|
- Test preference 1774104588325-0
|
|
24
33
|
- Test memory content
|
|
25
34
|
- Session test preference 1774020789925
|
|
26
|
-
-
|
|
27
|
-
- Test preference 1774020789520-1
|
|
28
|
-
- Test preference 1774020789520-0
|
|
29
|
-
- Test memory content
|
|
30
|
-
- Session test preference 1773999187736
|
|
35
|
+
- Upgrade all projects whenever a new version is pushed
|
|
31
36
|
|
|
32
37
|
---
|
|
33
38
|
*Auto-generated by Claude Recall. Regenerate: `npx claude-recall skills generate`*
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "preferences",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-03-
|
|
3
|
+
"sourceHash": "29117b36ff390c0168d551c7f821d92567c91e252995d3786e0f0fd7462fc548",
|
|
4
|
+
"memoryCount": 21,
|
|
5
|
+
"generatedAt": "2026-03-22T15:58:29.796Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1774195109780_8ffmflge1",
|
|
8
|
+
"memory_1774195109763_v6olh83ct",
|
|
9
|
+
"memory_1774195109743_i79j9a9rl",
|
|
10
|
+
"memory_1774195109624_nnh3wrwca",
|
|
11
|
+
"memory_1774191618164_wefq7s9x6",
|
|
12
|
+
"memory_1774191618139_k77izvxnq",
|
|
13
|
+
"memory_1774191618112_hzi64751y",
|
|
14
|
+
"memory_1774191617980_pzspevoct",
|
|
15
|
+
"valid1",
|
|
7
16
|
"memory_1774106331340_cwt88yhle",
|
|
8
17
|
"memory_1774106331311_491hg2a21",
|
|
9
18
|
"memory_1774106331297_0b6bvacd7",
|
|
@@ -15,10 +24,6 @@
|
|
|
15
24
|
"memory_1774104588325_g4o5ksubl",
|
|
16
25
|
"memory_1774104588255_fy0wv845g",
|
|
17
26
|
"memory_1774020789927_g99mrubvu",
|
|
18
|
-
"
|
|
19
|
-
"memory_1774020789618_m1p55yhtz",
|
|
20
|
-
"memory_1774020789521_saryqj7kw",
|
|
21
|
-
"memory_1774020789257_wla5q38wq",
|
|
22
|
-
"memory_1773999187737_qrdwbas47"
|
|
27
|
+
"hook_preference_1774106575282_45sk4ep52"
|
|
23
28
|
]
|
|
24
29
|
}
|
package/LICENSE
CHANGED
|
File without changes
|
|
@@ -123,7 +123,7 @@ async function handleBashFailureWatcher(input) {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
catch (err) {
|
|
126
|
-
(0, shared_1.hookLog)(HOOK_NAME, `Error: ${err}`);
|
|
126
|
+
(0, shared_1.hookLog)(HOOK_NAME, `Error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
127
127
|
// Never throw — hooks must not block Claude
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -166,7 +166,7 @@ async function handleFailure(command, exitCode, output, sessionId) {
|
|
|
166
166
|
});
|
|
167
167
|
}
|
|
168
168
|
catch (err) {
|
|
169
|
-
(0, shared_1.hookLog)(HOOK_NAME, `Outcome event error: ${err}`);
|
|
169
|
+
(0, shared_1.hookLog)(HOOK_NAME, `Outcome event error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
170
170
|
}
|
|
171
171
|
(0, shared_1.hookLog)(HOOK_NAME, `Stored failure: ${truncate(command, 60)} (exit ${exitCode})`);
|
|
172
172
|
// Track pending failure for fix pairing
|
|
@@ -215,14 +215,14 @@ async function handleSuccess(command, sessionId) {
|
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
217
|
catch (err) {
|
|
218
|
-
(0, shared_1.hookLog)(HOOK_NAME, `Positive outcome event error: ${err}`);
|
|
218
|
+
(0, shared_1.hookLog)(HOOK_NAME, `Positive outcome event error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
219
219
|
}
|
|
220
220
|
(0, shared_1.hookLog)(HOOK_NAME, `Paired fix: "${truncate(command, 60)}" → ${pf.memoryKey}`);
|
|
221
221
|
matched = true;
|
|
222
222
|
// Don't add to remaining — consumed
|
|
223
223
|
}
|
|
224
224
|
catch (err) {
|
|
225
|
-
(0, shared_1.hookLog)(HOOK_NAME, `Fix pairing error: ${err}`);
|
|
225
|
+
(0, shared_1.hookLog)(HOOK_NAME, `Fix pairing error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
226
226
|
remaining.push(pf);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
@@ -40,7 +40,7 @@ async function handleCorrectionDetector(input) {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
catch (err) {
|
|
43
|
-
(0, shared_1.hookLog)('correction-detector', `Reask signal detection error: ${err}`);
|
|
43
|
+
(0, shared_1.hookLog)('correction-detector', `Reask signal detection error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
44
44
|
}
|
|
45
45
|
const result = await (0, shared_1.classifyContent)(prompt);
|
|
46
46
|
if (!result)
|
|
@@ -127,7 +127,18 @@ async function handleMemoryStop(input) {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
catch (err) {
|
|
130
|
-
(0, shared_1.hookLog)('memory-stop', `Promotion error: ${err}`);
|
|
130
|
+
(0, shared_1.hookLog)('memory-stop', `Promotion error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
131
|
+
}
|
|
132
|
+
// Prune old outcome data to prevent unbounded table growth
|
|
133
|
+
try {
|
|
134
|
+
const pruned = outcomeStorage.pruneOldData();
|
|
135
|
+
const total = pruned.episodes + pruned.events + pruned.lessons + pruned.stats;
|
|
136
|
+
if (total > 0) {
|
|
137
|
+
(0, shared_1.hookLog)('memory-stop', `Pruned: ${pruned.episodes} episodes, ${pruned.events} events, ${pruned.lessons} lessons, ${pruned.stats} orphaned stats`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
(0, shared_1.hookLog)('memory-stop', `Prune error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
131
142
|
}
|
|
132
143
|
}
|
|
133
144
|
/**
|
|
@@ -331,7 +342,7 @@ function generateCandidateLessons(failures, episodeId, projectId) {
|
|
|
331
342
|
}
|
|
332
343
|
}
|
|
333
344
|
catch (err) {
|
|
334
|
-
(0, shared_1.hookLog)('memory-stop', `Candidate lesson generation error: ${err}`);
|
|
345
|
+
(0, shared_1.hookLog)('memory-stop', `Candidate lesson generation error: ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
335
346
|
}
|
|
336
347
|
}
|
|
337
348
|
function extractTagsFromContext(context) {
|
package/dist/hooks/shared.js
CHANGED
|
@@ -41,6 +41,7 @@ exports.jaccardSimilarity = jaccardSimilarity;
|
|
|
41
41
|
exports.isDuplicate = isDuplicate;
|
|
42
42
|
exports.storeMemory = storeMemory;
|
|
43
43
|
exports.searchExisting = searchExisting;
|
|
44
|
+
exports.safeErrorMessage = safeErrorMessage;
|
|
44
45
|
exports.hookLog = hookLog;
|
|
45
46
|
exports.readTranscriptTail = readTranscriptTail;
|
|
46
47
|
exports.isUserEntry = isUserEntry;
|
|
@@ -193,6 +194,16 @@ function searchExisting(query) {
|
|
|
193
194
|
const memoryService = memory_1.MemoryService.getInstance();
|
|
194
195
|
return memoryService.search(query);
|
|
195
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Extract a safe error message without exposing stack traces or internal paths.
|
|
199
|
+
*/
|
|
200
|
+
function safeErrorMessage(err) {
|
|
201
|
+
if (err instanceof Error)
|
|
202
|
+
return err.message;
|
|
203
|
+
if (typeof err === 'string')
|
|
204
|
+
return err;
|
|
205
|
+
return 'unknown error';
|
|
206
|
+
}
|
|
196
207
|
/**
|
|
197
208
|
* Append a log line to ~/.claude-recall/hook-logs/{hookName}.log
|
|
198
209
|
*/
|
|
@@ -297,8 +297,23 @@ class MemoryTools {
|
|
|
297
297
|
if (lowCompliance.length > 0) {
|
|
298
298
|
sections.push('## Rule Health\nThese rules are loaded frequently but never cited — consider rewording or removing:\n' +
|
|
299
299
|
lowCompliance.map(r => {
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
let val;
|
|
301
|
+
if (typeof r.value === 'string') {
|
|
302
|
+
try {
|
|
303
|
+
const parsed = JSON.parse(r.value);
|
|
304
|
+
val = typeof parsed === 'string' ? parsed : (parsed?.content || parsed?.value || r.value);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
val = r.value;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else if (typeof r.value === 'object' && r.value !== null) {
|
|
311
|
+
val = r.value.content || r.value.value || JSON.stringify(r.value);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
val = String(r.value ?? '');
|
|
315
|
+
}
|
|
316
|
+
return `- "${val.substring(0, 80)}" (loaded ${r.load_count}x, cited 0x)`;
|
|
302
317
|
}).join('\n'));
|
|
303
318
|
}
|
|
304
319
|
const totalRules = rules.preferences.length + rules.corrections.length +
|
|
@@ -193,6 +193,22 @@ class OutcomeStorage {
|
|
|
193
193
|
times_unhelpful = times_unhelpful + 1
|
|
194
194
|
`).run(key);
|
|
195
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Prune old data from outcome tables to prevent unbounded growth.
|
|
198
|
+
* - Episodes older than 90 days
|
|
199
|
+
* - Outcome events older than 90 days
|
|
200
|
+
* - Rejected/archived candidate lessons older than 14 days
|
|
201
|
+
* - Orphaned memory_stats entries (key no longer in memories table)
|
|
202
|
+
*/
|
|
203
|
+
pruneOldData() {
|
|
204
|
+
const cutoff90 = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000).toISOString();
|
|
205
|
+
const cutoff14 = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000).toISOString();
|
|
206
|
+
const episodes = this.db.prepare('DELETE FROM episodes WHERE created_at < ?').run(cutoff90).changes;
|
|
207
|
+
const events = this.db.prepare('DELETE FROM outcome_events WHERE created_at < ?').run(cutoff90).changes;
|
|
208
|
+
const lessons = this.db.prepare("DELETE FROM candidate_lessons WHERE status IN ('rejected', 'archived') AND updated_at < ?").run(cutoff14).changes;
|
|
209
|
+
const stats = this.db.prepare('DELETE FROM memory_stats WHERE memory_key NOT IN (SELECT key FROM memories)').run().changes;
|
|
210
|
+
return { episodes, events, lessons, stats };
|
|
211
|
+
}
|
|
196
212
|
}
|
|
197
213
|
exports.OutcomeStorage = OutcomeStorage;
|
|
198
214
|
// --- Helpers ---
|
|
@@ -34,13 +34,18 @@ class PromotionEngine {
|
|
|
34
34
|
let promoted = 0;
|
|
35
35
|
let archived = 0;
|
|
36
36
|
for (const candidate of candidates) {
|
|
37
|
-
|
|
38
|
-
this.
|
|
39
|
-
|
|
37
|
+
try {
|
|
38
|
+
if (this.shouldPromote(candidate)) {
|
|
39
|
+
this.promote(candidate.id);
|
|
40
|
+
promoted++;
|
|
41
|
+
}
|
|
42
|
+
else if (this.shouldReject(candidate)) {
|
|
43
|
+
outcomeStorage.updateLessonStatus(candidate.id, 'rejected');
|
|
44
|
+
archived++;
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
archived++;
|
|
47
|
+
catch (err) {
|
|
48
|
+
console.error(`PromotionEngine: failed to process candidate ${candidate.id}`);
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
// Check for demotion of existing memories
|
|
@@ -108,7 +113,13 @@ class PromotionEngine {
|
|
|
108
113
|
// Not retrieved in 90 days with low strength
|
|
109
114
|
if (stats.last_retrieved_at) {
|
|
110
115
|
const daysSinceRetrieved = (Date.now() - new Date(stats.last_retrieved_at).getTime()) / (1000 * 60 * 60 * 24);
|
|
111
|
-
|
|
116
|
+
let strength = 0;
|
|
117
|
+
try {
|
|
118
|
+
strength = retrieval_1.MemoryRetrieval.computeStrength(memory);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
strength = 0;
|
|
122
|
+
}
|
|
112
123
|
if (daysSinceRetrieved > 90 && strength < 0.2) {
|
|
113
124
|
return true;
|
|
114
125
|
}
|
|
@@ -159,8 +170,8 @@ class PromotionEngine {
|
|
|
159
170
|
}
|
|
160
171
|
}
|
|
161
172
|
}
|
|
162
|
-
catch {
|
|
163
|
-
|
|
173
|
+
catch (err) {
|
|
174
|
+
console.error('PromotionEngine: demotion sweep failed');
|
|
164
175
|
}
|
|
165
176
|
return archived;
|
|
166
177
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-recall",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.8",
|
|
4
4
|
"description": "Persistent memory for Claude Code with native Skills integration, automatic capture, failure learning, and project scoping via MCP server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|