claude-recall 0.20.0 → 0.20.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/skills/auto-corrections/SKILL.md +5 -1
- package/.claude/skills/auto-corrections/manifest.json +7 -3
- package/.claude/skills/auto-preferences/SKILL.md +23 -1
- package/.claude/skills/auto-preferences/manifest.json +25 -3
- package/dist/mcp/tools/memory-tools.js +4 -5
- package/dist/pi/extension.js +5 -4
- package/dist/shared/event-processors.js +75 -2
- package/package.json +1 -1
|
@@ -8,10 +8,14 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Corrections
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 9 memories. Last updated: 2026-04-02.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
+
- CORRECTION: Memory with complex metadata
|
|
16
|
+
- CORRECTION: Memory with complex metadata
|
|
17
|
+
- CORRECTION: Memory with complex metadata
|
|
18
|
+
- CORRECTION: Memory with complex metadata
|
|
15
19
|
- CORRECTION: Memory with complex metadata
|
|
16
20
|
- CORRECTION: Memory with complex metadata
|
|
17
21
|
- CORRECTION: Memory with complex metadata
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "corrections",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-04-
|
|
3
|
+
"sourceHash": "bc99031d99dbd5f9baeff51cd1b1d609f0a231dc120f5559a98080419ba54be6",
|
|
4
|
+
"memoryCount": 9,
|
|
5
|
+
"generatedAt": "2026-04-02T22:34:33.293Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1775169273281_4fod7ku6f",
|
|
8
|
+
"memory_1775169256118_y7kc07y6y",
|
|
9
|
+
"memory_1775169244673_d6d0uc33a",
|
|
10
|
+
"memory_1775160781806_vnqf355e9",
|
|
7
11
|
"memory_1775159399542_awfryrxp3",
|
|
8
12
|
"memory_1775157082825_8uvrul28i",
|
|
9
13
|
"memory_1775156381094_dr1nihes8",
|
|
@@ -8,10 +8,32 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Preferences
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 39 memories. Last updated: 2026-04-02.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
+
- Session test preference 1775169273366
|
|
16
|
+
- Test preference 1775169273296-2
|
|
17
|
+
- Test preference 1775169273296-1
|
|
18
|
+
- Test preference 1775169273296-0
|
|
19
|
+
- Test memory content
|
|
20
|
+
- Session test preference 1775169256189
|
|
21
|
+
- Test preference 1775169256133-2
|
|
22
|
+
- Test preference 1775169256133-1
|
|
23
|
+
- Test preference 1775169256133-0
|
|
24
|
+
- Test memory content
|
|
25
|
+
- Session test preference 1775169244752
|
|
26
|
+
- Test preference 1775169244686-2
|
|
27
|
+
- Test preference 1775169244686-1
|
|
28
|
+
- Test preference 1775169244686-0
|
|
29
|
+
- Test memory content
|
|
30
|
+
- Markdown documentation files should be named with the convention YYYYMMDD_<filename>.md (e.g., 20260402_nemoclaw_integration.md). Use underscores, not hyphens, in the date-prefixed filenames.
|
|
31
|
+
- Never commit to git unless the user explicitly approves. Always show the commit message and wait for a clear "yes", "go ahead", "commit", or similar confirmation before running git commit.
|
|
32
|
+
- Session test preference 1775160781884
|
|
33
|
+
- Test preference 1775160781820-2
|
|
34
|
+
- Test preference 1775160781820-1
|
|
35
|
+
- Test preference 1775160781820-0
|
|
36
|
+
- Test memory content
|
|
15
37
|
- Session test preference 1775159399698
|
|
16
38
|
- Test preference 1775159399559-2
|
|
17
39
|
- Test preference 1775159399559-1
|
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "preferences",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-04-
|
|
3
|
+
"sourceHash": "d609433b68eba6dbfaea5244e666c564e76ad1be0f75373c555fdd83405390cd",
|
|
4
|
+
"memoryCount": 39,
|
|
5
|
+
"generatedAt": "2026-04-02T22:34:33.383Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1775169273368_c1e5jdl9r",
|
|
8
|
+
"memory_1775169273337_wozxe12k3",
|
|
9
|
+
"memory_1775169273319_3o1ww90na",
|
|
10
|
+
"memory_1775169273297_oqmyxziav",
|
|
11
|
+
"memory_1775169273232_eoymf3ezj",
|
|
12
|
+
"memory_1775169256190_681x8frvt",
|
|
13
|
+
"memory_1775169256164_kqderurux",
|
|
14
|
+
"memory_1775169256150_0nqbk7tx9",
|
|
15
|
+
"memory_1775169256134_ftj0m44bb",
|
|
16
|
+
"memory_1775169256069_dywd646f7",
|
|
17
|
+
"memory_1775169244754_sjfarlk41",
|
|
18
|
+
"memory_1775169244722_mavida9fg",
|
|
19
|
+
"memory_1775169244707_nmmu0s0lu",
|
|
20
|
+
"memory_1775169244688_03q4mmcky",
|
|
21
|
+
"memory_1775169244628_7kuhf5met",
|
|
22
|
+
"memory_1775168901303_o8o0i4952",
|
|
23
|
+
"memory_1775162828137_l6uw5swdn",
|
|
24
|
+
"memory_1775160781885_fkbnc0s85",
|
|
25
|
+
"memory_1775160781857_gj5y299dr",
|
|
26
|
+
"memory_1775160781842_0xmv146n5",
|
|
27
|
+
"memory_1775160781821_o9ipt8nsc",
|
|
28
|
+
"memory_1775160781747_70e5gbp7j",
|
|
7
29
|
"memory_1775159399702_yg6ynd05n",
|
|
8
30
|
"memory_1775159399631_fmy4s2vhr",
|
|
9
31
|
"memory_1775159399606_xymkvcjfv",
|
|
@@ -467,9 +467,8 @@ class MemoryTools {
|
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
exports.MemoryTools = MemoryTools;
|
|
470
|
-
MemoryTools.LOAD_RULES_DIRECTIVE = '
|
|
471
|
-
'
|
|
472
|
-
'
|
|
473
|
-
'
|
|
474
|
-
'As you work, cite each applied rule inline: (applied from memory: <rule summary>)\n' +
|
|
470
|
+
MemoryTools.LOAD_RULES_DIRECTIVE = 'Before your FIRST action, briefly state which rules below you will apply to this task.\n' +
|
|
471
|
+
'As you work, cite each rule at the point where it influences your action:\n' +
|
|
472
|
+
'(applied from memory: <short rule name>)\n' +
|
|
473
|
+
'Place citations next to the action they influenced — not at the end of unrelated text.\n' +
|
|
475
474
|
'If a rule conflicts with your plan, follow the rule — it reflects a user decision.';
|
package/dist/pi/extension.js
CHANGED
|
@@ -14,10 +14,10 @@ const config_1 = require("../services/config");
|
|
|
14
14
|
const outcome_storage_1 = require("../services/outcome-storage");
|
|
15
15
|
const logging_1 = require("../services/logging");
|
|
16
16
|
const event_processors_1 = require("../shared/event-processors");
|
|
17
|
-
const LOAD_RULES_DIRECTIVE = '
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
17
|
+
const LOAD_RULES_DIRECTIVE = 'Before your FIRST action, briefly state which rules below you will apply to this task.\n' +
|
|
18
|
+
'As you work, cite each rule at the point where it influences your action:\n' +
|
|
19
|
+
'(applied from memory: <short rule name>)\n' +
|
|
20
|
+
'Place citations next to the action they influenced — not at the end of unrelated text.\n' +
|
|
21
21
|
'If a rule conflicts with your plan, follow the rule — it reflects a user decision.';
|
|
22
22
|
/** Format a memory value for display. */
|
|
23
23
|
function extractVal(value) {
|
|
@@ -62,6 +62,7 @@ function default_1(pi) {
|
|
|
62
62
|
projectId = ctx.cwd.split('/').pop() || 'unknown';
|
|
63
63
|
rulesLoaded = false;
|
|
64
64
|
collectedUserTexts.length = 0;
|
|
65
|
+
(0, event_processors_1.resetPendingFailures)();
|
|
65
66
|
try {
|
|
66
67
|
config_1.ConfigService.getInstance().updateConfig({
|
|
67
68
|
project: { rootDir: ctx.cwd },
|
|
@@ -41,17 +41,72 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
})();
|
|
42
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
43
|
exports.setLogFunction = setLogFunction;
|
|
44
|
+
exports.resetPendingFailures = resetPendingFailures;
|
|
44
45
|
exports.processToolOutcome = processToolOutcome;
|
|
45
46
|
exports.processUserInput = processUserInput;
|
|
46
47
|
exports.processSessionEnd = processSessionEnd;
|
|
47
48
|
exports.processPreCompact = processPreCompact;
|
|
48
49
|
const shared_1 = require("../hooks/shared");
|
|
50
|
+
const memory_1 = require("../services/memory");
|
|
49
51
|
const outcome_storage_1 = require("../services/outcome-storage");
|
|
50
52
|
let logFn = () => { }; // silent by default
|
|
51
53
|
/** Set the log function (hookLog for CC hooks, console for Pi, etc.) */
|
|
52
54
|
function setLogFunction(fn) {
|
|
53
55
|
logFn = fn;
|
|
54
56
|
}
|
|
57
|
+
const MAX_PENDING = 10;
|
|
58
|
+
const FIX_WINDOW_MS = 5 * 60 * 1000; // 5 minutes
|
|
59
|
+
const FIX_SIMILARITY_THRESHOLD = 0.3;
|
|
60
|
+
let pendingFailures = [];
|
|
61
|
+
/** Reset pending failures (e.g. on session start). */
|
|
62
|
+
function resetPendingFailures() {
|
|
63
|
+
pendingFailures = [];
|
|
64
|
+
}
|
|
65
|
+
/** Extract an identifier string from tool input for similarity comparison. */
|
|
66
|
+
function getToolIdentifier(toolName, toolInput) {
|
|
67
|
+
if ((toolName === 'Bash' || toolName === 'bash') && toolInput?.command) {
|
|
68
|
+
return toolInput.command;
|
|
69
|
+
}
|
|
70
|
+
if (toolInput?.file_path) {
|
|
71
|
+
return `${toolName}:${toolInput.file_path}`;
|
|
72
|
+
}
|
|
73
|
+
return toolName;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if a successful tool result matches a recent failure and pair the fix.
|
|
77
|
+
* Returns true if a fix was paired.
|
|
78
|
+
*/
|
|
79
|
+
function tryPairFix(toolName, toolInput, output) {
|
|
80
|
+
if (pendingFailures.length === 0)
|
|
81
|
+
return false;
|
|
82
|
+
const now = Date.now();
|
|
83
|
+
const identifier = getToolIdentifier(toolName, toolInput);
|
|
84
|
+
let matched = false;
|
|
85
|
+
const remaining = [];
|
|
86
|
+
for (const pf of pendingFailures) {
|
|
87
|
+
if (now - pf.timestamp > FIX_WINDOW_MS)
|
|
88
|
+
continue; // expired
|
|
89
|
+
if (!matched && pf.toolName === toolName &&
|
|
90
|
+
(0, shared_1.jaccardSimilarity)(pf.identifier, identifier) >= FIX_SIMILARITY_THRESHOLD) {
|
|
91
|
+
try {
|
|
92
|
+
memory_1.MemoryService.getInstance().update(pf.memoryKey, {
|
|
93
|
+
value: { what_should_do: `Fix: ${truncate(identifier, 200)}` },
|
|
94
|
+
});
|
|
95
|
+
logFn('event-processor', `Paired fix: "${truncate(identifier, 60)}" → ${pf.memoryKey}`);
|
|
96
|
+
matched = true;
|
|
97
|
+
// Don't add to remaining — consumed
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
remaining.push(pf); // keep if update fails
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
remaining.push(pf);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
pendingFailures = remaining;
|
|
108
|
+
return matched;
|
|
109
|
+
}
|
|
55
110
|
// --- Tool Outcome Processing ---
|
|
56
111
|
/** Error patterns for Edit/Write tools */
|
|
57
112
|
const WRITE_ERROR_PATTERNS = [
|
|
@@ -81,6 +136,7 @@ function firstLine(s) {
|
|
|
81
136
|
}
|
|
82
137
|
/**
|
|
83
138
|
* Process a tool outcome — capture failures as memories, record outcome events.
|
|
139
|
+
* When a tool succeeds after a similar recent failure, pairs the fix.
|
|
84
140
|
* Works for any tool type (Bash, Edit, Write, MCP, generic).
|
|
85
141
|
*/
|
|
86
142
|
function processToolOutcome(toolName, toolInput, toolOutput, isError, sessionId) {
|
|
@@ -89,9 +145,14 @@ function processToolOutcome(toolName, toolInput, toolOutput, isError, sessionId)
|
|
|
89
145
|
if (toolName.includes('claude-recall') || toolName.includes('claude_recall') ||
|
|
90
146
|
toolName.startsWith('recall_'))
|
|
91
147
|
return;
|
|
92
|
-
|
|
148
|
+
const isFail = isError || isToolFailureOutput(toolName, toolOutput);
|
|
149
|
+
if (isFail) {
|
|
93
150
|
storeToolFailure(toolName, toolInput, toolOutput, sessionId);
|
|
94
151
|
}
|
|
152
|
+
else {
|
|
153
|
+
// Success — check if this fixes a recent failure
|
|
154
|
+
tryPairFix(toolName, toolInput, toolOutput);
|
|
155
|
+
}
|
|
95
156
|
// Record outcome event for all tools
|
|
96
157
|
recordOutcomeEvent(toolName, toolInput, toolOutput);
|
|
97
158
|
}
|
|
@@ -136,7 +197,19 @@ function storeToolFailure(toolName, toolInput, output, sessionId) {
|
|
|
136
197
|
context: `${toolName} error`,
|
|
137
198
|
preventative_checks: ['Verify inputs are correct', 'Check preconditions'],
|
|
138
199
|
};
|
|
139
|
-
|
|
200
|
+
const key = `hook_failure_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
201
|
+
memory_1.MemoryService.getInstance().store({
|
|
202
|
+
key,
|
|
203
|
+
value: failureContent,
|
|
204
|
+
type: 'failure',
|
|
205
|
+
context: { timestamp: Date.now() },
|
|
206
|
+
relevanceScore: 0.75,
|
|
207
|
+
});
|
|
208
|
+
// Track for fix pairing — when a similar tool succeeds, we update this memory
|
|
209
|
+
const identifier = getToolIdentifier(toolName, toolInput);
|
|
210
|
+
pendingFailures.push({ toolName, identifier, memoryKey: key, timestamp: Date.now() });
|
|
211
|
+
while (pendingFailures.length > MAX_PENDING)
|
|
212
|
+
pendingFailures.shift();
|
|
140
213
|
logFn('event-processor', `Stored failure: ${truncate(whatFailed, 60)}`);
|
|
141
214
|
}
|
|
142
215
|
function recordOutcomeEvent(toolName, toolInput, output) {
|
package/package.json
CHANGED