claude_memory 0.5.1 → 0.7.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/memory.sqlite3 +0 -0
- data/.claude/memory.sqlite3-shm +0 -0
- data/.claude/memory.sqlite3-wal +0 -0
- data/.claude/rules/claude_memory.generated.md +1 -1
- data/.claude/settings.json +5 -0
- data/.claude/settings.local.json +19 -1
- data/.claude-plugin/marketplace.json +5 -2
- data/.claude-plugin/plugin.json +16 -3
- data/.gitattributes +1 -0
- data/CHANGELOG.md +91 -0
- data/CLAUDE.md +28 -14
- data/README.md +6 -2
- data/Rakefile +22 -0
- data/db/migrations/011_add_tool_call_summaries.rb +18 -0
- data/db/migrations/012_add_vec_indexing_support.rb +19 -0
- data/docs/improvements.md +225 -61
- data/docs/influence/claude-mem.md +253 -0
- data/docs/influence/claude-supermemory.md +158 -430
- data/docs/influence/episodic-memory.md +217 -0
- data/docs/influence/grepai.md +163 -839
- data/docs/influence/kbs.md +437 -0
- data/docs/influence/qmd.md +210 -481
- data/docs/quality_review.md +344 -56
- data/hooks/hooks.json +19 -15
- data/lefthook.yml +4 -0
- data/lib/claude_memory/commands/checks/database_check.rb +7 -0
- data/lib/claude_memory/commands/checks/vec_check.rb +73 -0
- data/lib/claude_memory/commands/compact_command.rb +104 -0
- data/lib/claude_memory/commands/doctor_command.rb +1 -0
- data/lib/claude_memory/commands/export_command.rb +116 -0
- data/lib/claude_memory/commands/git_lfs_command.rb +117 -0
- data/lib/claude_memory/commands/help_command.rb +2 -0
- data/lib/claude_memory/commands/hook_command.rb +110 -9
- data/lib/claude_memory/commands/index_command.rb +63 -8
- data/lib/claude_memory/commands/initializers/global_initializer.rb +26 -7
- data/lib/claude_memory/commands/initializers/project_initializer.rb +35 -12
- data/lib/claude_memory/commands/registry.rb +4 -1
- data/lib/claude_memory/commands/serve_mcp_command.rb +10 -1
- data/lib/claude_memory/commands/stats_command.rb +12 -1
- data/lib/claude_memory/configuration.rb +40 -1
- data/lib/claude_memory/core/snippet_extractor.rb +21 -19
- data/lib/claude_memory/hook/context_injector.rb +75 -0
- data/lib/claude_memory/hook/error_classifier.rb +67 -0
- data/lib/claude_memory/hook/handler.rb +21 -1
- data/lib/claude_memory/index/lexical_fts.rb +88 -16
- data/lib/claude_memory/index/vector_index.rb +171 -0
- data/lib/claude_memory/infrastructure/schema_validator.rb +5 -1
- data/lib/claude_memory/ingest/ingester.rb +26 -1
- data/lib/claude_memory/ingest/observation_compressor.rb +177 -0
- data/lib/claude_memory/mcp/instructions_builder.rb +76 -0
- data/lib/claude_memory/mcp/server.rb +3 -1
- data/lib/claude_memory/mcp/tool_definitions.rb +65 -27
- data/lib/claude_memory/mcp/tools.rb +137 -2
- data/lib/claude_memory/publish.rb +28 -27
- data/lib/claude_memory/recall/dual_query_template.rb +1 -12
- data/lib/claude_memory/recall.rb +71 -17
- data/lib/claude_memory/resolve/resolver.rb +22 -18
- data/lib/claude_memory/store/sqlite_store.rb +17 -1
- data/lib/claude_memory/store/store_manager.rb +19 -24
- data/lib/claude_memory/sweep/sweeper.rb +41 -2
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +15 -0
- data/scripts/hook-runner.sh +14 -0
- data/scripts/serve-mcp.sh +14 -0
- data/skills/setup-memory/SKILL.md +6 -0
- metadata +36 -2
|
@@ -1,31 +1,48 @@
|
|
|
1
|
-
# Claude-Supermemory Analysis
|
|
1
|
+
# Claude-Supermemory Analysis (Updated)
|
|
2
2
|
|
|
3
|
-
*Analysis Date: 2026-
|
|
3
|
+
*Analysis Date: 2026-03-02*
|
|
4
|
+
*Previous Analysis: 2026-02-02*
|
|
4
5
|
*Repository: https://github.com/supermemoryai/claude-supermemory*
|
|
5
|
-
*Version
|
|
6
|
+
*Version: 2.0.0 (commit de39413)*
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
## Executive Summary
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
### Project Purpose
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Claude-Supermemory is a Claude Code plugin providing persistent, cross-session memory using the Supermemory cloud service. It captures conversation transcripts at session end and injects recalled context at session start via hooks.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
### Key Innovation (What's New Since Last Study)
|
|
17
|
+
|
|
18
|
+
1. **Team Memory** (v2.0.0): Project knowledge shared across team members via repo-level container tags, separate from personal memories. Dual `personalTag` + `repoTag` queries in parallel (`src/context-hook.js:52-55`).
|
|
19
|
+
|
|
20
|
+
2. **Signal Extraction**: Configurable keyword-based capture — only capture conversation turns containing signal keywords (e.g., "remember", "architecture", "decision"). Reduces noise in memory storage (`settings.json:signalKeywords`).
|
|
21
|
+
|
|
22
|
+
3. **Project Config**: Per-repo overrides via `.claude/.supermemory-claude/config.json` — custom API keys, container tags, signal settings per project.
|
|
23
|
+
|
|
24
|
+
4. **Browser Auth Flow**: OAuth-based authentication with local HTTP callback server (`src/lib/auth.js:117 lines`). Falls back to manual API key.
|
|
25
|
+
|
|
26
|
+
### Technology Stack
|
|
16
27
|
|
|
17
28
|
| Component | Technology |
|
|
18
29
|
|-----------|-----------|
|
|
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
|
|
25
|
-
| Dependencies | 1 production (`supermemory@^4.0.0`), 2 dev |
|
|
26
|
-
|
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
| **Language** | JavaScript (CommonJS, Node.js ≥18) |
|
|
31
|
+
| **Storage** | Supermemory Cloud API (no local DB) |
|
|
32
|
+
| **Search** | Hybrid vector + keyword (via Supermemory API) |
|
|
33
|
+
| **Build** | esbuild (bundle to single CJS files) |
|
|
34
|
+
| **Linting** | Biome v2.3.13 |
|
|
35
|
+
| **Auth** | Browser-based OAuth + ENV fallback |
|
|
36
|
+
| **Dependencies** | 1 production (`supermemory@^4.0.0`), 2 dev |
|
|
37
|
+
| **Plugin** | Claude Code marketplace format |
|
|
38
|
+
|
|
39
|
+
### Production Readiness
|
|
40
|
+
|
|
41
|
+
- **Maturity**: Stable (v2.0.0), Supermemory Pro required
|
|
42
|
+
- **Test Coverage**: No automated tests (unchanged from last analysis)
|
|
43
|
+
- **Documentation**: Clear README with config examples
|
|
44
|
+
- **Limitation**: Cloud dependency — no offline use
|
|
45
|
+
- **License**: MIT
|
|
29
46
|
|
|
30
47
|
---
|
|
31
48
|
|
|
@@ -33,233 +50,96 @@
|
|
|
33
50
|
|
|
34
51
|
### Data Model
|
|
35
52
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- **Memories**:
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
### Design Patterns
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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 |
|
|
53
|
+
No local data model. All persistence is in Supermemory's cloud:
|
|
54
|
+
|
|
55
|
+
- **Personal Memories**: User-specific, identified by `personalTag` (derived from cwd)
|
|
56
|
+
- **Team/Repo Memories**: Project-wide, identified by `repoTag` (git remote URL hash)
|
|
57
|
+
- **Profiles**: Server-computed static + dynamic facts per container
|
|
58
|
+
|
|
59
|
+
Local state:
|
|
60
|
+
- `~/.supermemory-claude/credentials.json` — auth tokens
|
|
61
|
+
- `~/.supermemory-claude/settings.json` — global config
|
|
62
|
+
- `.claude/.supermemory-claude/config.json` — per-project config
|
|
63
|
+
|
|
64
|
+
### Key Design Patterns
|
|
65
|
+
|
|
66
|
+
1. **Dual Container Tags** (`src/context-hook.js:47-55`): Personal and repo tags queried in parallel for session context:
|
|
67
|
+
```javascript
|
|
68
|
+
const [personalResult, repoResult] = await Promise.all([
|
|
69
|
+
client.getProfile(personalTag, projectName).catch(() => null),
|
|
70
|
+
client.getProfile(repoTag, projectName).catch(() => null),
|
|
71
|
+
]);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
2. **Signal Extraction** (`settings.json`): Only capture conversation turns containing signal keywords, with configurable context window:
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"signalExtraction": true,
|
|
78
|
+
"signalKeywords": ["remember", "architecture", "decision", "bug", "fix"],
|
|
79
|
+
"signalTurnsBefore": 3,
|
|
80
|
+
"includeTools": ["Edit", "Write"]
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
3. **Graceful Degradation** (`src/context-hook.js:27-40`): Never blocks session start. Auth failures, API errors, and empty results all produce informative `additionalContext` messages.
|
|
85
|
+
|
|
86
|
+
4. **Tiered Config** (`src/lib/settings.js`): Defaults → file → ENV override chain.
|
|
87
|
+
|
|
88
|
+
### Comparison with ClaudeMemory
|
|
89
|
+
|
|
90
|
+
| Aspect | Supermemory (2.0.0) | ClaudeMemory | Notes |
|
|
91
|
+
|--------|---------------------|--------------|-------|
|
|
92
|
+
| **Storage** | Supermemory Cloud | Local SQLite (dual DB) | We're self-contained |
|
|
93
|
+
| **Search** | Cloud hybrid search | Local FTS5 + fastembed | We work offline |
|
|
94
|
+
| **Team Memory** | Repo container tags | Not supported | They support shared team knowledge |
|
|
95
|
+
| **Signal Extraction** | Keyword-triggered | Ingest all transcripts | They're more selective |
|
|
96
|
+
| **Config** | Per-project overrides | Global + project scope | Similar concept |
|
|
97
|
+
| **Context Injection** | SessionStart hook | SessionStart hook | Same pattern (we adopted this) |
|
|
98
|
+
| **Dependencies** | Cloud API required | All local | We're more reliable |
|
|
99
|
+
| **Testing** | None | Comprehensive RSpec | We're more robust |
|
|
100
|
+
| **LOC** | ~1,195 | ~5,000 | We're more feature-rich |
|
|
99
101
|
|
|
100
102
|
---
|
|
101
103
|
|
|
102
104
|
## Key Components Deep-Dive
|
|
103
105
|
|
|
104
|
-
### 1
|
|
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
|
|
106
|
+
### Component 1: Team Memory (NEW)
|
|
222
107
|
|
|
223
|
-
**Purpose**:
|
|
108
|
+
**Purpose**: Share project knowledge across team members.
|
|
224
109
|
|
|
225
|
-
**
|
|
110
|
+
**Location**: `src/context-hook.js:47-72`, `src/lib/container-tag.js`
|
|
226
111
|
|
|
227
|
-
|
|
112
|
+
**Design Decisions**:
|
|
113
|
+
- Personal tag: derived from filesystem path
|
|
114
|
+
- Repo tag: derived from git remote URL
|
|
115
|
+
- Both queried in parallel
|
|
116
|
+
- Results formatted separately ("Personal Memories" vs "Project Knowledge")
|
|
117
|
+
- Empty results handled gracefully
|
|
228
118
|
|
|
229
|
-
|
|
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
|
-
```
|
|
119
|
+
### Component 2: Signal Extraction
|
|
245
120
|
|
|
246
|
-
**
|
|
121
|
+
**Purpose**: Reduce noise by only capturing significant conversation turns.
|
|
247
122
|
|
|
248
|
-
|
|
123
|
+
**Location**: `README:52-69`, settings.json
|
|
249
124
|
|
|
250
|
-
**
|
|
125
|
+
**Design Decisions**:
|
|
126
|
+
- Keyword-based detection (configurable list)
|
|
127
|
+
- Context window: capture N turns before signal turn
|
|
128
|
+
- Tool-based detection: capture turns using specific tools (Edit, Write)
|
|
129
|
+
- Disabled by default (captures everything)
|
|
251
130
|
|
|
252
|
-
|
|
131
|
+
### Component 3: Context Hook
|
|
253
132
|
|
|
254
|
-
|
|
133
|
+
**Purpose**: Inject past memories into new sessions.
|
|
255
134
|
|
|
256
|
-
|
|
257
|
-
node "${CLAUDE_PLUGIN_ROOT}/scripts/search-memory.cjs" "USER_QUERY_HERE"
|
|
258
|
-
```
|
|
135
|
+
**Location**: `src/context-hook.js:12-121`
|
|
259
136
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
137
|
+
**Design Decisions**:
|
|
138
|
+
- Reads stdin JSON from Claude Code hook
|
|
139
|
+
- Parallel API calls for personal + team context
|
|
140
|
+
- `combineContexts` merges with labeled sections
|
|
141
|
+
- Output via `hookSpecificOutput.additionalContext`
|
|
142
|
+
- Multiple fallback messages for auth/API/empty states
|
|
263
143
|
|
|
264
144
|
---
|
|
265
145
|
|
|
@@ -267,38 +147,19 @@ The skill markdown defines when it should be triggered: "Use when user asks abou
|
|
|
267
147
|
|
|
268
148
|
### What They Do Well
|
|
269
149
|
|
|
270
|
-
1. **
|
|
271
|
-
2. **
|
|
272
|
-
3. **
|
|
273
|
-
4. **
|
|
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`).
|
|
150
|
+
1. **Team Memory**: Repo-level container tags enable shared team knowledge
|
|
151
|
+
2. **Signal Extraction**: Smart filtering reduces memory noise
|
|
152
|
+
3. **Simplicity**: ~1,195 LOC, single dependency, clear architecture
|
|
153
|
+
4. **Graceful Degradation**: Never blocks sessions on failure
|
|
278
154
|
|
|
279
155
|
### What We Do Well
|
|
280
156
|
|
|
281
|
-
1. **Local-
|
|
282
|
-
2. **
|
|
283
|
-
3. **Truth
|
|
284
|
-
4. **Comprehensive
|
|
285
|
-
5. **
|
|
286
|
-
6. **
|
|
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 |
|
|
157
|
+
1. **Local-First**: No cloud dependency, works offline
|
|
158
|
+
2. **Knowledge Distillation**: Structured facts > raw transcript dumps
|
|
159
|
+
3. **Truth Maintenance**: Supersession and conflict resolution
|
|
160
|
+
4. **Comprehensive Testing**: Full RSpec suite
|
|
161
|
+
5. **Rich MCP Tools**: 18 tools for diverse queries
|
|
162
|
+
6. **Dual-Database**: Cleaner than container tags for scope separation
|
|
302
163
|
|
|
303
164
|
---
|
|
304
165
|
|
|
@@ -306,193 +167,60 @@ The skill markdown defines when it should be triggered: "Use when user asks abou
|
|
|
306
167
|
|
|
307
168
|
### High Priority ⭐
|
|
308
169
|
|
|
309
|
-
#### 1.
|
|
310
|
-
|
|
311
|
-
- **
|
|
312
|
-
- **
|
|
313
|
-
- **
|
|
314
|
-
|
|
315
|
-
|
|
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.
|
|
170
|
+
#### 1. Signal-Based Ingestion Filtering
|
|
171
|
+
- **Value**: Reduce noise in fact database, focus on significant content
|
|
172
|
+
- **Evidence**: `README:52-69` — keyword-triggered capture with context window
|
|
173
|
+
- **Implementation**: During ingest, prioritize transcript sections containing signal keywords (e.g., "decided", "convention", "always", "never", "prefer"). Already partially implemented via distiller scope hints.
|
|
174
|
+
- **Effort**: 1-2 days
|
|
175
|
+
- **Trade-off**: May miss important but subtly-expressed facts
|
|
176
|
+
- **Recommendation**: **CONSIDER** — Our distiller already extracts structured facts, which inherently filters noise
|
|
355
177
|
|
|
356
178
|
### Medium Priority
|
|
357
179
|
|
|
358
|
-
####
|
|
359
|
-
|
|
360
|
-
- **
|
|
361
|
-
- **
|
|
362
|
-
- **
|
|
363
|
-
- **
|
|
364
|
-
- **
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
- **
|
|
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
|
|
180
|
+
#### 2. Team/Shared Memory
|
|
181
|
+
- **Value**: Share project knowledge across team members
|
|
182
|
+
- **Evidence**: `src/context-hook.js:47-55` — dual personal/repo queries
|
|
183
|
+
- **Implementation**: Our global database already serves this role for cross-project knowledge. For team sharing, would need a shared database location or sync mechanism.
|
|
184
|
+
- **Effort**: 5+ days
|
|
185
|
+
- **Trade-off**: Significant complexity for team sync
|
|
186
|
+
- **Recommendation**: **DEFER** — Wait for user demand
|
|
187
|
+
|
|
188
|
+
#### 3. Per-Project Configuration
|
|
189
|
+
- **Value**: Different settings per project
|
|
190
|
+
- **Evidence**: `.claude/.supermemory-claude/config.json` per-repo config
|
|
191
|
+
- **Implementation**: Our Configuration class could support project-level overrides
|
|
392
192
|
- **Effort**: 1-2 days
|
|
393
|
-
- **Trade-off**:
|
|
394
|
-
- **Recommendation**: **
|
|
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
|
|
193
|
+
- **Trade-off**: Minimal
|
|
194
|
+
- **Recommendation**: **CONSIDER** — Useful if users have different projects with different needs
|
|
404
195
|
|
|
405
196
|
### Features to Avoid
|
|
406
197
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
**
|
|
410
|
-
|
|
411
|
-
|
|
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
|
|
198
|
+
- **Cloud Storage Dependency**: Our local-first approach is superior
|
|
199
|
+
- **No-Test Approach**: Their lack of testing is a weakness, not a feature
|
|
200
|
+
- **Container Tag System**: Our dual-database approach is cleaner
|
|
201
|
+
- **Browser OAuth Flow**: Over-engineering for a developer tool
|
|
202
|
+
- **Supermemory API**: External service dependency
|
|
479
203
|
|
|
480
204
|
---
|
|
481
205
|
|
|
482
206
|
## Key Takeaways
|
|
483
207
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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.
|
|
208
|
+
### Changes Since Last Analysis (2026-02-02)
|
|
209
|
+
- v2.0.0 with team memory support
|
|
210
|
+
- Signal extraction for smarter capture
|
|
211
|
+
- Per-project configuration
|
|
212
|
+
- Browser-based auth flow
|
|
213
|
+
- Skills (super-search, super-save)
|
|
214
|
+
- GitHub Actions CI
|
|
493
215
|
|
|
494
|
-
|
|
216
|
+
### Main Learnings
|
|
217
|
+
1. Team memory via shared container tags is interesting but our dual-database handles scope well
|
|
218
|
+
2. Signal extraction is a clever noise reduction strategy worth considering
|
|
219
|
+
3. Their simplicity (~1,195 LOC) is admirable but comes at the cost of features and testing
|
|
220
|
+
4. Cloud dependency remains their biggest weakness vs our local-first approach
|
|
495
221
|
|
|
496
222
|
---
|
|
497
223
|
|
|
498
|
-
*Analysis
|
|
224
|
+
*Analysis completed: 2026-03-02*
|
|
225
|
+
*Analyst: Claude Code*
|
|
226
|
+
*Review Status: Draft*
|