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.
- checksums.yaml +4 -4
- data/.claude/memory.sqlite3 +0 -0
- data/.claude/rules/claude_memory.generated.md +32 -2
- data/.claude/settings.json +30 -52
- data/.claude/settings.local.json +3 -1
- data/.claude/skills/upgrade-dependencies/SKILL.md +154 -0
- data/.claude-plugin/marketplace.json +2 -2
- data/.claude-plugin/plugin.json +3 -3
- data/.claude-plugin/scripts/hook-runner.sh +14 -0
- data/.claude-plugin/scripts/serve-mcp.sh +14 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +41 -0
- data/CLAUDE.md +31 -17
- data/README.md +35 -0
- data/db/migrations/013_add_mcp_tool_calls.rb +26 -0
- data/db/migrations/014_canonicalize_predicates.rb +30 -0
- data/docs/improvements.md +58 -20
- data/docs/influence/claude-mem.md +1 -0
- data/docs/influence/claude-supermemory.md +1 -0
- data/docs/influence/episodic-memory.md +1 -0
- data/docs/influence/grepai.md +1 -0
- data/docs/influence/kbs.md +1 -0
- data/docs/influence/lossless-claw.md +1 -0
- data/docs/influence/qmd.md +1 -0
- data/lib/claude_memory/commands/completion_command.rb +1 -31
- data/lib/claude_memory/commands/embeddings_command.rb +198 -0
- data/lib/claude_memory/commands/help_command.rb +8 -1
- data/lib/claude_memory/commands/registry.rb +47 -34
- data/lib/claude_memory/commands/reject_command.rb +62 -0
- data/lib/claude_memory/commands/restore_command.rb +77 -0
- data/lib/claude_memory/commands/skills/distill-transcripts.md +5 -1
- data/lib/claude_memory/commands/stats_command.rb +98 -2
- data/lib/claude_memory/configuration.rb +14 -1
- data/lib/claude_memory/distill/json_schema.md +8 -4
- data/lib/claude_memory/distill/null_distiller.rb +2 -0
- data/lib/claude_memory/domain/entity.rb +13 -1
- data/lib/claude_memory/domain/fact.rb +26 -2
- data/lib/claude_memory/embeddings/api_adapter.rb +5 -4
- data/lib/claude_memory/embeddings/fastembed_adapter.rb +43 -13
- data/lib/claude_memory/embeddings/inspector.rb +91 -0
- data/lib/claude_memory/embeddings/model_registry.rb +210 -0
- data/lib/claude_memory/embeddings/resolver.rb +32 -6
- data/lib/claude_memory/ingest/ingester.rb +17 -0
- data/lib/claude_memory/mcp/handlers/management_handlers.rb +24 -0
- data/lib/claude_memory/mcp/handlers/stats_handlers.rb +5 -2
- data/lib/claude_memory/mcp/instructions_builder.rb +17 -0
- data/lib/claude_memory/mcp/server.rb +22 -1
- data/lib/claude_memory/mcp/telemetry.rb +86 -0
- data/lib/claude_memory/mcp/tool_definitions.rb +86 -3
- data/lib/claude_memory/mcp/tools.rb +10 -0
- data/lib/claude_memory/publish.rb +40 -5
- data/lib/claude_memory/recall.rb +81 -0
- data/lib/claude_memory/resolve/predicate_policy.rb +63 -3
- data/lib/claude_memory/resolve/resolver.rb +43 -0
- data/lib/claude_memory/store/schema_manager.rb +1 -1
- data/lib/claude_memory/store/sqlite_store.rb +250 -1
- data/lib/claude_memory/store/store_manager.rb +50 -1
- data/lib/claude_memory/sweep/maintenance.rb +115 -1
- data/lib/claude_memory/sweep/sweeper.rb +3 -0
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +5 -0
- metadata +26 -8
- data/.claude/memory.sqlite3-shm +0 -0
- 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-
|
|
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.
|
|
6
|
-
- *[obra/episodic-memory](https://github.com/obra/episodic-memory) - Semantic conversation search (v1.0.15, studied 2026-03-
|
|
7
|
-
- *[yoanbernabeu/grepai](https://github.com/yoanbernabeu/grepai) - Semantic code search (
|
|
8
|
-
- *[supermemoryai/claude-supermemory](https://github.com/supermemoryai/claude-supermemory) - Cloud-backed persistent memory (v2.0.1, studied 2026-03-
|
|
9
|
-
- *[tobi/qmd](https://github.com/tobi/qmd) - On-device hybrid search engine (v2.0.1, studied 2026-03-
|
|
10
|
-
- *[MadBomber/kbs](https://github.com/MadBomber/kbs) - Knowledge-Based System with RETE inference (v0.2.1, studied 2026-03-
|
|
11
|
-
- *[martian-engineering/lossless-claw](https://github.com/martian-engineering/lossless-claw) - DAG-based lossless context management (v0.
|
|
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.
|
|
245
|
-
- [grepai GitHub](https://github.com/yoanbernabeu/grepai) - Semantic code search (
|
|
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.
|
|
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) -
|
|
253
|
-
- [docs/influence/episodic-memory.md](influence/episodic-memory.md) -
|
|
254
|
-
- [docs/influence/claude-mem.md](influence/claude-mem.md) -
|
|
255
|
-
- [docs/influence/grepai.md](influence/grepai.md) -
|
|
256
|
-
- [docs/influence/claude-supermemory.md](influence/claude-supermemory.md) -
|
|
257
|
-
- [docs/influence/kbs.md](influence/kbs.md) -
|
|
258
|
-
- [docs/influence/lossless-claw.md](influence/lossless-claw.md) -
|
|
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-
|
|
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
|
|
data/docs/influence/grepai.md
CHANGED
|
@@ -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
|
|
data/docs/influence/kbs.md
CHANGED
|
@@ -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
|
|
data/docs/influence/qmd.md
CHANGED
|
@@ -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 =
|
|
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.
|