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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/CLAUDE.md +1 -1
  3. data/.claude/rules/claude_memory.generated.md +14 -1
  4. data/.claude/skills/check-memory/SKILL.md +10 -0
  5. data/.claude/skills/improve/SKILL.md +12 -1
  6. data/.claude-plugin/plugin.json +1 -1
  7. data/CHANGELOG.md +70 -0
  8. data/db/migrations/008_add_provenance_line_range.rb +21 -0
  9. data/db/migrations/009_add_docid.rb +39 -0
  10. data/db/migrations/010_add_llm_cache.rb +30 -0
  11. data/docs/improvements.md +72 -1084
  12. data/docs/influence/claude-supermemory.md +498 -0
  13. data/docs/influence/qmd.md +424 -2022
  14. data/docs/quality_review.md +64 -705
  15. data/lib/claude_memory/commands/doctor_command.rb +45 -4
  16. data/lib/claude_memory/commands/explain_command.rb +11 -6
  17. data/lib/claude_memory/commands/stats_command.rb +1 -1
  18. data/lib/claude_memory/core/fact_graph.rb +122 -0
  19. data/lib/claude_memory/core/fact_query_builder.rb +34 -14
  20. data/lib/claude_memory/core/fact_ranker.rb +3 -20
  21. data/lib/claude_memory/core/relative_time.rb +45 -0
  22. data/lib/claude_memory/core/result_sorter.rb +2 -2
  23. data/lib/claude_memory/core/rr_fusion.rb +57 -0
  24. data/lib/claude_memory/core/snippet_extractor.rb +97 -0
  25. data/lib/claude_memory/domain/fact.rb +3 -1
  26. data/lib/claude_memory/index/index_query.rb +2 -0
  27. data/lib/claude_memory/index/lexical_fts.rb +18 -0
  28. data/lib/claude_memory/infrastructure/operation_tracker.rb +7 -21
  29. data/lib/claude_memory/infrastructure/schema_validator.rb +30 -25
  30. data/lib/claude_memory/ingest/content_sanitizer.rb +8 -1
  31. data/lib/claude_memory/ingest/ingester.rb +67 -56
  32. data/lib/claude_memory/ingest/tool_extractor.rb +1 -1
  33. data/lib/claude_memory/ingest/tool_filter.rb +55 -0
  34. data/lib/claude_memory/logging/logger.rb +112 -0
  35. data/lib/claude_memory/mcp/query_guide.rb +96 -0
  36. data/lib/claude_memory/mcp/response_formatter.rb +86 -23
  37. data/lib/claude_memory/mcp/server.rb +34 -4
  38. data/lib/claude_memory/mcp/text_summary.rb +257 -0
  39. data/lib/claude_memory/mcp/tool_definitions.rb +20 -4
  40. data/lib/claude_memory/mcp/tools.rb +133 -120
  41. data/lib/claude_memory/publish.rb +12 -2
  42. data/lib/claude_memory/recall/expansion_detector.rb +44 -0
  43. data/lib/claude_memory/recall.rb +93 -41
  44. data/lib/claude_memory/resolve/resolver.rb +72 -40
  45. data/lib/claude_memory/store/sqlite_store.rb +99 -24
  46. data/lib/claude_memory/sweep/sweeper.rb +6 -0
  47. data/lib/claude_memory/version.rb +1 -1
  48. data/lib/claude_memory.rb +21 -0
  49. metadata +14 -2
  50. 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.*