claude_memory 0.8.0 → 0.9.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/memory.sqlite3 +0 -0
  3. data/.claude/rules/claude_memory.generated.md +32 -2
  4. data/.claude/settings.json +30 -52
  5. data/.claude/settings.local.json +3 -1
  6. data/.claude/skills/upgrade-dependencies/SKILL.md +154 -0
  7. data/.claude-plugin/marketplace.json +2 -2
  8. data/.claude-plugin/plugin.json +3 -3
  9. data/.claude-plugin/scripts/hook-runner.sh +14 -0
  10. data/.claude-plugin/scripts/serve-mcp.sh +14 -0
  11. data/.ruby-version +1 -1
  12. data/CHANGELOG.md +41 -0
  13. data/CLAUDE.md +31 -17
  14. data/README.md +35 -0
  15. data/db/migrations/013_add_mcp_tool_calls.rb +26 -0
  16. data/db/migrations/014_canonicalize_predicates.rb +30 -0
  17. data/docs/improvements.md +58 -20
  18. data/docs/influence/claude-mem.md +1 -0
  19. data/docs/influence/claude-supermemory.md +1 -0
  20. data/docs/influence/episodic-memory.md +1 -0
  21. data/docs/influence/grepai.md +1 -0
  22. data/docs/influence/kbs.md +1 -0
  23. data/docs/influence/lossless-claw.md +1 -0
  24. data/docs/influence/qmd.md +1 -0
  25. data/lib/claude_memory/commands/completion_command.rb +1 -31
  26. data/lib/claude_memory/commands/embeddings_command.rb +198 -0
  27. data/lib/claude_memory/commands/help_command.rb +8 -1
  28. data/lib/claude_memory/commands/registry.rb +47 -34
  29. data/lib/claude_memory/commands/reject_command.rb +62 -0
  30. data/lib/claude_memory/commands/restore_command.rb +77 -0
  31. data/lib/claude_memory/commands/skills/distill-transcripts.md +5 -1
  32. data/lib/claude_memory/commands/stats_command.rb +98 -2
  33. data/lib/claude_memory/configuration.rb +14 -1
  34. data/lib/claude_memory/distill/json_schema.md +8 -4
  35. data/lib/claude_memory/distill/null_distiller.rb +2 -0
  36. data/lib/claude_memory/domain/entity.rb +13 -1
  37. data/lib/claude_memory/domain/fact.rb +26 -2
  38. data/lib/claude_memory/embeddings/api_adapter.rb +5 -4
  39. data/lib/claude_memory/embeddings/fastembed_adapter.rb +43 -13
  40. data/lib/claude_memory/embeddings/inspector.rb +91 -0
  41. data/lib/claude_memory/embeddings/model_registry.rb +210 -0
  42. data/lib/claude_memory/embeddings/resolver.rb +32 -6
  43. data/lib/claude_memory/ingest/ingester.rb +17 -0
  44. data/lib/claude_memory/mcp/handlers/management_handlers.rb +24 -0
  45. data/lib/claude_memory/mcp/handlers/stats_handlers.rb +5 -2
  46. data/lib/claude_memory/mcp/instructions_builder.rb +17 -0
  47. data/lib/claude_memory/mcp/server.rb +22 -1
  48. data/lib/claude_memory/mcp/telemetry.rb +86 -0
  49. data/lib/claude_memory/mcp/tool_definitions.rb +86 -3
  50. data/lib/claude_memory/mcp/tools.rb +10 -0
  51. data/lib/claude_memory/publish.rb +40 -5
  52. data/lib/claude_memory/recall.rb +81 -0
  53. data/lib/claude_memory/resolve/predicate_policy.rb +63 -3
  54. data/lib/claude_memory/resolve/resolver.rb +43 -0
  55. data/lib/claude_memory/store/schema_manager.rb +1 -1
  56. data/lib/claude_memory/store/sqlite_store.rb +250 -1
  57. data/lib/claude_memory/store/store_manager.rb +50 -1
  58. data/lib/claude_memory/sweep/maintenance.rb +115 -1
  59. data/lib/claude_memory/sweep/sweeper.rb +3 -0
  60. data/lib/claude_memory/version.rb +1 -1
  61. data/lib/claude_memory.rb +5 -0
  62. metadata +26 -8
  63. data/.claude/memory.sqlite3-shm +0 -0
  64. data/.claude/memory.sqlite3-wal +0 -0
data/README.md CHANGED
@@ -83,6 +83,41 @@ Claude: "Based on my memory, you're using Rails with PostgreSQL..."
83
83
  👉 **[See Getting Started Guide →](docs/GETTING_STARTED.md)**
84
84
  👉 **[View Example Conversations →](docs/EXAMPLES.md)**
85
85
 
86
+ ## Why It Matters — Real A/B Test Results
87
+
88
+ We tested identical prompts with and without ClaudeMemory to measure the actual impact. Here's what we found:
89
+
90
+ ### Architecture Recall Without File Traversal
91
+
92
+ > **Prompt:** "Explain the conflict detection and resolution system. Answer from knowledge only — do not read any files."
93
+
94
+ | | Without Memory | With Memory |
95
+ |---|---|---|
96
+ | **Response** | 16 lines: "I don't know this codebase — let me read the files" | 76 lines: correct 4-role PredicatePolicy explanation, resolution pipeline, specific examples |
97
+ | **Outcome** | Honest refusal — zero architectural understanding | Deep understanding without touching the filesystem |
98
+
99
+ ### Correct File Paths vs Hallucinated Guesses
100
+
101
+ > **Prompt:** "I want to add a new predicate. Walk me through every file I need to update."
102
+
103
+ | | Without Memory | With Memory |
104
+ |---|---|---|
105
+ | **Response** | 6 steps targeting 3 **non-existent files** (`predicate.rb`, `predicate_synonyms.rb`, `json_schema.rb`) | 8 steps, all targeting **real files** with correct paths |
106
+ | **Outcome** | Plausible but wrong — would waste developer time | Actionable, correct, references actual commits |
107
+
108
+ ### Cross-Project Preferences
109
+
110
+ > **Prompt:** "What are my standard development environment preferences across all my projects?"
111
+
112
+ | | Without Memory | With Memory |
113
+ |---|---|---|
114
+ | **Response** | "I don't have stored knowledge of your preferences" | Lists 7 real preferences: iTerm2, tmux, VS Code, PostgreSQL, Redis, Docker |
115
+ | **Outcome** | Blank slate every session | Personalized from day one |
116
+
117
+ ### When Memory Doesn't Help
118
+
119
+ File-searchable questions ("what version is this?") and one-shot code generation without explicit recall don't benefit — `grep` is equally effective. Memory shines when the answer **isn't in any single file**: architecture spanning dozens of classes, conventions from past sessions, decisions with rationale, and user preferences.
120
+
86
121
  ## How It Works
87
122
 
88
123
  1. **You chat with Claude** - Tell it about your project
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Migration v13: Add mcp_tool_calls telemetry table
4
+ # Records every MCP server tool invocation for usage stats and ROI tracking.
5
+ # Distinct from `tool_calls` (v3), which stores Claude Code tool observations
6
+ # extracted from transcripts.
7
+ Sequel.migration do
8
+ up do
9
+ create_table?(:mcp_tool_calls) do
10
+ primary_key :id
11
+ String :tool_name, null: false
12
+ String :called_at, null: false
13
+ Integer :duration_ms, null: false
14
+ Integer :result_count
15
+ String :scope
16
+ String :error_class
17
+ end
18
+
19
+ run "CREATE INDEX IF NOT EXISTS idx_mcp_tool_calls_name_time ON mcp_tool_calls(tool_name, called_at)"
20
+ run "CREATE INDEX IF NOT EXISTS idx_mcp_tool_calls_called_at ON mcp_tool_calls(called_at)"
21
+ end
22
+
23
+ down do
24
+ drop_table?(:mcp_tool_calls)
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Migration v14: Canonicalize stale predicate names in existing facts.
4
+ #
5
+ # The predicate vocabulary was curated in 0.9.0 — synonym canonicalization
6
+ # now runs at insert time (Resolver), but existing facts with stale
7
+ # predicate names need a one-time rewrite so they appear in the correct
8
+ # snapshot sections and query results.
9
+ #
10
+ # This migration applies PredicatePolicy::SYNONYMS to all active facts.
11
+ # Reversible: the down migration is a no-op because we can't know the
12
+ # original predicate name after rewriting.
13
+ Sequel.migration do
14
+ up do
15
+ # Inline the synonym map so the migration is self-contained and
16
+ # doesn't break if PredicatePolicy::SYNONYMS changes later.
17
+ synonyms = {
18
+ "has_convention" => "convention",
19
+ "primary_language" => "uses_language"
20
+ }
21
+
22
+ synonyms.each do |from, to|
23
+ self[:facts].where(predicate: from).update(predicate: to)
24
+ end
25
+ end
26
+
27
+ down do
28
+ # No-op: can't reverse a predicate rename without storing the original.
29
+ end
30
+ end
data/docs/improvements.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # Improvements to Consider
2
2
 
3
- *Updated: 2026-03-24 - Implemented automatic distillation pipeline: NullDistiller wired into ingest hooks (Stop/SessionStart/PreCompact/SessionEnd/TaskCompleted/TeammateIdle), context hook injection for LLM extraction, `memory.undistilled` and `memory.mark_distilled` MCP tools, `/distill-transcripts` skill. Previously: Intent Parameter for Recall (#3), Retrieval Score Traces (#5), Search Agent Delegation (#8), Embedded Skill Distribution (#12), Shell Completion (#18), and 12 earlier features. Studied lossless-claw (v0.3.0). Other 6 repos unchanged since 2026-03-10.*
3
+ *Updated: 2026-03-30 - Re-studied all 7 influencer repos. New recommendations: CLAUDE_CONFIG_DIR support (#26, from episodic-memory), Usage Stats / ROI Tracking (#27, from grepai v0.35.0). New Features to Avoid: AST-Aware Code Chunking (QMD), Custom Instructions via Env Var (lossless-claw v0.5.2), OpenClaw Context Injection (claude-mem v10.6.0). Repos with no changes: kbs (v0.2.1), claude-supermemory (v2.0.1), episodic-memory (v1.0.15). Previously: 14 features implemented through 2026-03-24.*
4
4
  *Sources:*
5
- - *[thedotmack/claude-mem](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.5.5, studied 2026-03-09)*
6
- - *[obra/episodic-memory](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15, studied 2026-03-09)*
7
- - *[yoanbernabeu/grepai](https://github.com/yoanbernabeu/grepai) - Semantic code search (latest, studied 2026-03-09)*
8
- - *[supermemoryai/claude-supermemory](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed persistent memory (v2.0.1, studied 2026-03-09)*
9
- - *[tobi/qmd](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1, studied 2026-03-10)*
10
- - *[MadBomber/kbs](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1, studied 2026-03-09 — no changes)*
11
- - *[martian-engineering/lossless-claw](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.3.0, studied 2026-03-16)*
5
+ - *[thedotmack/claude-mem](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.6.3, re-studied 2026-03-30)*
6
+ - *[obra/episodic-memory](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15, re-studied 2026-03-30 — no changes)*
7
+ - *[yoanbernabeu/grepai](https://github.com/yoanbernabeu/grepai) - Semantic code search (v0.35.0, re-studied 2026-03-30)*
8
+ - *[supermemoryai/claude-supermemory](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed persistent memory (v2.0.1, re-studied 2026-03-30 — no changes)*
9
+ - *[tobi/qmd](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1+unreleased, re-studied 2026-03-30)*
10
+ - *[MadBomber/kbs](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1, studied 2026-03-30 — no changes)*
11
+ - *[martian-engineering/lossless-claw](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.5.2, re-studied 2026-03-30)*
12
12
 
13
13
  This document contains only unimplemented improvements. Completed items are removed.
14
14
 
@@ -128,10 +128,43 @@ Source: QMD study (updated 2026-03-02)
128
128
 
129
129
  `--async` flag on hook ingest/sweep/publish subcommands. Fork+detach for non-blocking execution, fallback to sync when fork unavailable.
130
130
 
131
+ ### ~~26. CLAUDE_CONFIG_DIR Support~~ ✅ Implemented 2026-04-13
132
+
133
+ `Configuration#claude_config_dir` reads `CLAUDE_CONFIG_DIR` env var before falling back to `~/.claude`. `global_db_path` routes through it, so users with non-standard Claude Code config locations (or multiple profiles) can point the global memory DB anywhere without touching project DB resolution.
134
+
135
+ ### 28. Code-Aware Transcript Chunking
136
+
137
+ Source: QMD v2.0.1+unreleased re-study (2026-03-30)
138
+
139
+ - **Value**: Better embeddings for transcripts containing code — detect fenced code blocks and apply AST-aware break points (function/class/import boundaries) rather than naive text splitting
140
+ - **Implementation**: Detect ` ```language ` fences in transcript content, parse code blocks with tree-sitter (via ruby_tree_sitter gem or shelling out), score break points (class=100, func=90, type=80, import=60), merge with markdown break points from #22
141
+ - **Evidence**: QMD `src/ast.ts` (392 lines) — web-tree-sitter with WASM grammars, `mergeBreakPoints()` combining AST + regex scores, graceful degradation on parse failure
142
+ - **Consideration**: Only useful in combination with #22 (Document Chunking). Transcripts often contain significant code in tool_use results and assistant responses
143
+ - **Effort**: 2-3 days (after #22)
144
+ - **Trade-off**: Adds tree-sitter dependency; graceful fallback to regex-only chunking when grammar unavailable
145
+
146
+ ### 30. Predicate Census Command
147
+
148
+ Source: predicate retrospective (2026-04-15)
149
+
150
+ - **Value**: Aggregate predicate usage data across many project databases for informed vocabulary decisions — without exposing content. Enables data-sharing across machines (work/personal) via a privacy-safe JSON report.
151
+ - **Implementation**: `claude-memory census [--root ~/src]`. Finds all `.claude/memory.sqlite3` files under root, opens each read-only, collects per-DB predicate × status counts, entity type counts, schema version, novel predicates, synonym canonicalization candidates. Outputs aggregated JSON with **no object_literal, no entity names, no project paths, no quotes** — only schema-level signal.
152
+ - **Evidence**: The multi-project survey that caught the `uses_framework` cardinality bug (commit `29818c2`) was a manual bash loop. Productizing it means any user can contribute usage data for vocabulary curation without privacy risk.
153
+ - **Effort**: 0.5 days
154
+ - **Trade-off**: None — purely additive, read-only, privacy-safe by design
155
+
156
+ ### ~~27. Usage Stats / ROI Tracking~~ ✅ Implemented 2026-04-15
157
+
158
+ Schema migration v13 adds `mcp_tool_calls` telemetry table (tool_name, called_at, duration_ms, result_count, scope, error_class). `MCP::Telemetry` wraps `Server#handle_tools_call` with monotonic-clock timing, captures errors, and records to the project DB; DB errors are swallowed so telemetry never fails a real tool call. `StatsCommand` gains `--tools` and `--since DAYS` flags showing total calls, error rate, and per-tool breakdown (calls, avg ms, p95 ms, error rate). `Sweep::Maintenance#prune_old_mcp_tool_calls` enforces a 90-day retention window, wired into `Sweeper#run!`. Rejected NDJSON in favor of SQLite for schema/query consistency with the rest of the gem. Dropped query-text capture (YAGNI — the dedup insight the hash would enable also needs raw text). Also fixed a latent bug where `StatsCommand` opened the DB via `Sequel.sqlite` (requiring the unlisted `sqlite3` gem); now uses the extralite adapter consistently.
159
+
131
160
  ---
132
161
 
133
162
  ## Low Priority / Defer
134
163
 
164
+ ### ~~29. Derive CompletionCommand Descriptions from Registry~~ ✅ Implemented 2026-04-15
165
+
166
+ `Registry::COMMANDS` now stores `{class:, description:}` entries as the single source of truth. New `Registry.description` and `Registry.descriptions` accessors. `CompletionCommand` reads descriptions via `Registry.descriptions` instead of maintaining its own parallel hash. `Registry.find` also simplified — class references stored directly since command files are required before the Registry, eliminating `const_get` string indirection. Drift between the command list and completion output is now impossible without a deliberate edit to a single file.
167
+
135
168
  ### 23. REST API Endpoint
136
169
 
137
170
  Source: QMD v2.0.1 study (2026-03-10)
@@ -219,6 +252,11 @@ Added `claude-memory export` command. Dumps facts with entities and provenance t
219
252
  - **Sub-Agent Delegation for Deep Recall** — lossless-claw spawns sub-agents for DAG traversal. Adds latency and complexity; our direct MCP tool responses are simpler and faster
220
253
  - **Message Parts Polymorphism** — lossless-claw's 10-column message_parts for tool calls, reasoning, patches. We don't store raw messages, so irrelevant
221
254
  - **OpenClaw ContextEngine Interface** — Tight framework coupling. Our MCP + hooks approach is more portable
255
+ - **Chunk Strategy Option** — QMD's `--chunk-strategy auto` for code files. ClaudeMemory has no standalone chunking pipeline to configure (QMD v0.35.0)
256
+ - **Custom Instructions via Env Var** — lossless-claw's `LCM_CUSTOM_INSTRUCTIONS` config stub exists but is never wired to summarization prompts. Incomplete pattern; our skill-based prompts are better (lossless-claw v0.5.2)
257
+ - **OpenClaw Context Injection** — claude-mem v10.6.0's `appendSystemContext` with 60s cache replaces MEMORY.md writes. Our SessionStart hook context injection already does this (claude-mem v10.6.0)
258
+ - **Message Parts Polymorphism** — lossless-claw's 10-column message_parts for tool calls, reasoning, patches. We don't store raw messages, so irrelevant
259
+ - **OpenClaw ContextEngine Interface** — Tight framework coupling. Our MCP + hooks approach is more portable
222
260
 
223
261
  ---
224
262
 
@@ -241,22 +279,22 @@ Added `claude-memory export` command. Dumps facts with entities and provenance t
241
279
  ## References
242
280
 
243
281
  - [episodic-memory GitHub](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15)
244
- - [claude-mem GitHub](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.5.5)
245
- - [grepai GitHub](https://github.com/yoanbernabeu/grepai) - Semantic code search (latest)
282
+ - [claude-mem GitHub](https://github.com/thedotmack/claude-mem) - Memory compression system (v10.6.3)
283
+ - [grepai GitHub](https://github.com/yoanbernabeu/grepai) - Semantic code search (v0.35.0)
246
284
  - [claude-supermemory GitHub](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed memory (v2.0.1)
247
- - [QMD GitHub](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1)
285
+ - [QMD GitHub](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1+unreleased)
248
286
  - [KBS GitHub](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1)
249
- - [lossless-claw GitHub](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.3.0)
287
+ - [lossless-claw GitHub](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.5.2)
250
288
 
251
289
  Influence documents:
252
- - [docs/influence/qmd.md](influence/qmd.md) - Updated 2026-03-10
253
- - [docs/influence/episodic-memory.md](influence/episodic-memory.md) - Updated 2026-03-09
254
- - [docs/influence/claude-mem.md](influence/claude-mem.md) - Updated 2026-03-09
255
- - [docs/influence/grepai.md](influence/grepai.md) - Updated 2026-03-09
256
- - [docs/influence/claude-supermemory.md](influence/claude-supermemory.md) - Updated 2026-03-09
257
- - [docs/influence/kbs.md](influence/kbs.md) - Updated 2026-03-09 (no changes)
258
- - [docs/influence/lossless-claw.md](influence/lossless-claw.md) - Updated 2026-03-16
290
+ - [docs/influence/qmd.md](influence/qmd.md) - Re-studied 2026-03-30
291
+ - [docs/influence/episodic-memory.md](influence/episodic-memory.md) - Re-studied 2026-03-30
292
+ - [docs/influence/claude-mem.md](influence/claude-mem.md) - Re-studied 2026-03-30
293
+ - [docs/influence/grepai.md](influence/grepai.md) - Re-studied 2026-03-30
294
+ - [docs/influence/claude-supermemory.md](influence/claude-supermemory.md) - Re-studied 2026-03-30
295
+ - [docs/influence/kbs.md](influence/kbs.md) - Re-studied 2026-03-30 (no changes)
296
+ - [docs/influence/lossless-claw.md](influence/lossless-claw.md) - Re-studied 2026-03-30
259
297
 
260
298
  ---
261
299
 
262
- *Last updated: 2026-03-24 - Implemented 14 features total. Latest: Automatic Distillation Pipeline (#13 partial, #17), Intent Parameter for Recall (#3). Previously: Retrieval Score Traces (#5), Search Agent Delegation (#8), Embedded Skill Distribution (#12), Shell Completion (#18), Dynamic MCP Instructions (#11), Structured Error Classification (#16), Content-Addressed Dedup (#19), Dedup Before Vector Scoring (#20), Dedicated Maintenance Class (#10), Three-Level Escalation (#14), Tool Escalation Workflow (#15). Studied lossless-claw (v0.3.0). Implemented earlier: MCP Tool Annotations, MCP Stdout Protection, Worktree-Aware Git Root, Self-Excluding Conversations, Plugin Distribution, sqlite-vec, Database Compact, Fact Export, Background Processing, MCP Discovery Tools.*
300
+ *Last updated: 2026-04-15 - Predicate retrospective: fixed uses_framework cardinality bug, curated vocabulary to 8 predicates, added synonym canonicalization + novel-predicate warnings. Also: reject/restore commands, #26 CLAUDE_CONFIG_DIR, #27 telemetry, #29 Registry descriptions.*
@@ -3,6 +3,7 @@
3
3
  *Analysis Date: 2026-03-02*
4
4
  *Repository: https://github.com/thedotmack/claude-mem*
5
5
  *Version: 10.5.2 (commit ecb09df)*
6
+ *Re-studied: 2026-03-30 — v10.6.3 (commit d068821). 4 releases since last study (v10.5.6, v10.6.0, v10.6.1, v10.6.2, v10.6.3). Key changes: OpenClaw system prompt context injection replacing MEMORY.md writes (v10.6.0), compressed context output ~53% smaller (v10.6.1), timeline report skill (v10.6.1), process supervisor hardening with PID 0 fix and signal race condition fix (v10.5.6), activity spinner orphan session fix (v10.6.2), Gemini CLI integration (v10.6.3), 7 critical cross-platform bug fixes (v10.6.3). Context injection pattern (appendSystemContext with 60s cache) aligns with our SessionStart hook approach. Compressed context format worth studying. No new adoptable patterns beyond what we already implement.*
6
7
 
7
8
  ---
8
9
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  *Analysis Date: 2026-03-02*
4
4
  *Previous Analysis: 2026-02-02*
5
+ *Re-studied: 2026-03-30 — No meaningful code changes since v2.0.1. marketplace.json bumped to 0.0.3, added claude-code-review GitHub Action (anthropics/claude-code-action@v1). All findings remain current.*
5
6
  *Repository: https://github.com/supermemoryai/claude-supermemory*
6
7
  *Version: 2.0.0 (commit de39413)*
7
8
 
@@ -3,6 +3,7 @@
3
3
  *Analysis Date: 2026-03-02*
4
4
  *Repository: https://github.com/obra/episodic-memory*
5
5
  *Version: 1.0.15 (commit 6feaa5b)*
6
+ *Re-studied: 2026-03-30 — No changes since v1.0.15. Repo dormant. One adoptable pattern identified: CLAUDE_CONFIG_DIR env var support (`src/paths.ts:20-22`) for configurable Claude config directory. Orphaned MCP process prevention (SIGHUP handler in wrapper) not applicable — ClaudeMemory runs as single Ruby process, no wrapper/child architecture.*
6
7
 
7
8
  ---
8
9
 
@@ -4,6 +4,7 @@
4
4
  *Previous Analysis: 2026-01-29*
5
5
  *Repository: https://github.com/yoanbernabeu/grepai*
6
6
  *Version: 0.34.0 (commit 1c7aba9)*
7
+ *Re-studied: 2026-03-30 — v0.35.0. One release since last study (2026-03-16). Key addition: privacy-first usage stats tracking (`stats/` package) recording every search/trace to NDJSON file (`.grepai/stats.json`), computing output tokens vs grep-equivalent tokens with savings percentages and optional USD cost savings. Fire-and-forget recording via goroutine with 100ms timeout, file-locking for cross-process safety. Shell completion also added (we already have this via #18). `.grepaiignore` support not relevant.*
7
8
 
8
9
  ---
9
10
 
@@ -1,6 +1,7 @@
1
1
  # KBS (Knowledge-Based System) Analysis
2
2
 
3
3
  *Analysis Date: 2026-03-02*
4
+ *Re-studied: 2026-03-30 — no changes since v0.2.1*
4
5
  *Repository: https://github.com/MadBomber/kbs*
5
6
  *Version: v0.2.1 (commit c04561d)*
6
7
 
@@ -3,6 +3,7 @@
3
3
  *Analysis Date: 2026-03-16*
4
4
  *Repository: https://github.com/martian-engineering/lossless-claw*
5
5
  *Version: 0.3.0 (commit 49949fb)*
6
+ *Re-studied: 2026-03-30 — v0.5.2. 5 releases since last study. Core DAG architecture unchanged; changes are operational hardening. Custom Instructions (`LCM_CUSTOM_INSTRUCTIONS`) — config stub exists but never wired to summarization prompts, do not adopt. Session exclusion patterns (ignore + stateless) — clean implementation but low priority (we already have ContentSanitizer exclusion tags). Prompt Slot Pattern — does not exist in codebase, not applicable. New: CJK-aware FTS5 fallback with `icu` tokenizer detection worth considering. Also: provider auth error surfacing, summarizer timeouts, bootstrap checkpoints, Docker support, TUI doctor command.*
6
7
 
7
8
  ---
8
9
 
@@ -4,6 +4,7 @@
4
4
  *Previous Analysis: 2026-03-02, 2026-02-02*
5
5
  *Repository: https://github.com/tobi/qmd*
6
6
  *Version: 2.0.1 (commit ae3604c)*
7
+ *Re-studied: 2026-03-30 — v2.0.1+unreleased. One significant addition: AST-aware chunking (`src/ast.ts`, 392 lines) using web-tree-sitter with WASM grammars for TS/JS/Python/Go/Rust. Detects language from extension, parses AST, extracts break points at function/class/import boundaries (class=100, func=90, type=80, import=60). Merged with regex break points via `mergeBreakPoints()`. Opt-in via `--chunk-strategy auto`. While we ingest transcripts rather than source code, transcripts frequently contain embedded code in tool results and assistant responses. AST-aware break points could improve embedding quality for code-heavy transcripts when combined with Document Chunking (#22). Added as improvement #28 (Code-Aware Transcript Chunking).*
7
8
 
8
9
  ---
9
10
 
@@ -37,7 +37,7 @@ module ClaudeMemory
37
37
  end
38
38
 
39
39
  def zsh_completion
40
- commands_with_desc = command_descriptions.map { |name, desc|
40
+ commands_with_desc = Registry.descriptions.sort.map { |name, desc|
41
41
  " '#{name}:#{desc}'"
42
42
  }.join("\n")
43
43
 
@@ -141,36 +141,6 @@ module ClaudeMemory
141
141
  BASH
142
142
  end
143
143
 
144
- def command_descriptions
145
- {
146
- "changes" => "Show recent fact changes",
147
- "compact" => "Compact databases",
148
- "completion" => "Generate shell completions",
149
- "conflicts" => "Show open conflicts",
150
- "db:init" => "Initialize database",
151
- "doctor" => "Check system health",
152
- "explain" => "Explain a fact with receipts",
153
- "export" => "Export facts to JSON",
154
- "git-lfs" => "Git LFS integration",
155
- "help" => "Show help message",
156
- "hook" => "Run hook entrypoints",
157
- "index" => "Index content",
158
- "ingest" => "Ingest transcript delta",
159
- "init" => "Initialize ClaudeMemory",
160
- "install-skill" => "Install agent skills",
161
- "promote" => "Promote fact to global",
162
- "publish" => "Publish snapshot",
163
- "recall" => "Recall facts matching query",
164
- "recover" => "Recover database",
165
- "search" => "Search indexed content",
166
- "serve-mcp" => "Start MCP server",
167
- "stats" => "Show statistics",
168
- "sweep" => "Run maintenance",
169
- "uninstall" => "Remove configuration",
170
- "version" => "Show version"
171
- }
172
- end
173
-
174
144
  def skill_names
175
145
  InstallSkillCommand::AVAILABLE_SKILLS.keys
176
146
  end
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ClaudeMemory
4
+ module Commands
5
+ # Shows embedding configuration, lists available models, and validates setup.
6
+ #
7
+ # Subcommands:
8
+ # claude-memory embeddings # Show current config
9
+ # claude-memory embeddings list # List available models
10
+ # claude-memory embeddings check # Validate current setup
11
+ #
12
+ class EmbeddingsCommand < BaseCommand
13
+ def call(args)
14
+ opts = parse_options(args, {}) do |o|
15
+ OptionParser.new do |parser|
16
+ parser.banner = "Usage: claude-memory embeddings [list|check]"
17
+ end
18
+ end
19
+ return 1 if opts.nil?
20
+
21
+ subcommand = args.first
22
+
23
+ case subcommand
24
+ when "list" then list_models
25
+ when "check" then check_setup
26
+ when nil then show_config
27
+ else
28
+ failure("Unknown subcommand: #{subcommand}. Use: list, check")
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def inspector
35
+ @inspector ||= Embeddings::Inspector.new
36
+ end
37
+
38
+ def show_config
39
+ provider = ENV["CLAUDE_MEMORY_EMBEDDING_PROVIDER"] || "tfidf"
40
+ model = ENV["CLAUDE_MEMORY_EMBEDDING_MODEL"]
41
+ api_url = ENV["CLAUDE_MEMORY_EMBEDDING_API_URL"]
42
+
43
+ stdout.puts "Embedding Configuration"
44
+ stdout.puts "======================"
45
+ stdout.puts "Provider: #{provider}"
46
+ stdout.puts "Model: #{model || "(default)"}"
47
+
48
+ if model
49
+ info = Embeddings::ModelRegistry.find(model)
50
+ if info
51
+ stdout.puts "Dimensions: #{info.dimensions}"
52
+ stdout.puts "Description: #{info.description}"
53
+ else
54
+ stdout.puts "Dimensions: (unknown - will be discovered at runtime)"
55
+ end
56
+ else
57
+ info = Embeddings::ModelRegistry.default_for_provider(provider)
58
+ if info
59
+ stdout.puts "Default model: #{info.name}"
60
+ stdout.puts "Dimensions: #{info.dimensions}"
61
+ end
62
+ end
63
+
64
+ stdout.puts "API URL: #{api_url}" if api_url && provider == "api"
65
+
66
+ inspector.database_states.each do |state|
67
+ stdout.puts ""
68
+ stdout.puts "#{state.label.capitalize} DB: provider=#{state.provider || "unknown"}, dimensions=#{state.dimensions || "unknown"}"
69
+ end
70
+
71
+ stdout.puts ""
72
+ stdout.puts "ENV variables:"
73
+ stdout.puts " CLAUDE_MEMORY_EMBEDDING_PROVIDER Provider (tfidf, fastembed, api)"
74
+ stdout.puts " CLAUDE_MEMORY_EMBEDDING_MODEL Model name"
75
+ stdout.puts " CLAUDE_MEMORY_EMBEDDING_API_KEY API key (for api provider)"
76
+ stdout.puts " CLAUDE_MEMORY_EMBEDDING_API_URL API endpoint (for api provider)"
77
+ 0
78
+ end
79
+
80
+ def list_models
81
+ Embeddings::ModelRegistry.providers.each do |provider|
82
+ stdout.puts ""
83
+ stdout.puts "#{provider_label(provider)}:"
84
+ stdout.puts "-" * 40
85
+
86
+ Embeddings::ModelRegistry.models_for_provider(provider).each do |model|
87
+ size = model.size_mb ? "#{model.size_mb}MB" : "cloud"
88
+ tokens = model.max_tokens ? "#{model.max_tokens} tokens" : ""
89
+ stdout.puts " #{model.name}"
90
+ stdout.puts " #{model.dimensions}-dim | #{size} | #{tokens}"
91
+ stdout.puts " #{model.description}"
92
+ end
93
+ end
94
+
95
+ stdout.puts ""
96
+ stdout.puts "Custom models: Set CLAUDE_MEMORY_EMBEDDING_MODEL to any model"
97
+ stdout.puts "supported by your provider. Dimensions are auto-detected."
98
+ 0
99
+ end
100
+
101
+ def check_setup
102
+ provider_name = ENV["CLAUDE_MEMORY_EMBEDDING_PROVIDER"] || "tfidf"
103
+ model_name = ENV["CLAUDE_MEMORY_EMBEDDING_MODEL"]
104
+
105
+ stdout.puts "Checking embedding setup..."
106
+ stdout.puts ""
107
+
108
+ ok = true
109
+ ok &= check_provider(provider_name)
110
+ ok &= check_model(provider_name, model_name) if model_name
111
+ ok &= render_dimension_checks(provider_name, model_name)
112
+
113
+ stdout.puts ""
114
+ stdout.puts ok ? "All checks passed." : "Some checks failed. See above."
115
+ ok ? 0 : 1
116
+ end
117
+
118
+ def check_provider(name)
119
+ case name
120
+ when "fastembed"
121
+ check_fastembed
122
+ when "api"
123
+ check_api_config
124
+ when "tfidf"
125
+ stdout.puts " [OK] tfidf provider (built-in, always available)"
126
+ true
127
+ else
128
+ stdout.puts " [FAIL] Unknown provider: #{name}"
129
+ false
130
+ end
131
+ end
132
+
133
+ def check_model(provider_name, model_name)
134
+ info = Embeddings::ModelRegistry.find(model_name)
135
+ if info
136
+ if info.provider != provider_name
137
+ stdout.puts " [WARN] Model '#{model_name}' is for '#{info.provider}' provider, but '#{provider_name}' is selected"
138
+ stdout.puts " Set CLAUDE_MEMORY_EMBEDDING_PROVIDER=#{info.provider}"
139
+ else
140
+ stdout.puts " [OK] Model '#{model_name}' (#{info.dimensions}-dim)"
141
+ end
142
+ else
143
+ stdout.puts " [INFO] Model '#{model_name}' not in registry (dimensions will be auto-detected)"
144
+ end
145
+ true
146
+ end
147
+
148
+ def render_dimension_checks(provider_name, model_name)
149
+ ok = true
150
+
151
+ inspector.dimension_checks(provider_name, model_name).each do |check|
152
+ case check.status
153
+ when :mismatch
154
+ stdout.puts " [WARN] #{check.label}: Dimension mismatch (stored: #{check.stored_dims}, current: #{check.current_dims})"
155
+ stdout.puts " Re-index with: claude-memory index --force --scope #{check.label}"
156
+ ok = false
157
+ when :match
158
+ stdout.puts " [OK] #{check.label}: #{check.stored_dims}-dim (provider: #{check.stored_provider || "unknown"})"
159
+ when :fresh
160
+ stdout.puts " [INFO] #{check.label}: No embeddings indexed yet"
161
+ end
162
+ end
163
+
164
+ ok
165
+ end
166
+
167
+ def check_fastembed
168
+ require "fastembed"
169
+ stdout.puts " [OK] fastembed gem available"
170
+ true
171
+ rescue LoadError
172
+ stdout.puts " [FAIL] fastembed gem not installed"
173
+ stdout.puts " Add `gem 'fastembed'` to your Gemfile"
174
+ false
175
+ end
176
+
177
+ def check_api_config
178
+ key = ENV["CLAUDE_MEMORY_EMBEDDING_API_KEY"] || ENV["OPENAI_API_KEY"]
179
+ if key
180
+ stdout.puts " [OK] API key configured"
181
+ true
182
+ else
183
+ stdout.puts " [FAIL] No API key found"
184
+ stdout.puts " Set CLAUDE_MEMORY_EMBEDDING_API_KEY or OPENAI_API_KEY"
185
+ false
186
+ end
187
+ end
188
+
189
+ def provider_label(provider)
190
+ case provider
191
+ when "fastembed" then "fastembed (local ONNX, no API key)"
192
+ when "api" then "api (OpenAI-compatible endpoints, requires API key)"
193
+ when "tfidf" then "tfidf (built-in, no dependencies)"
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -19,20 +19,27 @@ module ClaudeMemory
19
19
  explain Explain a fact with receipts
20
20
  export Export facts to JSON for backup
21
21
  help Show this help message
22
- hook Run hook entrypoints (ingest|sweep|publish)
22
+ hook Run hook entrypoints (ingest|sweep|publish|context)
23
23
  init Initialize ClaudeMemory in a project
24
24
  ingest Ingest transcript delta
25
25
  promote Promote a project fact to global memory
26
26
  publish Publish snapshot to Claude Code memory
27
27
  recall Recall facts matching a query
28
+ recover Recover stuck operations
29
+ reject Mark a fact as rejected (e.g. hallucination)
30
+ restore Restore superseded facts from reclassified predicates
28
31
  search Search indexed content
29
32
  serve-mcp Start MCP server
33
+ stats Show statistics (--tools for MCP telemetry)
30
34
  sweep Run maintenance/pruning
31
35
  uninstall Remove ClaudeMemory configuration
32
36
  version Show version number
33
37
 
34
38
  Utilities:
35
39
  completion Generate shell completions (bash/zsh)
40
+ embeddings Inspect embedding backend
41
+ git-lfs Git LFS integration for memory DB
42
+ index Build or rebuild content indexes
36
43
  install-skill Install agent skills to ~/.claude/commands/
37
44
 
38
45
  Run 'claude-memory <command> --help' for more information on a command.