claude-recall 0.20.7 → 0.20.9
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/skills/auto-corrections/SKILL.md +2 -1
- package/.claude/skills/auto-corrections/manifest.json +4 -3
- package/.claude/skills/auto-preferences/SKILL.md +6 -1
- package/.claude/skills/auto-preferences/manifest.json +8 -3
- package/README.md +8 -3
- package/dist/hooks/correction-detector.js +1 -1
- package/dist/hooks/memory-stop-hook.js +7 -0
- package/dist/hooks/post-compact-reload.js +1 -1
- package/dist/hooks/precompact-preserve.js +3 -0
- package/dist/pi/extension.js +31 -5
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Corrections
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 16 memories. Last updated: 2026-04-06.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
@@ -25,6 +25,7 @@ Auto-generated from 15 memories. Last updated: 2026-04-06.
|
|
|
25
25
|
- CORRECTION: Memory with complex metadata
|
|
26
26
|
- CORRECTION: Memory with complex metadata
|
|
27
27
|
- CORRECTION: Memory with complex metadata
|
|
28
|
+
- CORRECTION: Memory with complex metadata
|
|
28
29
|
- CORRECTION: License copyright should include user's name instead of 'Claude Recall Contributors'
|
|
29
30
|
- CORRECTION: License copyright should list your name instead of 'Claude Recall Contributors'
|
|
30
31
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "corrections",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-04-
|
|
3
|
+
"sourceHash": "1313608fb812bd1bed85d9854e8958179f7584619e0160604c56bd40ec8cc5b0",
|
|
4
|
+
"memoryCount": 16,
|
|
5
|
+
"generatedAt": "2026-04-06T17:24:01.505Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1775496241485_1yyc5ht88",
|
|
7
8
|
"memory_1775494279035_j6uj5lzxo",
|
|
8
9
|
"memory_1775492069326_vksvzmt3f",
|
|
9
10
|
"memory_1775491767369_sepsjmg8y",
|
|
@@ -8,10 +8,15 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Preferences
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 79 memories. Last updated: 2026-04-06.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
+
- Session test preference 1775496241643
|
|
16
|
+
- Test preference 1775496241514-2
|
|
17
|
+
- Test preference 1775496241514-1
|
|
18
|
+
- Test preference 1775496241514-0
|
|
19
|
+
- Test memory content
|
|
15
20
|
- Session test preference 1775494279149
|
|
16
21
|
- Test preference 1775494279061-2
|
|
17
22
|
- Test preference 1775494279061-1
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "preferences",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-04-
|
|
3
|
+
"sourceHash": "1cad20b547cd1594370facfdae6b4ae8700516e9be712d8b28459462398c9276",
|
|
4
|
+
"memoryCount": 79,
|
|
5
|
+
"generatedAt": "2026-04-06T17:24:01.663Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1775496241645_xtz7cwan4",
|
|
8
|
+
"memory_1775496241576_j7sxxuge3",
|
|
9
|
+
"memory_1775496241542_rg3hj24ud",
|
|
10
|
+
"memory_1775496241516_y3inz8rlf",
|
|
11
|
+
"memory_1775496241411_vwdz6igrm",
|
|
7
12
|
"memory_1775494279150_n4pq7zy11",
|
|
8
13
|
"memory_1775494279108_6hbe8qoit",
|
|
9
14
|
"memory_1775494279088_nv8hjdm7s",
|
package/README.md
CHANGED
|
@@ -65,13 +65,16 @@ Both agents use the same database (`~/.claude-recall/claude-recall.db`). Memorie
|
|
|
65
65
|
### Upgrading
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
# Claude Code
|
|
68
|
+
# Claude Code — update binary + re-install hooks in each project
|
|
69
69
|
npm install -g claude-recall
|
|
70
|
+
claude-recall setup --install # run from each project directory
|
|
70
71
|
|
|
71
72
|
# Pi
|
|
72
73
|
pi update claude-recall
|
|
73
74
|
```
|
|
74
75
|
|
|
76
|
+
The MCP server picks up the new version automatically. `setup --install` is needed to update hooks in `.claude/settings.json` (new hook events may have been added).
|
|
77
|
+
|
|
75
78
|
---
|
|
76
79
|
|
|
77
80
|
## What to Expect
|
|
@@ -81,10 +84,12 @@ Once installed, Claude Recall works automatically in the background:
|
|
|
81
84
|
1. **Session start** — active rules are loaded before the first action. In Claude Code, this happens via the `search_enforcer` hook; in Pi, rules are injected into the system prompt automatically
|
|
82
85
|
2. **As you work** — every prompt is classified for corrections and preferences. Natural statements like *"we use tabs here"* or *"no, put tests in `__tests__/`"* are detected and stored
|
|
83
86
|
3. **Tool outcomes** — results from all tools (Bash, Edit, Write, and more) are captured. Failures are stored as memories; Bash failures are paired with successful fixes
|
|
84
|
-
4. **End of session** — session episodes are created, candidate lessons extracted from failures, and a promotion cycle graduates validated patterns into active rules
|
|
87
|
+
4. **End of session** — session episodes are created, candidate lessons extracted from failures, and a promotion cycle graduates validated patterns into active rules. A session extraction pass sends the last 50 transcript entries to Haiku to extract durable project knowledge from long coding sessions
|
|
85
88
|
5. **Reask detection** — frustration signals ("still broken", "that didn't work") are recorded as outcome events
|
|
86
89
|
6. **Before context compression** — aggressive memory sweep captures important context before the window shrinks
|
|
87
|
-
7. **
|
|
90
|
+
7. **After context compression** (Claude Code only) — rules are automatically re-injected into context so they're not lost when the window shrinks
|
|
91
|
+
8. **Multi-agent outcomes** — subagent completions (completed/failed/killed) are captured from task notifications and recorded as outcome events
|
|
92
|
+
9. **Rules sync** (Claude Code only) — top 30 rules are exported as typed `.md` files to Claude Code's native memory directory
|
|
88
93
|
|
|
89
94
|
Classification uses Claude Haiku (via `ANTHROPIC_API_KEY`) with silent regex fallback. No configuration needed.
|
|
90
95
|
|
|
@@ -64,6 +64,6 @@ async function handleCorrectionDetector(input) {
|
|
|
64
64
|
? result.extract.substring(0, 60) + '...'
|
|
65
65
|
: result.extract;
|
|
66
66
|
// Output hook message that Claude sees
|
|
67
|
-
console.log(`<user-prompt-submit-hook
|
|
67
|
+
console.log(`<user-prompt-submit-hook>📌 Recall: auto-captured ${result.type} — ${summary}</user-prompt-submit-hook>`);
|
|
68
68
|
(0, shared_1.hookLog)('correction-detector', `Captured ${result.type}: ${result.extract.substring(0, 80)}`);
|
|
69
69
|
}
|
|
@@ -107,6 +107,9 @@ async function handleMemoryStop(input) {
|
|
|
107
107
|
stored++;
|
|
108
108
|
(0, shared_1.hookLog)('memory-stop', `Captured ${result.type}: ${result.extract.substring(0, 80)}`);
|
|
109
109
|
}
|
|
110
|
+
if (stored > 0) {
|
|
111
|
+
console.log(`📝 Recall: captured ${stored} memories from this session`);
|
|
112
|
+
}
|
|
110
113
|
(0, shared_1.hookLog)('memory-stop', `Session end: stored ${stored} memories from ${entries.length} entries`);
|
|
111
114
|
// Session extraction: learn from long coding sessions (reads wider window)
|
|
112
115
|
try {
|
|
@@ -131,6 +134,7 @@ async function handleMemoryStop(input) {
|
|
|
131
134
|
}
|
|
132
135
|
const extracted = await (0, event_processors_1.extractSessionLearnings)(conversationEntries, input?.session_id ?? '', projectId, 5);
|
|
133
136
|
if (extracted > 0) {
|
|
137
|
+
console.log(`🔍 Recall: extracted ${extracted} learnings from session analysis`);
|
|
134
138
|
(0, shared_1.hookLog)('memory-stop', `Session extraction: stored ${extracted} learnings`);
|
|
135
139
|
stored += extracted;
|
|
136
140
|
}
|
|
@@ -158,6 +162,9 @@ async function handleMemoryStop(input) {
|
|
|
158
162
|
const { PromotionEngine } = await Promise.resolve().then(() => __importStar(require('../services/promotion-engine')));
|
|
159
163
|
const result = PromotionEngine.getInstance().runCycle(projectId);
|
|
160
164
|
if (result.promoted > 0 || result.archived > 0) {
|
|
165
|
+
if (result.promoted > 0) {
|
|
166
|
+
console.log(`⬆️ Recall: ${result.promoted} lesson(s) promoted to active rules`);
|
|
167
|
+
}
|
|
161
168
|
(0, shared_1.hookLog)('memory-stop', `Promotion: ${result.promoted} promoted, ${result.archived} archived`);
|
|
162
169
|
}
|
|
163
170
|
}
|
|
@@ -48,7 +48,7 @@ async function handlePostCompactReload(input) {
|
|
|
48
48
|
if (totalRules === 0)
|
|
49
49
|
return;
|
|
50
50
|
const body = formatRules(rules);
|
|
51
|
-
console.log(
|
|
51
|
+
console.log(`🔄 Recall: ${totalRules} rules re-loaded after context compaction\n\n${DIRECTIVE}\n\n---\n\n${body}`);
|
|
52
52
|
(0, shared_1.hookLog)('post-compact-reload', `Re-injected ${totalRules} rules after compaction`);
|
|
53
53
|
}
|
|
54
54
|
catch (err) {
|
|
@@ -93,6 +93,9 @@ async function handlePrecompactPreserve(input) {
|
|
|
93
93
|
stored++;
|
|
94
94
|
(0, shared_1.hookLog)('precompact', `Captured ${result.type}: ${result.extract.substring(0, 80)}`);
|
|
95
95
|
}
|
|
96
|
+
if (stored > 0) {
|
|
97
|
+
console.log(`💾 Recall: preserved ${stored} memories before context compression`);
|
|
98
|
+
}
|
|
96
99
|
(0, shared_1.hookLog)('precompact', `PreCompact sweep: stored ${stored} memories from ${entries.length} entries`);
|
|
97
100
|
// Reset search enforcer hook-state so Claude is forced to re-load rules
|
|
98
101
|
// after context compression. Without this, the enforcer thinks rules are
|
package/dist/pi/extension.js
CHANGED
|
@@ -137,21 +137,47 @@ function default_1(pi) {
|
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
139
|
// --- Event: detect corrections from user input ---
|
|
140
|
-
pi.on('input', (event,
|
|
140
|
+
pi.on('input', (event, ctx) => {
|
|
141
141
|
collectedUserTexts.push(event.text);
|
|
142
|
-
(0, event_processors_1.processUserInput)(event.text, sessionId).
|
|
142
|
+
(0, event_processors_1.processUserInput)(event.text, sessionId).then(msg => {
|
|
143
|
+
if (msg && ctx.hasUI) {
|
|
144
|
+
try {
|
|
145
|
+
ctx.ui.notify(`📌 ${msg}`, 'info');
|
|
146
|
+
}
|
|
147
|
+
catch { /* non-critical */ }
|
|
148
|
+
}
|
|
149
|
+
}).catch(() => { });
|
|
143
150
|
return { action: 'continue' };
|
|
144
151
|
});
|
|
145
152
|
// --- Event: session end — episode + promotion + session extraction ---
|
|
146
|
-
pi.on('session_shutdown', (_event,
|
|
147
|
-
(0, event_processors_1.processSessionEnd)(collectedUserTexts, sessionId, projectId).
|
|
153
|
+
pi.on('session_shutdown', (_event, ctx) => {
|
|
154
|
+
(0, event_processors_1.processSessionEnd)(collectedUserTexts, sessionId, projectId).then(result => {
|
|
155
|
+
if (ctx.hasUI) {
|
|
156
|
+
try {
|
|
157
|
+
if (result.stored > 0) {
|
|
158
|
+
ctx.ui.notify(`📝 Recall: captured ${result.stored} memories from this session`, 'info');
|
|
159
|
+
}
|
|
160
|
+
if (result.promoted > 0) {
|
|
161
|
+
ctx.ui.notify(`⬆️ Recall: ${result.promoted} lesson(s) promoted to active rules`, 'info');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch { /* non-critical */ }
|
|
165
|
+
}
|
|
166
|
+
}).catch(() => { });
|
|
148
167
|
// Session extraction: learn from long coding sessions
|
|
149
168
|
const allEntries = [
|
|
150
169
|
...collectedUserTexts.map(t => ({ role: 'user', text: t })),
|
|
151
170
|
...collectedToolResults,
|
|
152
171
|
];
|
|
153
172
|
if (allEntries.length >= 10) {
|
|
154
|
-
(0, event_processors_1.extractSessionLearnings)(allEntries, sessionId, projectId, 5).
|
|
173
|
+
(0, event_processors_1.extractSessionLearnings)(allEntries, sessionId, projectId, 5).then(extracted => {
|
|
174
|
+
if (extracted > 0 && ctx.hasUI) {
|
|
175
|
+
try {
|
|
176
|
+
ctx.ui.notify(`🔍 Recall: extracted ${extracted} learnings from session`, 'info');
|
|
177
|
+
}
|
|
178
|
+
catch { /* non-critical */ }
|
|
179
|
+
}
|
|
180
|
+
}).catch(() => { });
|
|
155
181
|
}
|
|
156
182
|
});
|
|
157
183
|
// --- Event: pre-compaction — aggressive capture ---
|
package/package.json
CHANGED