claude_memory 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.claude/CLAUDE.md +1 -1
- data/.claude/rules/claude_memory.generated.md +14 -1
- data/.claude/skills/check-memory/SKILL.md +10 -0
- data/.claude/skills/improve/SKILL.md +12 -1
- data/.claude-plugin/plugin.json +1 -1
- data/CHANGELOG.md +70 -0
- data/db/migrations/008_add_provenance_line_range.rb +21 -0
- data/db/migrations/009_add_docid.rb +39 -0
- data/db/migrations/010_add_llm_cache.rb +30 -0
- data/docs/improvements.md +72 -1084
- data/docs/influence/claude-supermemory.md +498 -0
- data/docs/influence/qmd.md +424 -2022
- data/docs/quality_review.md +64 -705
- data/lib/claude_memory/commands/doctor_command.rb +45 -4
- data/lib/claude_memory/commands/explain_command.rb +11 -6
- data/lib/claude_memory/commands/stats_command.rb +1 -1
- data/lib/claude_memory/core/fact_graph.rb +122 -0
- data/lib/claude_memory/core/fact_query_builder.rb +34 -14
- data/lib/claude_memory/core/fact_ranker.rb +3 -20
- data/lib/claude_memory/core/relative_time.rb +45 -0
- data/lib/claude_memory/core/result_sorter.rb +2 -2
- data/lib/claude_memory/core/rr_fusion.rb +57 -0
- data/lib/claude_memory/core/snippet_extractor.rb +97 -0
- data/lib/claude_memory/domain/fact.rb +3 -1
- data/lib/claude_memory/index/index_query.rb +2 -0
- data/lib/claude_memory/index/lexical_fts.rb +18 -0
- data/lib/claude_memory/infrastructure/operation_tracker.rb +7 -21
- data/lib/claude_memory/infrastructure/schema_validator.rb +30 -25
- data/lib/claude_memory/ingest/content_sanitizer.rb +8 -1
- data/lib/claude_memory/ingest/ingester.rb +67 -56
- data/lib/claude_memory/ingest/tool_extractor.rb +1 -1
- data/lib/claude_memory/ingest/tool_filter.rb +55 -0
- data/lib/claude_memory/logging/logger.rb +112 -0
- data/lib/claude_memory/mcp/query_guide.rb +96 -0
- data/lib/claude_memory/mcp/response_formatter.rb +86 -23
- data/lib/claude_memory/mcp/server.rb +34 -4
- data/lib/claude_memory/mcp/text_summary.rb +257 -0
- data/lib/claude_memory/mcp/tool_definitions.rb +20 -4
- data/lib/claude_memory/mcp/tools.rb +133 -120
- data/lib/claude_memory/publish.rb +12 -2
- data/lib/claude_memory/recall/expansion_detector.rb +44 -0
- data/lib/claude_memory/recall.rb +93 -41
- data/lib/claude_memory/resolve/resolver.rb +72 -40
- data/lib/claude_memory/store/sqlite_store.rb +99 -24
- data/lib/claude_memory/sweep/sweeper.rb +6 -0
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +21 -0
- metadata +14 -2
- data/docs/remaining_improvements.md +0 -330
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
# Claude-Supermemory Analysis
|
|
2
|
+
|
|
3
|
+
*Analysis Date: 2026-02-02*
|
|
4
|
+
*Repository: https://github.com/supermemoryai/claude-supermemory*
|
|
5
|
+
*Version/Commit: latest main (shallow clone)*
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Executive Summary
|
|
10
|
+
|
|
11
|
+
**Project purpose**: Claude-Supermemory is a Claude Code plugin that provides persistent, cross-session memory by capturing conversation transcripts and injecting recalled context via hooks. It uses the Supermemory cloud service as its backend for storage and retrieval.
|
|
12
|
+
|
|
13
|
+
**Key innovation**: Cloud-delegated memory with automatic profile injection. Rather than maintaining a local knowledge base, it offloads all persistence, search, and profile computation to the Supermemory API. The plugin is purely a bridge between Claude Code's hook system and the cloud service.
|
|
14
|
+
|
|
15
|
+
**Technology Stack**:
|
|
16
|
+
|
|
17
|
+
| Component | Technology |
|
|
18
|
+
|-----------|-----------|
|
|
19
|
+
| Language | JavaScript (Node.js ≥18) |
|
|
20
|
+
| Storage | Supermemory Cloud API (no local DB) |
|
|
21
|
+
| Search | Hybrid vector + keyword (via Supermemory API) |
|
|
22
|
+
| Build | esbuild (bundle to single CJS files) |
|
|
23
|
+
| Linting | Biome v2.3.13 |
|
|
24
|
+
| Auth | Browser-based OAuth (local HTTP callback server) |
|
|
25
|
+
| Dependencies | 1 production (`supermemory@^4.0.0`), 2 dev |
|
|
26
|
+
| Total LOC | ~1,195 lines (source, excluding minified validate.js) |
|
|
27
|
+
|
|
28
|
+
**Production readiness**: Beta. Clean architecture, graceful error handling, and CI linting. No automated test suite. External API dependency means offline use is impossible. MIT license.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Architecture Overview
|
|
33
|
+
|
|
34
|
+
### Data Model
|
|
35
|
+
|
|
36
|
+
Claude-Supermemory has **no local data model**. All persistence is in Supermemory's cloud:
|
|
37
|
+
|
|
38
|
+
- **Memories**: Free-text content with container tags, metadata, and custom IDs
|
|
39
|
+
- **Profiles**: Server-computed static (persistent) + dynamic (recent) facts per container
|
|
40
|
+
- **Search Results**: Vector + keyword hybrid search with similarity scores
|
|
41
|
+
|
|
42
|
+
The only local state is:
|
|
43
|
+
- Credentials: `~/.supermemory-claude/credentials.json`
|
|
44
|
+
- Settings: `~/.supermemory-claude/settings.json`
|
|
45
|
+
- Session trackers: `~/.supermemory-claude/trackers/{sessionId}.txt` (last captured UUID)
|
|
46
|
+
|
|
47
|
+
### Design Patterns
|
|
48
|
+
|
|
49
|
+
| Pattern | Location | Description |
|
|
50
|
+
|---------|----------|-------------|
|
|
51
|
+
| Adapter | `supermemory-client.js:11-109` | Wraps Supermemory SDK into normalized interface |
|
|
52
|
+
| Strategy | `hooks.json:1-50` | Different hooks for different lifecycle events |
|
|
53
|
+
| Facade | `context-hook.js:8-93` | Unified entry point delegating to helpers |
|
|
54
|
+
| Delta Ingestion | `transcript-formatter.js:51-70` | UUID-based cursor for incremental capture |
|
|
55
|
+
| Graceful Degradation | `context-hook.js:27-40` | Never blocks session, always returns `continue: true` |
|
|
56
|
+
| Tiered Config | `settings.js:23-41` | Defaults → file → ENV override chain |
|
|
57
|
+
|
|
58
|
+
### Module Organization
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
src/
|
|
62
|
+
├── Hooks (entry points)
|
|
63
|
+
│ ├── context-hook.js → SessionStart: fetch profile, inject context
|
|
64
|
+
│ ├── prompt-hook.js → UserPromptSubmit: stub (placeholder)
|
|
65
|
+
│ ├── observation-hook.js → PostToolUse: stub (placeholder)
|
|
66
|
+
│ └── summary-hook.js → Stop: capture transcript, save to cloud
|
|
67
|
+
├── CLI Scripts
|
|
68
|
+
│ ├── search-memory.js → Manual memory search
|
|
69
|
+
│ └── add-memory.js → Manual memory add
|
|
70
|
+
└── lib/ (core logic)
|
|
71
|
+
├── supermemory-client.js → API wrapper (111 lines)
|
|
72
|
+
├── settings.js → Configuration (89 lines)
|
|
73
|
+
├── auth.js → Browser OAuth flow (117 lines)
|
|
74
|
+
├── format-context.js → Memory → Claude injection (121 lines)
|
|
75
|
+
├── transcript-formatter.js → Transcript parsing (228 lines)
|
|
76
|
+
├── container-tag.js → Project/user identification (51 lines)
|
|
77
|
+
├── compress.js → Tool observation summarization (93 lines)
|
|
78
|
+
├── stdin.js → Hook I/O abstraction
|
|
79
|
+
└── validate.js → Input validation (minified)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Comparison Table vs ClaudeMemory
|
|
83
|
+
|
|
84
|
+
| Aspect | Claude-Supermemory | ClaudeMemory |
|
|
85
|
+
|--------|-------------------|--------------|
|
|
86
|
+
| **Storage** | Cloud API (Supermemory) | Local SQLite (dual-DB) |
|
|
87
|
+
| **Data Model** | Free-text memories | Subject-predicate-object facts |
|
|
88
|
+
| **Search** | Hybrid via API | FTS5 + FastEmbed local vectors |
|
|
89
|
+
| **Truth Maintenance** | Server-side (opaque) | Explicit resolver with supersession |
|
|
90
|
+
| **Scope System** | Container tags (project/user hash) | Dual database (global + project) |
|
|
91
|
+
| **Offline Support** | None | Full offline |
|
|
92
|
+
| **Test Suite** | None | Full RSpec suite + benchmarks |
|
|
93
|
+
| **Extraction** | Raw transcript capture | Distiller interface for fact extraction |
|
|
94
|
+
| **Conflict Resolution** | Deduplication only | Conflict detection + resolution |
|
|
95
|
+
| **Context Injection** | Hook-based XML injection | Published markdown snapshots |
|
|
96
|
+
| **Language** | JavaScript (Node.js) | Ruby |
|
|
97
|
+
| **LOC** | ~1,195 | ~8,000+ |
|
|
98
|
+
| **Dependencies** | 1 prod, 2 dev | ~5 prod |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Key Components Deep-Dive
|
|
103
|
+
|
|
104
|
+
### 1. Context Injection via SessionStart Hook
|
|
105
|
+
|
|
106
|
+
**Purpose**: Inject recalled memories at session start so Claude has prior context.
|
|
107
|
+
|
|
108
|
+
**File**: `src/context-hook.js:8-93`
|
|
109
|
+
|
|
110
|
+
The hook reads stdin JSON from Claude Code, fetches the user's profile from Supermemory, formats it, and returns it as `additionalContext` in the hook response:
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
// context-hook.js:72-74
|
|
114
|
+
writeOutput({
|
|
115
|
+
hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext },
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The `additionalContext` string is injected into Claude's system prompt as XML:
|
|
120
|
+
|
|
121
|
+
```xml
|
|
122
|
+
<supermemory-context>
|
|
123
|
+
The following is recalled context about the user...
|
|
124
|
+
|
|
125
|
+
## User Profile (Persistent)
|
|
126
|
+
- Prefers TypeScript over JavaScript
|
|
127
|
+
|
|
128
|
+
## Recent Context
|
|
129
|
+
- Working on authentication flow
|
|
130
|
+
|
|
131
|
+
## Relevant Memories (with relevance %)
|
|
132
|
+
- [2hrs ago] Implemented JWT auth for API [89%]
|
|
133
|
+
|
|
134
|
+
Use these memories naturally when relevant...
|
|
135
|
+
</supermemory-context>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Key design**: `format-context.js:25-52` deduplicates across static, dynamic, and search results using a `Set`. This is lexical matching only (no semantic dedup).
|
|
139
|
+
|
|
140
|
+
**ClaudeMemory comparison**: We publish to `.claude/rules/claude_memory.generated.md` which Claude reads on startup. Their approach is more dynamic (fetches at runtime) but requires API availability. Our approach works offline but is stale until re-published.
|
|
141
|
+
|
|
142
|
+
### 2. Transcript Capture via Stop Hook
|
|
143
|
+
|
|
144
|
+
**Purpose**: Capture conversation turns when session ends.
|
|
145
|
+
|
|
146
|
+
**File**: `src/summary-hook.js:7-67`, `src/lib/transcript-formatter.js:1-228`
|
|
147
|
+
|
|
148
|
+
The Stop hook parses Claude Code's NDJSON transcript, extracts new entries since last capture, and formats them into a compact tagged format:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
[turn:start timestamp="2026-02-02T10:30:00Z"]
|
|
152
|
+
|
|
153
|
+
[role:user]
|
|
154
|
+
How do I implement auth?
|
|
155
|
+
[user:end]
|
|
156
|
+
|
|
157
|
+
[tool:Edit]
|
|
158
|
+
file_path: src/auth.js
|
|
159
|
+
old_string: function login() {
|
|
160
|
+
new_string: async function login() {
|
|
161
|
+
[tool:end]
|
|
162
|
+
|
|
163
|
+
[role:assistant]
|
|
164
|
+
I've updated the login function to be async...
|
|
165
|
+
[assistant:end]
|
|
166
|
+
|
|
167
|
+
[turn:end]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Key features**:
|
|
171
|
+
- UUID-based cursor tracking (`transcript-formatter.js:17-29`) — more reliable than timestamps
|
|
172
|
+
- Thinking blocks skipped (`transcript-formatter.js:136`)
|
|
173
|
+
- System reminders and self-references cleaned (`transcript-formatter.js:168-175`)
|
|
174
|
+
- Tool results truncated to 500 chars (`transcript-formatter.js:5`)
|
|
175
|
+
- Read tool results completely skipped (`transcript-formatter.js:6`)
|
|
176
|
+
- Minimum 100 chars to save (`transcript-formatter.js:212`)
|
|
177
|
+
|
|
178
|
+
**ClaudeMemory comparison**: We also do delta-based ingestion with cursor tracking. Their approach stores raw formatted transcript as a single memory blob. We extract structured facts (subject-predicate-object). Their approach is simpler but less queryable.
|
|
179
|
+
|
|
180
|
+
### 3. Tool Observation Compression
|
|
181
|
+
|
|
182
|
+
**Purpose**: Summarize tool usage into compact strings for memory storage.
|
|
183
|
+
|
|
184
|
+
**File**: `src/lib/compress.js:1-93`
|
|
185
|
+
|
|
186
|
+
Each tool type gets a custom summarization:
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
// compress.js:17-74
|
|
190
|
+
case 'Edit': return `Edited ${file}: "${oldSnippet}" → "${newSnippet}"`;
|
|
191
|
+
case 'Write': return `Created ${file} (${contentLen} chars)`;
|
|
192
|
+
case 'Bash': return `Ran: ${cmd}${desc}${success ? '' : ' [FAILED]'}`;
|
|
193
|
+
case 'Task': return `Spawned ${agent}: ${desc}`;
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Handles 10 tool types: Edit, Write, Bash, Task, Read, Glob, Grep, WebFetch, WebSearch, NotebookEdit.
|
|
197
|
+
|
|
198
|
+
**ClaudeMemory comparison**: We don't have tool-specific compression. Our transcript formatter stores tool usage in provenance, but without per-tool summarization logic. This is a useful pattern for reducing memory storage size.
|
|
199
|
+
|
|
200
|
+
### 4. Container Tag System (Project Isolation)
|
|
201
|
+
|
|
202
|
+
**Purpose**: Identify projects and users for memory isolation.
|
|
203
|
+
|
|
204
|
+
**File**: `src/lib/container-tag.js:1-51`
|
|
205
|
+
|
|
206
|
+
Uses SHA256 hashing of git root path for project identification:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
// container-tag.js:21-25
|
|
210
|
+
function getContainerTag(cwd) {
|
|
211
|
+
const gitRoot = getGitRoot(cwd);
|
|
212
|
+
const basePath = gitRoot || cwd;
|
|
213
|
+
return `claudecode_project_${sha256(basePath)}`; // 16-char hash
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Also generates user-level tags based on git email or username (`container-tag.js:33-43`).
|
|
218
|
+
|
|
219
|
+
**ClaudeMemory comparison**: We use `project_path` on facts and dual databases. Their hashing approach provides privacy (path not exposed in API calls) and cross-machine consistency for same-email users. Our approach is more explicit but less privacy-preserving.
|
|
220
|
+
|
|
221
|
+
### 5. Graceful Auth Flow
|
|
222
|
+
|
|
223
|
+
**Purpose**: Authenticate with Supermemory via browser-based OAuth.
|
|
224
|
+
|
|
225
|
+
**File**: `src/lib/auth.js` (referenced from context-hook.js:22-40)
|
|
226
|
+
|
|
227
|
+
Starts a local HTTP server on port 19876, opens the system browser to Supermemory's auth page, and captures the API key via callback. Falls back gracefully:
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
// context-hook.js:27-40
|
|
231
|
+
catch (authErr) {
|
|
232
|
+
const isTimeout = authErr.message === 'AUTH_TIMEOUT';
|
|
233
|
+
writeOutput({
|
|
234
|
+
hookSpecificOutput: {
|
|
235
|
+
hookEventName: 'SessionStart',
|
|
236
|
+
additionalContext: `<supermemory-status>
|
|
237
|
+
${isTimeout ? 'Authentication timed out...' : 'Authentication failed...'}
|
|
238
|
+
Session will continue without memory context.
|
|
239
|
+
</supermemory-status>`,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
return; // Never blocks the session
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**ClaudeMemory comparison**: We don't need authentication (local SQLite). This is relevant only if we ever add a cloud sync feature.
|
|
247
|
+
|
|
248
|
+
### 6. Skill-Based Search
|
|
249
|
+
|
|
250
|
+
**Purpose**: User-triggered memory search via `/super-search` command.
|
|
251
|
+
|
|
252
|
+
**File**: `plugin/skills/super-search/SKILL.md:1-35`
|
|
253
|
+
|
|
254
|
+
Defines a Claude Code skill that triggers a search script:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/search-memory.cjs" "USER_QUERY_HERE"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The skill markdown defines when it should be triggered: "Use when user asks about past work, previous sessions, how something was implemented."
|
|
261
|
+
|
|
262
|
+
**ClaudeMemory comparison**: We expose `memory.recall` and related tools via MCP. Their skill-based approach requires Claude to interpret intent and construct a search query. Our MCP approach lets Claude call tools directly with structured parameters. MCP is more powerful; skills are simpler to implement.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Comparative Analysis
|
|
267
|
+
|
|
268
|
+
### What They Do Well
|
|
269
|
+
|
|
270
|
+
1. **Minimal footprint**: ~1,195 lines of code with 1 production dependency. Extremely lightweight.
|
|
271
|
+
2. **Hook response format**: Clean use of `hookSpecificOutput.additionalContext` for context injection at session start. This is a documented Claude Code API pattern we could adopt.
|
|
272
|
+
3. **Relative time formatting** (`format-context.js:1-23`): "2hrs ago", "3d ago" instead of ISO timestamps — more useful for context.
|
|
273
|
+
4. **Tool-specific compression** (`compress.js:13-75`): Per-tool summarization produces compact, readable summaries.
|
|
274
|
+
5. **Privacy-preserving identifiers** (`container-tag.js:4-6`): SHA256 hashing of paths means project names never leave the local machine.
|
|
275
|
+
6. **Deferred profile computation**: The Supermemory API computes static vs dynamic fact separation server-side, avoiding client-side complexity.
|
|
276
|
+
7. **Structured content tags**: `[turn:start]`, `[role:user]`, `[tool:Edit]` markup enables later parsing.
|
|
277
|
+
8. **Credential security**: API key never persisted in settings file (`settings.js:46`).
|
|
278
|
+
|
|
279
|
+
### What We Do Well
|
|
280
|
+
|
|
281
|
+
1. **Local-first architecture**: Full offline support, no API dependency, no subscription cost.
|
|
282
|
+
2. **Structured fact model**: SPO triples enable rich querying that blob storage cannot.
|
|
283
|
+
3. **Truth maintenance**: Supersession and conflict resolution with predicate policies.
|
|
284
|
+
4. **Comprehensive test suite**: Full RSpec coverage + DevMemBench benchmarks.
|
|
285
|
+
5. **Dual-database scope**: Clean separation of global vs project knowledge.
|
|
286
|
+
6. **Local semantic search**: FastEmbed ONNX model runs locally, no API calls for search.
|
|
287
|
+
7. **MCP integration**: 18 tools expose full memory API to Claude, more powerful than skills.
|
|
288
|
+
8. **Provenance tracking**: Every fact links back to source content with evidence.
|
|
289
|
+
|
|
290
|
+
### Trade-offs
|
|
291
|
+
|
|
292
|
+
| Trade-off | Cloud (Supermemory) | Local (ClaudeMemory) |
|
|
293
|
+
|-----------|-------------------|---------------------|
|
|
294
|
+
| **Setup** | Needs account + API key | `gem install` + done |
|
|
295
|
+
| **Latency** | Network round-trip | Instant (local SQLite) |
|
|
296
|
+
| **Offline** | Doesn't work | Full functionality |
|
|
297
|
+
| **Cost** | Requires Pro subscription | Free |
|
|
298
|
+
| **Cross-device** | Automatic sync | Manual (no built-in sync) |
|
|
299
|
+
| **Complexity** | Simple bridge (~1.2K LOC) | Full system (~8K+ LOC) |
|
|
300
|
+
| **Profile AI** | Server computes profiles | Must implement distiller |
|
|
301
|
+
| **Scalability** | Server handles growth | Must manage local DB |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Adoption Opportunities
|
|
306
|
+
|
|
307
|
+
### High Priority ⭐
|
|
308
|
+
|
|
309
|
+
#### 1. SessionStart Context Injection via Hook ⭐
|
|
310
|
+
|
|
311
|
+
- **Value**: Inject recalled facts directly into Claude's context at session start, ensuring Claude always has relevant memory without requiring MCP tool calls
|
|
312
|
+
- **Evidence**: `context-hook.js:72-74` — uses `hookSpecificOutput.additionalContext` to inject XML context
|
|
313
|
+
- **Implementation**: Add a `SessionStart` hook handler to ClaudeMemory that:
|
|
314
|
+
1. Queries both global and project databases for recent/relevant facts
|
|
315
|
+
2. Formats them into a concise context block
|
|
316
|
+
3. Returns via `hookSpecificOutput.additionalContext`
|
|
317
|
+
- This supplements (not replaces) our existing `.claude/rules/` publish mechanism
|
|
318
|
+
- **Effort**: 1-2 days (hook handler, context formatter, settings integration)
|
|
319
|
+
- **Trade-off**: Adds startup latency (local DB query is fast, <100ms). Could duplicate info already in published rules file.
|
|
320
|
+
- **Recommendation**: **ADOPT** — Direct context injection ensures Claude sees memory immediately, before it could even call MCP tools. Our published rules file may not always be read or prioritized.
|
|
321
|
+
|
|
322
|
+
#### 2. Tool-Specific Observation Compression ⭐
|
|
323
|
+
|
|
324
|
+
- **Value**: Compact, readable summaries of tool usage for fact provenance and memory storage. Reduces token waste by ~70% vs storing raw tool I/O.
|
|
325
|
+
- **Evidence**: `compress.js:13-75` — 10 tool handlers producing human-readable summaries like `Edited auth.js: "login()" → "async login()"`
|
|
326
|
+
- **Implementation**: Create `ClaudeMemory::Compress::ToolSummarizer` class with per-tool handlers:
|
|
327
|
+
```ruby
|
|
328
|
+
case tool_name
|
|
329
|
+
when "Edit" then "Edited #{relative_path(file)}: #{truncate(old)} → #{truncate(new)}"
|
|
330
|
+
when "Bash" then "Ran: #{truncate(cmd)}#{failed ? ' [FAILED]' : ''}"
|
|
331
|
+
end
|
|
332
|
+
```
|
|
333
|
+
Use during ingestion to produce compact provenance descriptions.
|
|
334
|
+
- **Effort**: 4-6 hours (class + tests, integrate with ingest pipeline)
|
|
335
|
+
- **Trade-off**: Lossy compression — original tool I/O detail is discarded
|
|
336
|
+
- **Recommendation**: **ADOPT** — Directly improves provenance quality and reduces storage size
|
|
337
|
+
|
|
338
|
+
#### 3. Relative Time Formatting in Recall Output ⭐
|
|
339
|
+
|
|
340
|
+
- **Value**: "2hrs ago", "3d ago" is more useful than "2026-02-02T10:30:00Z" when browsing facts
|
|
341
|
+
- **Evidence**: `format-context.js:1-23` — clean relative time function with progressive granularity
|
|
342
|
+
- **Implementation**: Add `ClaudeMemory::Formatting::RelativeTime` module, use in MCP recall results and CLI output
|
|
343
|
+
- **Effort**: 2-3 hours (module + tests + integration)
|
|
344
|
+
- **Trade-off**: None significant — ISO timestamps can be kept for technical/sort purposes
|
|
345
|
+
- **Recommendation**: **ADOPT** — Simple UX improvement
|
|
346
|
+
|
|
347
|
+
#### 4. Structured Transcript Tagging Format ⭐
|
|
348
|
+
|
|
349
|
+
- **Value**: Tagged format (`[role:user]`, `[tool:Edit]`, `[turn:start]`) enables structured parsing of ingested content. More reliable than regex-based extraction.
|
|
350
|
+
- **Evidence**: `transcript-formatter.js:72-84, 95-96, 141-148` — consistent markup for all content types
|
|
351
|
+
- **Implementation**: During ingestion, emit structured markers around content chunks. Enables the distiller to identify tool usage, user intent, and assistant reasoning separately.
|
|
352
|
+
- **Effort**: 1 day (update ingest formatter, update distiller interface)
|
|
353
|
+
- **Trade-off**: Slightly larger storage per content item
|
|
354
|
+
- **Recommendation**: **CONSIDER** — Useful when we implement a real distiller. Can defer until then.
|
|
355
|
+
|
|
356
|
+
### Medium Priority
|
|
357
|
+
|
|
358
|
+
#### 5. Plugin Distribution Format
|
|
359
|
+
|
|
360
|
+
- **Value**: Standard Claude Code plugin installation (`/install plugin`) instead of manual gem + MCP + hook setup
|
|
361
|
+
- **Evidence**: `plugin/hooks/hooks.json`, `plugin/skills/`, `plugin/commands/` — structured plugin format with automatic hook registration
|
|
362
|
+
- **Implementation**: Package ClaudeMemory as a Claude Code plugin with `hooks.json`, skills, and commands. Keep the gem for library usage.
|
|
363
|
+
- **Effort**: 2-3 days (plugin packaging, testing across platforms)
|
|
364
|
+
- **Trade-off**: Must maintain two distribution formats (gem + plugin). Plugin format may have constraints.
|
|
365
|
+
- **Recommendation**: **CONSIDER** — Would significantly reduce setup friction. Wait for Claude Code plugin ecosystem to mature.
|
|
366
|
+
|
|
367
|
+
#### 6. Tool Capture Filtering (Skip/Capture Lists)
|
|
368
|
+
|
|
369
|
+
- **Value**: Configurable tool filtering prevents noisy tools (Read, Glob) from bloating memory
|
|
370
|
+
- **Evidence**: `settings.js:9-15` — `skipTools` and `captureTools` arrays with whitelist/blacklist modes
|
|
371
|
+
- **Implementation**: Add tool filtering to ingestion config. Default skip: Read, Glob, Grep. Default capture: Edit, Write, Bash, Task.
|
|
372
|
+
- **Effort**: 3-4 hours (config + filter logic + tests)
|
|
373
|
+
- **Trade-off**: May miss useful context from skipped tools
|
|
374
|
+
- **Recommendation**: **CONSIDER** — Our tool_calls table already captures all tools; this would filter what gets elevated to facts
|
|
375
|
+
|
|
376
|
+
#### 7. Content Cleaning Pipeline
|
|
377
|
+
|
|
378
|
+
- **Value**: Strip system reminders, self-referential context, and noise before storage
|
|
379
|
+
- **Evidence**: `transcript-formatter.js:168-175` — regex-based removal of `<system-reminder>` and `<supermemory-context>` tags
|
|
380
|
+
- **Implementation**: Extend our `ContentSanitizer` to also strip `<claude-memory-context>` and `<system-reminder>` tags from ingested content
|
|
381
|
+
- **Effort**: 1-2 hours (regex additions + tests)
|
|
382
|
+
- **Trade-off**: Could accidentally strip user content that happens to use these tags
|
|
383
|
+
- **Recommendation**: **CONSIDER** — Our `ContentSanitizer` already handles `<private>` and `<no-memory>` tags. Adding system tag stripping is a small extension.
|
|
384
|
+
|
|
385
|
+
### Low Priority
|
|
386
|
+
|
|
387
|
+
#### 8. Browser-Based Auth Flow
|
|
388
|
+
|
|
389
|
+
- **Value**: Smoother onboarding for cloud features
|
|
390
|
+
- **Evidence**: `auth.js:62-109` — local HTTP server + browser redirect
|
|
391
|
+
- **Implementation**: Only relevant if we add cloud sync or API features
|
|
392
|
+
- **Effort**: 1-2 days
|
|
393
|
+
- **Trade-off**: Complexity for a feature we may never need
|
|
394
|
+
- **Recommendation**: **DEFER** — We're local-first. No cloud auth needed.
|
|
395
|
+
|
|
396
|
+
#### 9. Minimum Content Length Filter
|
|
397
|
+
|
|
398
|
+
- **Value**: Prevents saving trivially small memories
|
|
399
|
+
- **Evidence**: `transcript-formatter.js:212` — `if (result.length < 100) return null`
|
|
400
|
+
- **Implementation**: Add minimum content threshold in ingestion pipeline
|
|
401
|
+
- **Effort**: 30 minutes
|
|
402
|
+
- **Trade-off**: Could miss short but significant exchanges
|
|
403
|
+
- **Recommendation**: **DEFER** — Our distiller should handle quality filtering
|
|
404
|
+
|
|
405
|
+
### Features to Avoid
|
|
406
|
+
|
|
407
|
+
#### 1. Cloud-Only Storage
|
|
408
|
+
|
|
409
|
+
**Reasoning**: Their entire storage layer depends on Supermemory's API. This means no offline support, requires a paid subscription, and exposes all memory content to a third party. Our local SQLite approach is a fundamental advantage. Do not adopt cloud storage as primary.
|
|
410
|
+
|
|
411
|
+
#### 2. No Local Search
|
|
412
|
+
|
|
413
|
+
**Reasoning**: All search queries go to Supermemory's API. Our local FastEmbed + FTS5 hybrid search is faster, private, and works offline. Do not replace local search with API calls.
|
|
414
|
+
|
|
415
|
+
#### 3. No Test Suite
|
|
416
|
+
|
|
417
|
+
**Reasoning**: The repository has zero automated tests. Our comprehensive RSpec suite + DevMemBench benchmarks is a significant quality advantage. Do not reduce test coverage.
|
|
418
|
+
|
|
419
|
+
#### 4. Stub Hooks (Placeholder Architecture)
|
|
420
|
+
|
|
421
|
+
**Reasoning**: `prompt-hook.js` and `observation-hook.js` are stubs that only log and return success. This suggests the architecture was designed for future features that haven't materialized. Don't create placeholder code.
|
|
422
|
+
|
|
423
|
+
#### 5. Server-Side Profile Computation
|
|
424
|
+
|
|
425
|
+
**Reasoning**: They delegate "static vs dynamic" fact classification to the Supermemory API. This is opaque and uncontrollable. Our explicit predicate policies and truth maintenance system provide transparent, auditable knowledge management.
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## Implementation Recommendations
|
|
430
|
+
|
|
431
|
+
### Phase 1: Context Injection (Immediate)
|
|
432
|
+
|
|
433
|
+
1. Add `SessionStart` hook handler that queries local DB for relevant facts
|
|
434
|
+
2. Format facts as compact context block with sections (conventions, decisions, architecture)
|
|
435
|
+
3. Return via `hookSpecificOutput.additionalContext`
|
|
436
|
+
4. Include relative timestamps for temporal context
|
|
437
|
+
5. Add tests for hook handler and formatter
|
|
438
|
+
|
|
439
|
+
### Phase 2: Ingestion Quality (Near-term)
|
|
440
|
+
|
|
441
|
+
1. Implement tool-specific observation compression for provenance
|
|
442
|
+
2. Add `<system-reminder>` and self-reference tag stripping to ContentSanitizer
|
|
443
|
+
3. Add configurable tool filtering for ingestion noise reduction
|
|
444
|
+
4. Consider structured transcript tagging for distiller input
|
|
445
|
+
|
|
446
|
+
### Phase 3: Distribution (Future)
|
|
447
|
+
|
|
448
|
+
1. Investigate Claude Code plugin format for easier installation
|
|
449
|
+
2. Package hooks, skills, and MCP server as plugin bundle
|
|
450
|
+
3. Maintain gem distribution for library consumers
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Architecture Decisions
|
|
455
|
+
|
|
456
|
+
### Preserve (Our Advantages)
|
|
457
|
+
|
|
458
|
+
- **Local SQLite storage** — privacy, offline support, no subscription
|
|
459
|
+
- **Fact-based knowledge graph** — structured querying, truth maintenance
|
|
460
|
+
- **Dual-database architecture** — clean global vs project separation
|
|
461
|
+
- **MCP tool interface** — 18 tools, more powerful than skills
|
|
462
|
+
- **Comprehensive test suite** — RSpec + DevMemBench benchmarks
|
|
463
|
+
- **FastEmbed local embeddings** — no API for semantic search
|
|
464
|
+
|
|
465
|
+
### Adopt
|
|
466
|
+
|
|
467
|
+
- **SessionStart context injection** — supplement published rules with dynamic injection
|
|
468
|
+
- **Tool observation compression** — compact provenance descriptions
|
|
469
|
+
- **Relative time formatting** — better UX for temporal context
|
|
470
|
+
- **System tag stripping** — cleaner ingested content
|
|
471
|
+
|
|
472
|
+
### Reject
|
|
473
|
+
|
|
474
|
+
- **Cloud storage dependency** — local-first is our core advantage
|
|
475
|
+
- **API-only search** — local search is faster and private
|
|
476
|
+
- **No test policy** — maintain our testing standards
|
|
477
|
+
- **Placeholder architecture** — only build what's needed now
|
|
478
|
+
- **Plugin-only distribution** — keep gem as primary, plugin as secondary option
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## Key Takeaways
|
|
483
|
+
|
|
484
|
+
1. **Cloud vs local is the fundamental architectural difference.** Claude-Supermemory trades privacy and offline support for simplicity and cross-device sync. We should stay local-first.
|
|
485
|
+
|
|
486
|
+
2. **SessionStart context injection is the highest-value pattern to adopt.** It ensures Claude has memory context before any MCP tool calls. This is complementary to our existing publish mechanism.
|
|
487
|
+
|
|
488
|
+
3. **Their codebase is remarkably lean (~1.2K LOC).** This is achieved by delegating all intelligence to the Supermemory API. Our system is necessarily more complex because we handle search, truth maintenance, and fact extraction locally.
|
|
489
|
+
|
|
490
|
+
4. **Tool compression and relative timestamps are easy wins.** Both improve UX with minimal implementation effort.
|
|
491
|
+
|
|
492
|
+
5. **The plugin distribution format is worth watching.** As Claude Code's plugin ecosystem matures, packaging as a plugin could dramatically reduce setup friction.
|
|
493
|
+
|
|
494
|
+
6. **No test suite is a significant weakness.** Their approach of "delegate to cloud API" reduces local testing needs, but also means they can't verify behavior changes. Our testing infrastructure is a major advantage.
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
*Analysis performed by studying source code at `/tmp/study-repos/claude-supermemory`. All file:line references are relative to that checkout.*
|