claude-recall 0.20.0 → 0.20.1

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.
@@ -8,13 +8,14 @@ source: claude-recall
8
8
 
9
9
  # Corrections
10
10
 
11
- Auto-generated from 5 memories. Last updated: 2026-04-02.
11
+ Auto-generated from 6 memories. Last updated: 2026-04-02.
12
12
 
13
13
  ## Rules
14
14
 
15
15
  - CORRECTION: Memory with complex metadata
16
16
  - CORRECTION: Memory with complex metadata
17
17
  - CORRECTION: Memory with complex metadata
18
+ - CORRECTION: Memory with complex metadata
18
19
  - CORRECTION: License copyright should include user's name instead of 'Claude Recall Contributors'
19
20
  - CORRECTION: License copyright should list your name instead of 'Claude Recall Contributors'
20
21
 
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "topicId": "corrections",
3
- "sourceHash": "a88187b382c2104a20922fd98e9de60d9ef6434a0a5e25f03a011998b491290f",
4
- "memoryCount": 5,
5
- "generatedAt": "2026-04-02T19:49:59.553Z",
3
+ "sourceHash": "b1b937b59846b125f1209888415c3c3ba1eb668bee822d20b08fd6a70783510f",
4
+ "memoryCount": 6,
5
+ "generatedAt": "2026-04-02T20:13:01.816Z",
6
6
  "memoryKeys": [
7
+ "memory_1775160781806_vnqf355e9",
7
8
  "memory_1775159399542_awfryrxp3",
8
9
  "memory_1775157082825_8uvrul28i",
9
10
  "memory_1775156381094_dr1nihes8",
@@ -8,10 +8,15 @@ source: claude-recall
8
8
 
9
9
  # Preferences
10
10
 
11
- Auto-generated from 17 memories. Last updated: 2026-04-02.
11
+ Auto-generated from 22 memories. Last updated: 2026-04-02.
12
12
 
13
13
  ## Rules
14
14
 
15
+ - Session test preference 1775160781884
16
+ - Test preference 1775160781820-2
17
+ - Test preference 1775160781820-1
18
+ - Test preference 1775160781820-0
19
+ - Test memory content
15
20
  - Session test preference 1775159399698
16
21
  - Test preference 1775159399559-2
17
22
  - Test preference 1775159399559-1
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "topicId": "preferences",
3
- "sourceHash": "13276d13523c8f8ec13ae9948cfa0e2cdd8ca5cd0fd6453b544307ae47d91df5",
4
- "memoryCount": 17,
5
- "generatedAt": "2026-04-02T19:49:59.727Z",
3
+ "sourceHash": "d26df6886905013086073ba0031b5e052ec17ae91863e95938269e72d1d5a556",
4
+ "memoryCount": 22,
5
+ "generatedAt": "2026-04-02T20:13:01.897Z",
6
6
  "memoryKeys": [
7
+ "memory_1775160781885_fkbnc0s85",
8
+ "memory_1775160781857_gj5y299dr",
9
+ "memory_1775160781842_0xmv146n5",
10
+ "memory_1775160781821_o9ipt8nsc",
11
+ "memory_1775160781747_70e5gbp7j",
7
12
  "memory_1775159399702_yg6ynd05n",
8
13
  "memory_1775159399631_fmy4s2vhr",
9
14
  "memory_1775159399606_xymkvcjfv",
@@ -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
- if (isError || isToolFailureOutput(toolName, toolOutput)) {
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
- (0, shared_1.storeMemory)(JSON.stringify(failureContent), 'failure', undefined, 0.75);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-recall",
3
- "version": "0.20.0",
3
+ "version": "0.20.1",
4
4
  "description": "Persistent memory for Claude Code and Pi with native Skills integration, automatic capture, failure learning, and project scoping",
5
5
  "main": "dist/index.js",
6
6
  "bin": {