claude-recall 0.15.35 → 0.16.0
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 +4 -1
- package/.claude/skills/auto-corrections/manifest.json +6 -3
- package/.claude/skills/auto-failure-lessons/SKILL.md +11 -1
- package/.claude/skills/auto-failure-lessons/manifest.json +13 -3
- package/.claude/skills/auto-preferences/SKILL.md +16 -1
- package/.claude/skills/auto-preferences/manifest.json +18 -3
- package/README.md +52 -63
- package/dist/cli/claude-recall-cli.js +11 -1
- package/dist/cli/commands/hook-commands.js +6 -1
- package/dist/hooks/memory-sync-hook.js +189 -0
- 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 19 memories. Last updated: 2026-03-16.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
@@ -21,6 +21,9 @@ Auto-generated from 16 memories. Last updated: 2026-03-13.
|
|
|
21
21
|
- CORRECTION: Memory with complex metadata
|
|
22
22
|
- CORRECTION: Memory with complex metadata
|
|
23
23
|
- CORRECTION: Memory with complex metadata
|
|
24
|
+
- CORRECTION: Memory with complex metadata
|
|
25
|
+
- CORRECTION: Memory with complex metadata
|
|
26
|
+
- CORRECTION: Memory with complex metadata
|
|
24
27
|
- CORRECTION: Replace expired access token with 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
|
|
25
28
|
- CORRECTION: use spaces not tabs for indentation
|
|
26
29
|
- CORRECTION: cited (loaded 5+ times): 19
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "corrections",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-03-
|
|
3
|
+
"sourceHash": "a0d5ebfdc3b3ad70a29a38511679290d1e2918e5c7c3a4b856c0da65595c81ed",
|
|
4
|
+
"memoryCount": 19,
|
|
5
|
+
"generatedAt": "2026-03-16T10:21:29.906Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1773656489899_l75d50pxo",
|
|
8
|
+
"memory_1773654956776_7mffm1tp2",
|
|
9
|
+
"memory_1773410782442_mnfvdml5n",
|
|
7
10
|
"memory_1773409168373_t4lqoqpiv",
|
|
8
11
|
"memory_1773220863163_q8k0ewti8",
|
|
9
12
|
"memory_1773140547102_2wmy0cfga",
|
|
@@ -8,11 +8,19 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Failure Lessons
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 23 memories. Last updated: 2026-03-16.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
15
|
- SQLite query syntax error: LIKE clause requires single quotes around string literal, not double quotes
|
|
16
|
+
- Avoid: Command failed: npm whoami 2>&1 && npm config get registry 2>&1 → Instead: Check command syntax, file paths, and prerequisites before running
|
|
17
|
+
- npm install -g claude-recall@0.15.36 failed with notarget error
|
|
18
|
+
- claude-recall@0.15.36 does not exist on npm registry (ETARGET error)
|
|
19
|
+
- npm install failed: claude-recall@0.15.36 version not found in registry
|
|
20
|
+
- npm package claude-recall@0.15.36 does not exist - version not found in registry
|
|
21
|
+
- npm package claude-recall@0.15.36 not found - version does not exist in registry
|
|
22
|
+
- Claude-recall MCP Server failed to start with npx claude-recall@latest mcp start
|
|
23
|
+
- Claude-recall MCP Server failed to start with command: npx -y claude-recall@latest mcp start
|
|
16
24
|
- Avoid: Command failed: npm run build 2>&1 | tail -3 && npm test 2>&1 → Instead: Check command syntax, file paths, and prerequisites before running
|
|
17
25
|
- Avoid: Command failed: npx jest tests/unit/failure-detectors.test.ts 2>&1 → Instead: Check command syntax, file paths, and prerequisites before running
|
|
18
26
|
- Missing dependency: better-sqlite3 module not installed
|
|
@@ -22,6 +30,8 @@ Auto-generated from 13 memories. Last updated: 2026-03-10.
|
|
|
22
30
|
- npm package claude-recall@0.15.14 not found in registry - 404 error during installation
|
|
23
31
|
- Avoid: Test command reported failures: npx jest tests/unit/failure-detectors.test.ts 2>&1 → Instead: Read test output carefully — exit code 0 does not mean all tests passed
|
|
24
32
|
- Node.js -e flag cannot parse multiline strings with unescaped newlines in single quotes
|
|
33
|
+
- claude-recall reconnection failed after reinstall
|
|
34
|
+
- claude-recall reconnection failed after reinstall attempt
|
|
25
35
|
- Output is showing '>' instead of expected response
|
|
26
36
|
- Code output returns '>' instead of expected response
|
|
27
37
|
- Avoid: Claude backtracked: "let me try a different approach" → Instead: Consider the problem more carefully before starting. Check for similar past failures.
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "failure-lessons",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-03-
|
|
3
|
+
"sourceHash": "6c18a22368601e246196934bc675b7cc11619a20758e5a8067886375b499dd00",
|
|
4
|
+
"memoryCount": 23,
|
|
5
|
+
"generatedAt": "2026-03-16T09:55:56.753Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
7
|
"hook_failure_1772637584921_0tj4rrxnt",
|
|
8
|
+
"hook_failure_non-zero-exit_1773409269877_ful451241",
|
|
9
|
+
"hook_failure_1773410916808_5k1r6zo4u",
|
|
10
|
+
"hook_failure_1773410916789_xtrb8j9nw",
|
|
11
|
+
"hook_failure_1773410910825_rd25wy0tf",
|
|
12
|
+
"hook_failure_1773410885720_u05tuf2dk",
|
|
13
|
+
"hook_failure_1773410874391_kbnfssg62",
|
|
14
|
+
"hook_failure_1773409616313_gmsfcbuzh",
|
|
15
|
+
"hook_failure_1773409607268_83ie5yunz",
|
|
8
16
|
"hook_failure_non-zero-exit_1773068793859_0z0ah0743",
|
|
9
17
|
"hook_failure_non-zero-exit_1772640279977_g3gwlfoqi",
|
|
10
18
|
"hook_failure_1772637646276_ow6m7pr34",
|
|
@@ -14,6 +22,8 @@
|
|
|
14
22
|
"hook_failure_1771937269919_jx3wvpyxq",
|
|
15
23
|
"hook_failure_silent-test-failure_1772640279996_m8f3ks8fw",
|
|
16
24
|
"hook_failure_1772637495154_i21dho3dv",
|
|
25
|
+
"hook_failure_1773410663873_oegccxk83",
|
|
26
|
+
"hook_failure_1773410656672_kno1aw8wf",
|
|
17
27
|
"hook_failure_1772637391602_cjj3esg33",
|
|
18
28
|
"hook_failure_1772637376157_hvco6jbm4",
|
|
19
29
|
"hook_failure_backtracking_1772640280006_snb0x5cgg"
|
|
@@ -8,10 +8,25 @@ source: claude-recall
|
|
|
8
8
|
|
|
9
9
|
# Preferences
|
|
10
10
|
|
|
11
|
-
Auto-generated from
|
|
11
|
+
Auto-generated from 81 memories. Last updated: 2026-03-16.
|
|
12
12
|
|
|
13
13
|
## Rules
|
|
14
14
|
|
|
15
|
+
- Session test preference 1773656489963
|
|
16
|
+
- Test preference 1773656489911-2
|
|
17
|
+
- Test preference 1773656489911-1
|
|
18
|
+
- Test preference 1773656489911-0
|
|
19
|
+
- Test memory content
|
|
20
|
+
- Session test preference 1773654956838
|
|
21
|
+
- Test preference 1773654956788-2
|
|
22
|
+
- Test preference 1773654956788-1
|
|
23
|
+
- Test preference 1773654956788-0
|
|
24
|
+
- Test memory content
|
|
25
|
+
- Session test preference 1773410782522
|
|
26
|
+
- Test preference 1773410782456-2
|
|
27
|
+
- Test preference 1773410782456-1
|
|
28
|
+
- Test preference 1773410782456-0
|
|
29
|
+
- Test memory content
|
|
15
30
|
- Session test preference 1773409168447
|
|
16
31
|
- Test preference 1773409168387-2
|
|
17
32
|
- Test preference 1773409168387-1
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"topicId": "preferences",
|
|
3
|
-
"sourceHash": "
|
|
4
|
-
"memoryCount":
|
|
5
|
-
"generatedAt": "2026-03-
|
|
3
|
+
"sourceHash": "3dce40a1ad092880b2f8005a2c3f9982e37775ef0886a74f329ef1b167c409ce",
|
|
4
|
+
"memoryCount": 81,
|
|
5
|
+
"generatedAt": "2026-03-16T10:21:29.975Z",
|
|
6
6
|
"memoryKeys": [
|
|
7
|
+
"memory_1773656489964_tpm4ycfc1",
|
|
8
|
+
"memory_1773656489936_29pvxu7ni",
|
|
9
|
+
"memory_1773656489924_ick7951wj",
|
|
10
|
+
"memory_1773656489912_w54afewzm",
|
|
11
|
+
"memory_1773656489839_ij3r3sg2s",
|
|
12
|
+
"memory_1773654956839_pluovrk77",
|
|
13
|
+
"memory_1773654956815_ofh9by5rb",
|
|
14
|
+
"memory_1773654956802_24y27xjux",
|
|
15
|
+
"memory_1773654956790_pnrio2ihb",
|
|
16
|
+
"memory_1773654956712_hnjabccni",
|
|
17
|
+
"memory_1773410782523_k5hjje6pt",
|
|
18
|
+
"memory_1773410782491_zbm4dcqvl",
|
|
19
|
+
"memory_1773410782472_t0nrgizx2",
|
|
20
|
+
"memory_1773410782457_eca2hxqcs",
|
|
21
|
+
"memory_1773410782389_ehwhx4mov",
|
|
7
22
|
"memory_1773409168448_lp6jbcq6o",
|
|
8
23
|
"memory_1773409168422_x97lwordj",
|
|
9
24
|
"memory_1773409168407_gjxhfjl1u",
|
package/README.md
CHANGED
|
@@ -31,11 +31,10 @@ Your preferences, project structure, workflows, corrections, and coding style ar
|
|
|
31
31
|
### Install & Activate
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
npx claude-recall --version
|
|
34
|
+
npm install -g claude-recall
|
|
35
|
+
claude mcp remove claude-recall 2>/dev/null; claude mcp add claude-recall -s user -- claude-recall mcp start
|
|
36
|
+
cd your-project && claude-recall setup --install
|
|
37
|
+
claude-recall --version
|
|
39
38
|
```
|
|
40
39
|
|
|
41
40
|
Then restart your terminal or Claude Code session.
|
|
@@ -56,6 +55,7 @@ Once installed, Claude Recall works automatically in the background:
|
|
|
56
55
|
2. **As you work** — the `correction-detector` hook classifies every prompt you type. Natural statements like *"we use tabs here"* or *"no, put tests in `__tests__/`"* are detected and stored automatically
|
|
57
56
|
3. **End of turn** — the `memory-stop` hook scans recent transcript entries for corrections, preferences, failures, and devops patterns
|
|
58
57
|
4. **Before context compression** — the `precompact-preserve` hook sweeps up to 50 entries so nothing important is lost when the context window shrinks
|
|
58
|
+
5. **Rules sync to auto-memory** — the `memory-sync` hook exports active rules to `~/.claude/projects/{project}/memory/recall-rules.md` so they're available even when the MCP server is down
|
|
59
59
|
|
|
60
60
|
All classification uses Claude Haiku (via `ANTHROPIC_API_KEY` from your Claude Code session) with silent regex fallback. No configuration needed.
|
|
61
61
|
|
|
@@ -64,8 +64,8 @@ All classification uses Claude Haiku (via `ANTHROPIC_API_KEY` from your Claude C
|
|
|
64
64
|
```bash
|
|
65
65
|
# Verify it's working
|
|
66
66
|
cat ~/.claude-recall/hook-logs/correction-detector.log
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
claude-recall stats
|
|
68
|
+
claude-recall search "preference"
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
---
|
|
@@ -88,12 +88,12 @@ Claude Recall runs as an MCP server exposing four tools, backed by a local SQLit
|
|
|
88
88
|
### Common Commands
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
claude-recall stats # Memory statistics
|
|
92
|
+
claude-recall search "query" # Search memories
|
|
93
|
+
claude-recall failures # View failure memories
|
|
94
|
+
claude-recall export backup.json # Export memories to JSON
|
|
95
|
+
claude-recall import backup.json # Import memories from JSON
|
|
96
|
+
claude-recall --version # Check version
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
<details>
|
|
@@ -101,53 +101,54 @@ npx claude-recall --version # Check version
|
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
103
|
# ── Upgrade ──────────────────────────────────────────────────────────
|
|
104
|
-
npm
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
npm install -g claude-recall@latest
|
|
105
|
+
claude-recall setup --install # Re-register hooks + skills
|
|
106
|
+
claude-recall --version # Verify
|
|
107
107
|
|
|
108
108
|
# ── Setup & Diagnostics ─────────────────────────────────────────────
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
claude-recall setup # Show activation instructions
|
|
110
|
+
claude-recall setup --install # Install skills + hooks
|
|
111
|
+
claude-recall status # Installation and system status
|
|
112
|
+
claude-recall repair # Clean up old hooks, install skills
|
|
113
113
|
|
|
114
114
|
# ── Memory ───────────────────────────────────────────────────────────
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
claude-recall stats # Memory statistics
|
|
116
|
+
claude-recall search "query" # Search memories
|
|
117
|
+
claude-recall store "content" # Store memory directly
|
|
118
|
+
claude-recall export backup.json # Export memories to JSON
|
|
119
|
+
claude-recall import backup.json # Import memories from JSON
|
|
120
|
+
claude-recall clear --force # Clear all memories
|
|
121
|
+
claude-recall failures # View failure memories
|
|
122
|
+
claude-recall failures --limit 20 # Limit results
|
|
123
|
+
claude-recall monitor # Memory search monitoring stats
|
|
124
124
|
|
|
125
125
|
# ── Skills ───────────────────────────────────────────────────────────
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
claude-recall skills generate # Generate skills from memories
|
|
127
|
+
claude-recall skills generate --dry-run # Preview without writing
|
|
128
|
+
claude-recall skills generate --force # Regenerate even if unchanged
|
|
129
|
+
claude-recall skills list # List generated skills
|
|
130
|
+
claude-recall skills clean --force # Remove all auto-generated skills
|
|
131
131
|
|
|
132
132
|
# ── MCP Server ───────────────────────────────────────────────────────
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
claude-recall mcp status # Current project's server status
|
|
134
|
+
claude-recall mcp ps # List all running servers
|
|
135
|
+
claude-recall mcp stop # Stop server
|
|
136
|
+
claude-recall mcp stop --force # Force stop
|
|
137
|
+
claude-recall mcp restart # Restart server
|
|
138
|
+
claude-recall mcp cleanup # Remove stale PID files
|
|
139
|
+
claude-recall mcp cleanup --all # Stop all servers
|
|
140
140
|
|
|
141
141
|
# ── Project ──────────────────────────────────────────────────────────
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
claude-recall project show # Current project info
|
|
143
|
+
claude-recall project list # All registered projects
|
|
144
|
+
claude-recall project register # Register current project
|
|
145
|
+
claude-recall project clean # Remove stale registry entries
|
|
146
146
|
|
|
147
147
|
# ── Auto-Capture Hooks (run automatically, registered via setup --install) ──
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
claude-recall hook run correction-detector # UserPromptSubmit hook
|
|
149
|
+
claude-recall hook run memory-stop # Stop hook
|
|
150
|
+
claude-recall hook run precompact-preserve # PreCompact hook
|
|
151
|
+
claude-recall hook run memory-sync # Stop + PreCompact hook (syncs rules to auto-memory)
|
|
151
152
|
```
|
|
152
153
|
|
|
153
154
|
</details>
|
|
@@ -176,23 +177,11 @@ Details in [docs/security.md](docs/security.md).
|
|
|
176
177
|
<details>
|
|
177
178
|
<summary>WSL Users</summary>
|
|
178
179
|
|
|
179
|
-
If you hit "invalid ELF header" errors from mixed Windows/WSL `node_modules`,
|
|
180
|
+
If you hit "invalid ELF header" errors from mixed Windows/WSL `node_modules`, ensure you're using the global install (now the default). Verify the binary resolves to a Linux path:
|
|
180
181
|
|
|
181
182
|
```bash
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
Update `~/.claude.json` to use the global binary:
|
|
186
|
-
|
|
187
|
-
```json
|
|
188
|
-
{
|
|
189
|
-
"claude-recall": {
|
|
190
|
-
"type": "stdio",
|
|
191
|
-
"command": "claude-recall",
|
|
192
|
-
"args": ["mcp", "start"],
|
|
193
|
-
"env": {}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
183
|
+
which claude-recall
|
|
184
|
+
# Should show: /home/<user>/.nvm/.../bin/claude-recall (NOT a Windows path)
|
|
196
185
|
```
|
|
197
186
|
|
|
198
187
|
Global installation does **not** affect project scoping — project ID is still detected from Claude Code's working directory.
|
|
@@ -608,7 +608,7 @@ async function main() {
|
|
|
608
608
|
// This avoids registry lookups on every hook invocation.
|
|
609
609
|
const cliScript = path.join(packageDir, 'dist', 'cli', 'claude-recall-cli.js');
|
|
610
610
|
const hookCmd = `node ${cliScript} hook run`;
|
|
611
|
-
settings.hooksVersion = '
|
|
611
|
+
settings.hooksVersion = '7.0.0'; // v7 = add memory-sync hook for auto-memory export
|
|
612
612
|
settings.hooks = {
|
|
613
613
|
PreToolUse: [
|
|
614
614
|
{
|
|
@@ -638,6 +638,11 @@ async function main() {
|
|
|
638
638
|
type: "command",
|
|
639
639
|
command: `${hookCmd} memory-stop`,
|
|
640
640
|
timeout: 30
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
type: "command",
|
|
644
|
+
command: `${hookCmd} memory-sync`,
|
|
645
|
+
timeout: 10
|
|
641
646
|
}
|
|
642
647
|
]
|
|
643
648
|
}
|
|
@@ -649,6 +654,11 @@ async function main() {
|
|
|
649
654
|
type: "command",
|
|
650
655
|
command: `${hookCmd} precompact-preserve`,
|
|
651
656
|
timeout: 60
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
type: "command",
|
|
660
|
+
command: `${hookCmd} memory-sync`,
|
|
661
|
+
timeout: 10
|
|
652
662
|
}
|
|
653
663
|
]
|
|
654
664
|
}
|
|
@@ -70,9 +70,14 @@ class HookCommands {
|
|
|
70
70
|
await handlePrecompactPreserve(input);
|
|
71
71
|
break;
|
|
72
72
|
}
|
|
73
|
+
case 'memory-sync': {
|
|
74
|
+
const { handleMemorySync } = await Promise.resolve().then(() => __importStar(require('../../hooks/memory-sync-hook')));
|
|
75
|
+
await handleMemorySync(input);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
73
78
|
default:
|
|
74
79
|
console.error(`Unknown hook: ${name}`);
|
|
75
|
-
console.error('Available: correction-detector, memory-stop, precompact-preserve');
|
|
80
|
+
console.error('Available: correction-detector, memory-stop, precompact-preserve, memory-sync');
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
catch {
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* memory-sync-hook — fires on Stop and PreCompact events.
|
|
4
|
+
*
|
|
5
|
+
* Exports active rules from Claude Recall's SQLite database to a topic file
|
|
6
|
+
* in Claude Code's auto-memory directory, so rules are available even when
|
|
7
|
+
* the MCP server is down.
|
|
8
|
+
*
|
|
9
|
+
* Input: { session_id, cwd, hook_event_name }
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.deriveAutoMemoryPath = deriveAutoMemoryPath;
|
|
46
|
+
exports.handleMemorySync = handleMemorySync;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const os = __importStar(require("os"));
|
|
50
|
+
const shared_1 = require("./shared");
|
|
51
|
+
const memory_1 = require("../services/memory");
|
|
52
|
+
const config_1 = require("../services/config");
|
|
53
|
+
/** Keys that look like test data */
|
|
54
|
+
const TEST_KEY_PATTERNS = [/^Test /i, /^Session test /i, /^test_/i];
|
|
55
|
+
/** Values that may contain secrets */
|
|
56
|
+
const SECRET_PATTERNS = [/api_key/i, /token/i, /password/i, /secret/i, /credential/i, /private_key/i];
|
|
57
|
+
/**
|
|
58
|
+
* Derive the auto-memory directory path from a cwd.
|
|
59
|
+
* Matches Claude Code's convention: ~/.claude/projects/{cwd with / replaced by -}/memory/
|
|
60
|
+
*/
|
|
61
|
+
function deriveAutoMemoryPath(cwd, homedir) {
|
|
62
|
+
const home = homedir || os.homedir();
|
|
63
|
+
const sanitized = cwd.replace(/\//g, '-');
|
|
64
|
+
return path.join(home, '.claude', 'projects', sanitized, 'memory');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract display value from a memory record, matching memory-tools.ts formatting.
|
|
68
|
+
*/
|
|
69
|
+
function extractValue(m) {
|
|
70
|
+
const val = typeof m.value === 'object'
|
|
71
|
+
? (m.value.content || m.value.value || JSON.stringify(m.value))
|
|
72
|
+
: m.value;
|
|
73
|
+
return String(val);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if a memory key matches test data patterns.
|
|
77
|
+
*/
|
|
78
|
+
function isTestData(key) {
|
|
79
|
+
return TEST_KEY_PATTERNS.some(p => p.test(key));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if a value contains secret-like content.
|
|
83
|
+
*/
|
|
84
|
+
function containsSecret(value) {
|
|
85
|
+
return SECRET_PATTERNS.some(p => p.test(value));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Format rules into markdown sections.
|
|
89
|
+
*/
|
|
90
|
+
function formatRulesMarkdown(rules) {
|
|
91
|
+
const sections = [];
|
|
92
|
+
sections.push('<!-- Auto-generated by Claude Recall — overwritten each session -->');
|
|
93
|
+
sections.push('# Claude Recall Rules');
|
|
94
|
+
if (rules.preferences.length > 0) {
|
|
95
|
+
sections.push('\n## Preferences');
|
|
96
|
+
for (const m of rules.preferences) {
|
|
97
|
+
const val = extractValue(m);
|
|
98
|
+
const key = m.preference_key || m.key || '';
|
|
99
|
+
const isAutoKey = key.startsWith('memory_') || key.startsWith('auto_') || key.startsWith('pref_') || key.startsWith('hook_');
|
|
100
|
+
sections.push(isAutoKey ? `- ${val}` : `- ${key}: ${val}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (rules.corrections.length > 0) {
|
|
104
|
+
sections.push('\n## Corrections');
|
|
105
|
+
for (const m of rules.corrections) {
|
|
106
|
+
sections.push(`- ${extractValue(m)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (rules.failures.length > 0) {
|
|
110
|
+
sections.push('\n## Failures');
|
|
111
|
+
for (const m of rules.failures) {
|
|
112
|
+
sections.push(`- ${extractValue(m)}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (rules.devops.length > 0) {
|
|
116
|
+
sections.push('\n## DevOps Rules');
|
|
117
|
+
for (const m of rules.devops) {
|
|
118
|
+
sections.push(`- ${extractValue(m)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
sections.push(`\n---\n*Last synced: ${new Date().toISOString()}*`);
|
|
122
|
+
return sections.join('\n') + '\n';
|
|
123
|
+
}
|
|
124
|
+
const MEMORY_MD_POINTER = `\n## Claude Recall\n- See [recall-rules.md](recall-rules.md) for learned preferences, corrections, and failure lessons\n`;
|
|
125
|
+
/**
|
|
126
|
+
* Ensure MEMORY.md contains a pointer to recall-rules.md.
|
|
127
|
+
* Appends the pointer only if absent. Never overwrites existing content.
|
|
128
|
+
*/
|
|
129
|
+
function ensureMemoryMdPointer(memoryDir) {
|
|
130
|
+
const memoryMdPath = path.join(memoryDir, 'MEMORY.md');
|
|
131
|
+
let existing = '';
|
|
132
|
+
if (fs.existsSync(memoryMdPath)) {
|
|
133
|
+
existing = fs.readFileSync(memoryMdPath, 'utf-8');
|
|
134
|
+
}
|
|
135
|
+
if (existing.includes('recall-rules.md')) {
|
|
136
|
+
return; // Pointer already present
|
|
137
|
+
}
|
|
138
|
+
fs.appendFileSync(memoryMdPath, MEMORY_MD_POINTER);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Filter out test data and secrets from rules.
|
|
142
|
+
*/
|
|
143
|
+
function filterRules(memories) {
|
|
144
|
+
return memories.filter(m => {
|
|
145
|
+
const key = m.preference_key || m.key || '';
|
|
146
|
+
if (isTestData(key))
|
|
147
|
+
return false;
|
|
148
|
+
const val = extractValue(m);
|
|
149
|
+
if (containsSecret(val))
|
|
150
|
+
return false;
|
|
151
|
+
return true;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async function handleMemorySync(input) {
|
|
155
|
+
const cwd = input?.cwd ?? '';
|
|
156
|
+
if (!cwd) {
|
|
157
|
+
(0, shared_1.hookLog)('memory-sync', 'No cwd provided — skipping sync');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const projectId = config_1.ConfigService.getInstance().getProjectId();
|
|
162
|
+
const memoryService = memory_1.MemoryService.getInstance();
|
|
163
|
+
const rules = memoryService.loadActiveRules(projectId);
|
|
164
|
+
// Filter each category
|
|
165
|
+
const filtered = {
|
|
166
|
+
preferences: filterRules(rules.preferences),
|
|
167
|
+
corrections: filterRules(rules.corrections),
|
|
168
|
+
failures: filterRules(rules.failures),
|
|
169
|
+
devops: filterRules(rules.devops),
|
|
170
|
+
};
|
|
171
|
+
const totalRules = filtered.preferences.length + filtered.corrections.length +
|
|
172
|
+
filtered.failures.length + filtered.devops.length;
|
|
173
|
+
// Derive auto-memory path and ensure directory exists
|
|
174
|
+
const memoryDir = deriveAutoMemoryPath(cwd);
|
|
175
|
+
if (!fs.existsSync(memoryDir)) {
|
|
176
|
+
fs.mkdirSync(memoryDir, { recursive: true });
|
|
177
|
+
}
|
|
178
|
+
// Write recall-rules.md (full overwrite)
|
|
179
|
+
const markdown = formatRulesMarkdown(filtered);
|
|
180
|
+
const rulesPath = path.join(memoryDir, 'recall-rules.md');
|
|
181
|
+
fs.writeFileSync(rulesPath, markdown);
|
|
182
|
+
// Ensure MEMORY.md has pointer
|
|
183
|
+
ensureMemoryMdPointer(memoryDir);
|
|
184
|
+
(0, shared_1.hookLog)('memory-sync', `Synced ${totalRules} rules to ${rulesPath}`);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
(0, shared_1.hookLog)('memory-sync', `Error: ${error.message}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-recall",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
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": {
|