claude-memory-hub 0.4.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/CHANGELOG.md +140 -0
- package/LICENSE +21 -0
- package/README.md +281 -0
- package/dist/cli.js +167 -0
- package/dist/hooks/post-compact.js +892 -0
- package/dist/hooks/post-tool-use.js +740 -0
- package/dist/hooks/pre-compact.js +892 -0
- package/dist/hooks/session-end.js +811 -0
- package/dist/hooks/user-prompt-submit.js +744 -0
- package/dist/index.js +14443 -0
- package/package.json +56 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `claude-memory-hub` are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## [0.4.0] - 2026-04-01
|
|
9
|
+
|
|
10
|
+
### Problem
|
|
11
|
+
Every Claude Code session loads ALL skills, agents, rules, and memory files into context regardless of relevance. Typical overhead: **23-51K tokens** before the user types anything.
|
|
12
|
+
|
|
13
|
+
### Solution — Smart Resource Loader
|
|
14
|
+
- **ResourceTracker** — new `resource_usage` SQLite table automatically tracks which skills, agents, and MCP tools are actually used per session
|
|
15
|
+
- **SmartResourceLoader** — predicts relevant resources for new sessions based on usage frequency and prompt relevance, within a configurable token budget
|
|
16
|
+
- **MCP tool: `memory_context_budget`** — lets Claude analyze token costs and get resource recommendations on demand
|
|
17
|
+
- **PostToolUse auto-tracking** — Skill, Agent, and MCP tool invocations recorded automatically (zero config)
|
|
18
|
+
- **UserPromptSubmit advice injection** — when resources are deferred for efficiency, injects a hint so Claude knows to use SkillTool/ToolSearch on demand
|
|
19
|
+
|
|
20
|
+
### Impact
|
|
21
|
+
```
|
|
22
|
+
BEFORE: 23-51K tokens overhead (all resources loaded)
|
|
23
|
+
AFTER: Only frequently-used resources recommended
|
|
24
|
+
Rare resources loaded on demand via SkillTool
|
|
25
|
+
~10-30K tokens saved per session on heavy setups
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Files
|
|
29
|
+
- `src/context/resource-tracker.ts` — usage tracking + SQLite schema
|
|
30
|
+
- `src/context/smart-resource-loader.ts` — prediction + budgeted context planning
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## [0.3.0] - 2026-04-01
|
|
35
|
+
|
|
36
|
+
### Problem
|
|
37
|
+
v0.2.0 required `@anthropic-ai/sdk` + `ANTHROPIC_API_KEY` for rich session summaries. Users without API key got degraded rule-based summaries. Extra dependency, extra cost, extra friction.
|
|
38
|
+
|
|
39
|
+
### Solution — Zero API Key Architecture
|
|
40
|
+
- **Removed `@anthropic-ai/sdk`** entirely from dependencies
|
|
41
|
+
- **Key insight:** PostCompact hook already receives Claude Code's own compact summary for free — no need to call the API again
|
|
42
|
+
- **Two summarization paths, both free:**
|
|
43
|
+
- Short sessions (no compact) → rule-based summary from L2 entities
|
|
44
|
+
- Long sessions (compact fires) → PostCompact hook captures Claude's summary directly
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- **install.sh** — 1-command installer: `bash install.sh` handles bun install, MCP registration via `claude mcp add -s user`, and hooks patching. Works on CLI, VS Code, JetBrains.
|
|
48
|
+
|
|
49
|
+
### Breaking Changes
|
|
50
|
+
- `@anthropic-ai/sdk` removed — re-run `bash install.sh` to update
|
|
51
|
+
- `ANTHROPIC_API_KEY` env var no longer needed
|
|
52
|
+
|
|
53
|
+
### Dependencies
|
|
54
|
+
```
|
|
55
|
+
KEPT: @modelcontextprotocol/sdk, bun:sqlite (built-in)
|
|
56
|
+
REMOVED: @anthropic-ai/sdk
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## [0.2.0] - 2026-04-01
|
|
62
|
+
|
|
63
|
+
### Problem
|
|
64
|
+
v0.1.0 could not intercept Claude Code's auto-compact. When compact ran, 90% of context was lost and memory-hub had no way to influence what survived. Entity extraction was metadata-only (file paths, exit codes) with no understanding of WHY actions were taken.
|
|
65
|
+
|
|
66
|
+
### Solution — Compact Interceptor (Core Innovation)
|
|
67
|
+
|
|
68
|
+
**PreCompact Hook** — fires BEFORE compact summarization:
|
|
69
|
+
1. Reads all L2 entities (files, decisions, errors)
|
|
70
|
+
2. Scores by `importance * recencyWeight`
|
|
71
|
+
3. Outputs priority list as text
|
|
72
|
+
4. Claude Code **APPENDS** this to the compact prompt as `Additional Instructions`
|
|
73
|
+
5. Result: compact summarizer now **knows** what to preserve
|
|
74
|
+
|
|
75
|
+
**PostCompact Hook** — fires AFTER compact:
|
|
76
|
+
1. Receives the FULL 9-section compact summary via stdin
|
|
77
|
+
2. Saves directly to L3 SQLite
|
|
78
|
+
3. Zero additional information loss
|
|
79
|
+
|
|
80
|
+
### Added — Contextual Entity Enrichment
|
|
81
|
+
- File reads: captures first lines + code patterns (imports, class/function defs)
|
|
82
|
+
- File edits: captures `old_string → new_string` delta
|
|
83
|
+
- File writes: captures line count + content snippet
|
|
84
|
+
- Errors: captures command + stderr + stdout
|
|
85
|
+
- No XML required — parsed directly from tool response JSON
|
|
86
|
+
|
|
87
|
+
### Added — Importance-Weighted Scoring
|
|
88
|
+
| Entity Type | Importance | Example |
|
|
89
|
+
|-------------|-----------|---------|
|
|
90
|
+
| file_created | 4 | New file written |
|
|
91
|
+
| file_modified | 4 | File edited |
|
|
92
|
+
| error (fatal) | 5 | Non-zero exit, crash |
|
|
93
|
+
| error (normal) | 3 | Build warning |
|
|
94
|
+
| decision | 3 | TodoWrite task |
|
|
95
|
+
| file_read | 1 | File opened |
|
|
96
|
+
|
|
97
|
+
Score formula: `importance * (1 / (1 + hoursAgo))`
|
|
98
|
+
|
|
99
|
+
### Breaking Changes
|
|
100
|
+
- Entity extraction returns enriched `context` field — re-run `bash install.sh`
|
|
101
|
+
- 5 hooks instead of 3 (added PreCompact, PostCompact)
|
|
102
|
+
|
|
103
|
+
### Resolved Limitations from v0.1.0
|
|
104
|
+
- ~~Cannot intercept compact~~ → PreCompact + PostCompact hooks
|
|
105
|
+
- ~~No importance scoring~~ → Importance x recency in PreCompact
|
|
106
|
+
- ~~Metadata only, no reasoning~~ → Context enricher with diffs, patterns, stderr
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## [0.1.0] - 2026-04-01
|
|
111
|
+
|
|
112
|
+
### Problem
|
|
113
|
+
Claude Code's built-in memory has 7 critical gaps:
|
|
114
|
+
1. Session memory triggers after 10K tokens — early context lost
|
|
115
|
+
2. Auto-compact loses 90% of information (200K → 20K tokens)
|
|
116
|
+
3. Memory selection is keyword-only (no ranking)
|
|
117
|
+
4. No cross-session carry-over — each session starts from zero
|
|
118
|
+
5. No entity tracking (files touched, decisions made, errors fixed)
|
|
119
|
+
6. Existing solution (claude-mem) requires Claude to output fragile XML format
|
|
120
|
+
7. claude-mem requires Python + Chroma subprocess — heavy operational overhead
|
|
121
|
+
|
|
122
|
+
### Solution — Hierarchical Memory Hub
|
|
123
|
+
- **L1: WorkingMemory** — in-process Map, current session, <1ms access
|
|
124
|
+
- **L2: SessionStore** — SQLite: entities + notes, session-scoped, <10ms
|
|
125
|
+
- **L3: LongTermStore** — SQLite FTS5: cross-session summaries, <100ms
|
|
126
|
+
|
|
127
|
+
### Added
|
|
128
|
+
- **Zero-XML entity extraction** — captures files, errors, decisions from Claude Code hook JSON (tool_name, file_path, exit_code). No special output format required.
|
|
129
|
+
- **SQLite FTS5 search** — BM25-ranked full-text search with automatic LIKE fallback
|
|
130
|
+
- **MCP Server (stdio)** — 4 tools: `memory_recall`, `memory_entities`, `memory_session_notes`, `memory_store`
|
|
131
|
+
- **3 Claude Code hooks** — PostToolUse, UserPromptSubmit, Stop
|
|
132
|
+
- **Progressive 3-layer disclosure** — index (~50 tok), summary (~300 tok), full (~800 tok)
|
|
133
|
+
- **Cross-session carry-over** — past summaries auto-injected at session start
|
|
134
|
+
|
|
135
|
+
### Known Limitations (addressed in later versions)
|
|
136
|
+
- Cannot intercept compact (→ solved in v0.2.0)
|
|
137
|
+
- Metadata only, no reasoning context (→ solved in v0.2.0)
|
|
138
|
+
- Requires API key for rich summaries (→ solved in v0.3.0)
|
|
139
|
+
- No token budget optimization (→ solved in v0.4.0)
|
|
140
|
+
- FTS5 keyword-only search (no vector/semantic — intentional trade-off)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="claude-memory-hub" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">claude-memory-hub</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>The missing memory layer for Claude Code.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/claude-memory-hub"><img src="https://img.shields.io/npm/v/claude-memory-hub.svg" alt="npm version" /></a>
|
|
13
|
+
<a href="https://github.com/TranHoaiHung/claude-memory-hub/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/claude-memory-hub.svg" alt="license" /></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
Zero API key. Zero Python. Zero config. One install command.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## The Problem
|
|
21
|
+
|
|
22
|
+
Claude Code forgets everything between sessions. Within long sessions, auto-compact destroys 90% of context. Every session wastes tokens loading resources that aren't needed.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Session 1: You spend 2 hours building auth system
|
|
26
|
+
Session 2: Claude has no idea what happened yesterday
|
|
27
|
+
|
|
28
|
+
Long session: Claude auto-compacts at 200K tokens
|
|
29
|
+
→ 180K tokens of context vaporized
|
|
30
|
+
→ Claude loses track of files, decisions, errors
|
|
31
|
+
|
|
32
|
+
Every session: ALL skills + agents + rules loaded
|
|
33
|
+
→ 23-51K tokens consumed before you type anything
|
|
34
|
+
→ Most of them never used
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Three problems. No existing tool solves all of them.**
|
|
38
|
+
|
|
39
|
+
| Problem | Claude Code built-in | claude-mem | memory-hub |
|
|
40
|
+
|---------|:-------------------:|:----------:|:----------:|
|
|
41
|
+
| Cross-session memory | -- | Yes | **Yes** |
|
|
42
|
+
| Influence what compact preserves | -- | -- | **Yes** |
|
|
43
|
+
| Save compact output | -- | -- | **Yes** |
|
|
44
|
+
| Token budget optimization | -- | -- | **Yes** |
|
|
45
|
+
| No API key needed | N/A | Yes | **Yes** |
|
|
46
|
+
| No Python/Chroma needed | N/A | -- | **Yes** |
|
|
47
|
+
| No XML format required | N/A | -- | **Yes** |
|
|
48
|
+
| No HTTP server to manage | N/A | -- | **Yes** |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## How It Works
|
|
53
|
+
|
|
54
|
+
### Layer 1 — Entity Capture (every tool call)
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Claude reads a file → memory-hub records: which file, code patterns found
|
|
58
|
+
Claude edits a file → memory-hub records: what changed (old → new diff)
|
|
59
|
+
Claude runs a command → memory-hub records: command, exit code, stderr
|
|
60
|
+
Claude makes a decision → memory-hub records: decision text + importance score
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
No XML. No special format. Extracted directly from hook JSON metadata.
|
|
64
|
+
|
|
65
|
+
### Layer 2 — Compact Interceptor (the key innovation)
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
BEFORE compact runs
|
|
69
|
+
|
|
|
70
|
+
+--------------+--------------+
|
|
71
|
+
| |
|
|
72
|
+
PreCompact hook Claude Code's
|
|
73
|
+
reads all entities compact engine
|
|
74
|
+
scores by importance receives our output
|
|
75
|
+
outputs priority list --> as Additional Instructions
|
|
76
|
+
| |
|
|
77
|
+
| compact now KNOWS
|
|
78
|
+
| what to preserve
|
|
79
|
+
| |
|
|
80
|
+
| AFTER compact runs
|
|
81
|
+
| |
|
|
82
|
+
+-------- PostCompact hook ---+
|
|
83
|
+
receives FULL summary
|
|
84
|
+
saves to SQLite L3
|
|
85
|
+
zero information loss
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**This is something no other memory tool does.** claude-mem never sees the compact. Built-in session memory is supplementary, not directive. memory-hub is the only system that **tells the compact what matters**.
|
|
89
|
+
|
|
90
|
+
### Layer 3 — Cross-Session Memory
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Session N ends → rule-based summary from entities → SQLite L3
|
|
94
|
+
OR PostCompact summary (richer) → SQLite L3
|
|
95
|
+
|
|
96
|
+
Session N+1 → UserPromptSubmit hook fires
|
|
97
|
+
→ FTS5 search: match user prompt against past summaries
|
|
98
|
+
→ inject relevant context automatically
|
|
99
|
+
→ Claude starts with history, not from zero
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Layer 4 — Smart Resource Loading
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
Typical Claude Code session
|
|
106
|
+
|
|
107
|
+
BEFORE memory-hub AFTER memory-hub
|
|
108
|
+
┌──────────────────┐ ┌──────────────────┐
|
|
109
|
+
│ System prompt 8K │ │ System prompt 8K │
|
|
110
|
+
│ ALL skills 10K │ │ Used skills 3K │
|
|
111
|
+
│ ALL agents 5K │ │ Used agents 1K │
|
|
112
|
+
│ ALL rules 15K │ │ Key rules 5K │
|
|
113
|
+
│ ALL memory 5K │ │ Relevant mem 2K │
|
|
114
|
+
├──────────────────┤ ├──────────────────┤
|
|
115
|
+
│ OVERHEAD: ~43K │ │ OVERHEAD: ~19K │
|
|
116
|
+
│ │ │ SAVED: ~24K │
|
|
117
|
+
└──────────────────┘ └──────────────────┘
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
memory-hub tracks which skills/agents/tools you **actually use**, then recommends only those for future sessions. Rare resources load on demand via SkillTool.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Architecture
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
┌──────────────────────────────────────────────────────────┐
|
|
128
|
+
│ Claude Code │
|
|
129
|
+
│ │
|
|
130
|
+
│ 5 Lifecycle Hooks │
|
|
131
|
+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
132
|
+
│ │ PostToolUse │ │ PreCompact │ │ PostCompact │ │
|
|
133
|
+
│ │ entity capture│ │ inject │ │ save summary │ │
|
|
134
|
+
│ └──────┬───────┘ │ priorities │ └──────┬───────┘ │
|
|
135
|
+
│ │ └──────┬───────┘ │ │
|
|
136
|
+
│ ┌──────┴───────┐ │ ┌──────┴───────┐ │
|
|
137
|
+
│ │UserPrompt │ │ │ Stop │ │
|
|
138
|
+
│ │Submit: inject│ │ │ session end │ │
|
|
139
|
+
│ │past context │ │ │ summarize │ │
|
|
140
|
+
│ └──────────────┘ │ └──────────────┘ │
|
|
141
|
+
│ │ │
|
|
142
|
+
│ MCP Server (stdio) │ │
|
|
143
|
+
│ ┌─────────────────────┐ │ │
|
|
144
|
+
│ │ memory_recall │ │ │
|
|
145
|
+
│ │ memory_entities │ │ ┌────────────────────────┐ │
|
|
146
|
+
│ │ memory_session_notes│ │ │ Smart Resource Loader │ │
|
|
147
|
+
│ │ memory_store │ │ │ track usage → predict │ │
|
|
148
|
+
│ │ memory_context_budget│ │ │ → budget → recommend │ │
|
|
149
|
+
│ └─────────────────────┘ │ └────────────────────────┘ │
|
|
150
|
+
│ │ │
|
|
151
|
+
└───────────────────────────┼──────────────────────────────┘
|
|
152
|
+
│
|
|
153
|
+
┌────────┴────────┐
|
|
154
|
+
│ SQLite + FTS5 │
|
|
155
|
+
│ ~/.claude- │
|
|
156
|
+
│ memory-hub/ │
|
|
157
|
+
│ memory.db │
|
|
158
|
+
│ │
|
|
159
|
+
│ sessions │
|
|
160
|
+
│ entities │
|
|
161
|
+
│ session_notes │
|
|
162
|
+
│ long_term_ │
|
|
163
|
+
│ summaries │
|
|
164
|
+
│ resource_usage │
|
|
165
|
+
│ fts_memories │
|
|
166
|
+
└─────────────────┘
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Memory Hierarchy
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
┌─────────────────────────────────────────────────────┐
|
|
175
|
+
│ L1: WorkingMemory in-process Map │
|
|
176
|
+
│ Current session only <1ms access │
|
|
177
|
+
│ Lives in MCP server FIFO 50 entries/session │
|
|
178
|
+
├─────────────────────────────────────────────────────┤
|
|
179
|
+
│ L2: SessionStore SQLite │
|
|
180
|
+
│ Entities + notes <10ms access │
|
|
181
|
+
│ files_read, file_modified Per-session scope │
|
|
182
|
+
│ errors, decisions Importance scored │
|
|
183
|
+
├─────────────────────────────────────────────────────┤
|
|
184
|
+
│ L3: LongTermStore SQLite + FTS5 │
|
|
185
|
+
│ Cross-session summaries <100ms access │
|
|
186
|
+
│ BM25 ranked search Persistent forever │
|
|
187
|
+
│ Auto-injected on start LIKE fallback │
|
|
188
|
+
└─────────────────────────────────────────────────────┘
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Install
|
|
194
|
+
|
|
195
|
+
### From npm (recommended)
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
bunx claude-memory-hub install
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
One command. Registers MCP server + 5 hooks globally. Works on CLI, VS Code, JetBrains.
|
|
202
|
+
|
|
203
|
+
### From source
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
git clone https://github.com/TranHoaiHung/claude-memory-hub.git ~/.claude-memory-hub
|
|
207
|
+
cd ~/.claude-memory-hub
|
|
208
|
+
bun install && bun run build:all
|
|
209
|
+
bunx . install
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Other commands
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
bunx claude-memory-hub status # Check installation
|
|
216
|
+
bunx claude-memory-hub uninstall # Clean removal
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Requirements
|
|
220
|
+
|
|
221
|
+
- [Bun](https://bun.sh) runtime
|
|
222
|
+
- Claude Code (CLI, VS Code, or JetBrains)
|
|
223
|
+
- **No API key needed**
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## MCP Tools
|
|
228
|
+
|
|
229
|
+
Claude can call these tools directly during conversation:
|
|
230
|
+
|
|
231
|
+
| Tool | What it does | When to use |
|
|
232
|
+
|------|-------------|-------------|
|
|
233
|
+
| `memory_recall` | FTS5 search past session summaries | Starting a task, looking for prior work |
|
|
234
|
+
| `memory_entities` | Find all sessions that touched a file | Before editing a file, understanding history |
|
|
235
|
+
| `memory_session_notes` | Current session activity summary | Mid-session, checking what's been done |
|
|
236
|
+
| `memory_store` | Manually save a note or decision | Preserving important context |
|
|
237
|
+
| `memory_context_budget` | Analyze token costs + recommendations | Optimizing which resources to load |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Version History
|
|
242
|
+
|
|
243
|
+
| Version | What it solved |
|
|
244
|
+
|---------|---------------|
|
|
245
|
+
| **v0.1.0** | Cross-session memory, entity tracking, FTS5 search |
|
|
246
|
+
| **v0.2.0** | Compact interceptor (PreCompact/PostCompact hooks), context enrichment, importance scoring |
|
|
247
|
+
| **v0.3.0** | Removed API key requirement, 1-command install |
|
|
248
|
+
| **v0.4.0** | Smart resource loading, token budget optimization |
|
|
249
|
+
|
|
250
|
+
See [CHANGELOG.md](CHANGELOG.md) for full details.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Dependencies
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
@modelcontextprotocol/sdk MCP stdio server
|
|
258
|
+
bun:sqlite Built-in, zero install
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
That's it. **One npm package.** The other is built into Bun.
|
|
262
|
+
|
|
263
|
+
No Python. No Chroma. No HTTP server. No API key. No Docker.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Data & Privacy
|
|
268
|
+
|
|
269
|
+
All data stored locally at `~/.claude-memory-hub/memory.db`.
|
|
270
|
+
|
|
271
|
+
No cloud. No telemetry. No network calls. Your memory stays on your machine.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Uninstall
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
claude mcp remove claude-memory-hub -s user
|
|
279
|
+
# Remove hook entries containing "claude-memory-hub" from ~/.claude/settings.json
|
|
280
|
+
rm -rf ~/.claude-memory-hub
|
|
281
|
+
```
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
var __require = import.meta.require;
|
|
4
|
+
|
|
5
|
+
// src/cli/main.ts
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
7
|
+
import { homedir } from "os";
|
|
8
|
+
import { join, resolve, dirname } from "path";
|
|
9
|
+
import { spawnSync } from "child_process";
|
|
10
|
+
var CLAUDE_DIR = join(homedir(), ".claude");
|
|
11
|
+
var SETTINGS_PATH = join(CLAUDE_DIR, "settings.json");
|
|
12
|
+
var PKG_DIR = resolve(dirname(import.meta.dir));
|
|
13
|
+
function getHookPath(hookName) {
|
|
14
|
+
return join(PKG_DIR, "dist", "hooks", `${hookName}.js`);
|
|
15
|
+
}
|
|
16
|
+
function getMcpServerPath() {
|
|
17
|
+
return join(PKG_DIR, "dist", "index.js");
|
|
18
|
+
}
|
|
19
|
+
function loadSettings() {
|
|
20
|
+
if (!existsSync(SETTINGS_PATH))
|
|
21
|
+
return {};
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(readFileSync(SETTINGS_PATH, "utf-8"));
|
|
24
|
+
} catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function saveSettings(settings) {
|
|
29
|
+
if (!existsSync(CLAUDE_DIR))
|
|
30
|
+
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
31
|
+
writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + `
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
function install() {
|
|
35
|
+
console.log(`claude-memory-hub \u2014 install
|
|
36
|
+
`);
|
|
37
|
+
console.log("1. Registering MCP server...");
|
|
38
|
+
const mcpPath = getMcpServerPath();
|
|
39
|
+
const result = spawnSync("claude", ["mcp", "add", "claude-memory-hub", "-s", "user", "--", "bun", "run", mcpPath], {
|
|
40
|
+
stdio: "inherit"
|
|
41
|
+
});
|
|
42
|
+
if (result.status !== 0) {
|
|
43
|
+
console.log(" claude CLI not available \u2014 registering in settings.json directly");
|
|
44
|
+
const settings2 = loadSettings();
|
|
45
|
+
settings2.mcpServers ??= {};
|
|
46
|
+
settings2.mcpServers["claude-memory-hub"] = {
|
|
47
|
+
command: "bun",
|
|
48
|
+
args: ["run", mcpPath]
|
|
49
|
+
};
|
|
50
|
+
saveSettings(settings2);
|
|
51
|
+
}
|
|
52
|
+
console.log(" MCP server registered.");
|
|
53
|
+
console.log(`
|
|
54
|
+
2. Registering hooks...`);
|
|
55
|
+
const settings = loadSettings();
|
|
56
|
+
settings.hooks ??= {};
|
|
57
|
+
const hookEntries = [
|
|
58
|
+
["PostToolUse", getHookPath("post-tool-use")],
|
|
59
|
+
["UserPromptSubmit", getHookPath("user-prompt-submit")],
|
|
60
|
+
["PreCompact", getHookPath("pre-compact")],
|
|
61
|
+
["PostCompact", getHookPath("post-compact")],
|
|
62
|
+
["Stop", getHookPath("session-end")]
|
|
63
|
+
];
|
|
64
|
+
let registered = 0;
|
|
65
|
+
for (const [event, scriptPath] of hookEntries) {
|
|
66
|
+
const hooks = settings.hooks;
|
|
67
|
+
hooks[event] ??= [];
|
|
68
|
+
const exists = hooks[event].some((e) => JSON.stringify(e).includes("claude-memory-hub"));
|
|
69
|
+
if (!exists) {
|
|
70
|
+
hooks[event].push({
|
|
71
|
+
matcher: "",
|
|
72
|
+
hooks: [{ type: "command", command: `bun run ${scriptPath}` }]
|
|
73
|
+
});
|
|
74
|
+
registered++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
saveSettings(settings);
|
|
78
|
+
console.log(` ${registered} hook(s) registered. (${5 - registered} already existed)`);
|
|
79
|
+
const dataDir = join(homedir(), ".claude-memory-hub");
|
|
80
|
+
if (!existsSync(dataDir)) {
|
|
81
|
+
mkdirSync(dataDir, { recursive: true, mode: 448 });
|
|
82
|
+
console.log(`
|
|
83
|
+
3. Created data directory: ${dataDir}`);
|
|
84
|
+
} else {
|
|
85
|
+
console.log(`
|
|
86
|
+
3. Data directory exists: ${dataDir}`);
|
|
87
|
+
}
|
|
88
|
+
console.log(`
|
|
89
|
+
========================================`);
|
|
90
|
+
console.log("Installation complete!");
|
|
91
|
+
console.log("");
|
|
92
|
+
console.log(" MCP: claude-memory-hub");
|
|
93
|
+
console.log(" Hooks: PostToolUse, UserPromptSubmit, PreCompact, PostCompact, Stop");
|
|
94
|
+
console.log(" Data: ~/.claude-memory-hub/memory.db");
|
|
95
|
+
console.log(" Key: not needed");
|
|
96
|
+
console.log("");
|
|
97
|
+
console.log(" Restart Claude Code to activate.");
|
|
98
|
+
console.log("========================================");
|
|
99
|
+
}
|
|
100
|
+
function uninstall() {
|
|
101
|
+
console.log(`claude-memory-hub \u2014 uninstall
|
|
102
|
+
`);
|
|
103
|
+
spawnSync("claude", ["mcp", "remove", "claude-memory-hub", "-s", "user"], {
|
|
104
|
+
stdio: "inherit"
|
|
105
|
+
});
|
|
106
|
+
const settings = loadSettings();
|
|
107
|
+
if (settings.hooks) {
|
|
108
|
+
const hooks = settings.hooks;
|
|
109
|
+
for (const event of Object.keys(hooks)) {
|
|
110
|
+
hooks[event] = hooks[event].filter((e) => !JSON.stringify(e).includes("claude-memory-hub"));
|
|
111
|
+
if (hooks[event].length === 0)
|
|
112
|
+
delete hooks[event];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (settings.mcpServers) {
|
|
116
|
+
delete settings.mcpServers["claude-memory-hub"];
|
|
117
|
+
}
|
|
118
|
+
saveSettings(settings);
|
|
119
|
+
console.log("Removed MCP server and hooks from settings.json.");
|
|
120
|
+
console.log("Data at ~/.claude-memory-hub/ preserved. Delete manually if desired.");
|
|
121
|
+
}
|
|
122
|
+
function status() {
|
|
123
|
+
console.log(`claude-memory-hub \u2014 status
|
|
124
|
+
`);
|
|
125
|
+
const settings = loadSettings();
|
|
126
|
+
const hasMcp = !!settings.mcpServers?.["claude-memory-hub"];
|
|
127
|
+
const hookCount = Object.values(settings.hooks ?? {}).flat().filter((e) => JSON.stringify(e).includes("claude-memory-hub")).length;
|
|
128
|
+
const dataDir = join(homedir(), ".claude-memory-hub");
|
|
129
|
+
const hasData = existsSync(join(dataDir, "memory.db"));
|
|
130
|
+
console.log(` MCP server: ${hasMcp ? "registered" : "not registered"}`);
|
|
131
|
+
console.log(` Hooks: ${hookCount}/5 registered`);
|
|
132
|
+
console.log(` Database: ${hasData ? "exists" : "not created yet"}`);
|
|
133
|
+
if (hasData) {
|
|
134
|
+
const { statSync } = __require("fs");
|
|
135
|
+
const stats = statSync(join(dataDir, "memory.db"));
|
|
136
|
+
console.log(` DB size: ${(stats.size / 1024).toFixed(1)} KB`);
|
|
137
|
+
}
|
|
138
|
+
if (!hasMcp || hookCount < 5) {
|
|
139
|
+
console.log(`
|
|
140
|
+
Run: npx claude-memory-hub install`);
|
|
141
|
+
} else {
|
|
142
|
+
console.log(`
|
|
143
|
+
Everything looks good.`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
var command = process.argv[2];
|
|
147
|
+
switch (command) {
|
|
148
|
+
case "install":
|
|
149
|
+
install();
|
|
150
|
+
break;
|
|
151
|
+
case "uninstall":
|
|
152
|
+
uninstall();
|
|
153
|
+
break;
|
|
154
|
+
case "status":
|
|
155
|
+
status();
|
|
156
|
+
break;
|
|
157
|
+
default:
|
|
158
|
+
console.log(`claude-memory-hub \u2014 persistent memory for Claude Code
|
|
159
|
+
`);
|
|
160
|
+
console.log("Commands:");
|
|
161
|
+
console.log(" install Register MCP server + hooks");
|
|
162
|
+
console.log(" uninstall Remove MCP server + hooks");
|
|
163
|
+
console.log(" status Check installation status");
|
|
164
|
+
console.log(`
|
|
165
|
+
Usage: npx claude-memory-hub <command>`);
|
|
166
|
+
break;
|
|
167
|
+
}
|