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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b42d582ddd17dd325f8048268c889d6c80c1ca9c229732da1a8d619279201af
|
|
4
|
+
data.tar.gz: 8853caacc212900483a4a3f9939e8261e18f53b886675f01b4c5a5b61a506d26
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a65038105334c741d26c5e485da7565016ae670ed24f04d4c23b2bb00329d729ee3bfd91cf333ea36ad518937e40e4c95c4d0846bcb423984b0ec683fee59b5a
|
|
7
|
+
data.tar.gz: d94e2ce5fbd1ed496a0c56f094b7f1fbb01b9eb255c819a95b2ffe6ecf79ea9c1706408fd658b2bcaee19d440a87d45a1185a7e471cb05fc7c003d433d6e5808
|
data/.claude/memory.sqlite3
CHANGED
|
Binary file
|
|
@@ -1,21 +1,51 @@
|
|
|
1
|
-
<!--
|
|
1
|
+
<!--
|
|
2
2
|
This file is auto-generated by claude-memory.
|
|
3
3
|
Do not edit manually - changes will be overwritten.
|
|
4
|
-
Generated: 2026-
|
|
4
|
+
Generated: 2026-04-15T17:38:20Z
|
|
5
5
|
-->
|
|
6
6
|
|
|
7
7
|
# Project Memory
|
|
8
8
|
|
|
9
9
|
## Current Decisions
|
|
10
10
|
|
|
11
|
+
- MCP tool-call telemetry stores minimal columns (tool_name, duration_ms, result_count, scope, error_class) — deliberately no query_text or query_hash. YAGNI: hashes are write-only without the raw text, and raw text adds privacy concerns without clear value beyond existing shortcut tools (memory.decisions, memory.conventions).
|
|
11
12
|
- From QMD 2026-02-02 restudy: adopt Claude Code plugin format, MCP structured content pattern, MCP query guide prompt, inline status checks. Carry forward sqlite-vec, RRF, docids, smart expansion from 2026-01-26. Reject custom fine-tuned models, LLM reranking, YAML collections.
|
|
12
13
|
- From claude-supermemory study: adopt SessionStart hook context injection (hookSpecificOutput.additionalContext), tool-specific observation compression, and relative time formatting. Reject cloud storage dependency and no-test approach.
|
|
13
14
|
|
|
14
15
|
## Conventions
|
|
15
16
|
|
|
17
|
+
- Never use Sequel.sqlite for DB reads; this gem only depends on extralite. Use Sequel.connect("extralite://#{db_path}") or SQLiteStore.new. Sequel.sqlite requires the ungem'd sqlite3 adapter and fails at runtime.
|
|
18
|
+
- Two distinct tool_calls tables exist: tool_calls (v3) for transcript-observed Claude Code tool usage, and mcp_tool_calls (v13) for MCP server telemetry. Disjoint purposes, never join.
|
|
19
|
+
- MCP tool-call telemetry is recorded via MCP::Telemetry wrapping Server#handle_tools_call. Writes to mcp_tool_calls table in the project DB. Swallows DB errors so telemetry never breaks a real tool response. Viewable via 'claude-memory stats --tools [--since DAYS]'.
|
|
20
|
+
- mcp_tool_calls retention is 90 days, enforced by Sweep::Maintenance#prune_old_mcp_tool_calls wired into Sweeper#run!. Configurable via mcp_tool_call_retention_days in Maintenance DEFAULT_CONFIG.
|
|
21
|
+
- CLAUDE_CONFIG_DIR env var overrides the default ~/.claude location for Configuration#global_db_path. Access via Configuration#claude_config_dir. Additive, backwards compatible.
|
|
22
|
+
- Registry::COMMANDS stores {class:, description:} entries as the single source of truth for command name, class reference, and shell-completion description. Class constants stored directly (no const_get). Registry.descriptions feeds CompletionCommand; adding a new command requires updating only this hash.
|
|
23
|
+
- Prefer do...end over braces when a block has repeated argument names, multiple expressions, or non-trivial body. Single-expression simple blocks can still use braces.
|
|
24
|
+
- EXPECTED_HOOKS constant must stay in sync with events in HooksConfigurator#build_hooks_config. Adding a new hook event without updating EXPECTED_HOOKS causes false doctor warnings.
|
|
25
|
+
- Tests using --db for hook context only set the project DB path. StoreManager still connects to the real global DB. Must stub Configuration to return a temp global path for isolation.
|
|
26
|
+
- Version must be updated in three places: lib/claude_memory/version.rb, .claude-plugin/plugin.json, .claude-plugin/marketplace.json. Runtime code uses ClaudeMemory::VERSION dynamically.
|
|
27
|
+
- Use module inclusion (not class extraction) to break up god objects — preserves public API so zero tests need modification
|
|
28
|
+
- Configuration class has instance methods only — use Configuration.new.global_db_path, not Configuration.global_db_path. Stub with instance_double + allow(Configuration).to receive(:new).and_return(config)
|
|
29
|
+
- OperationTracker.reset_stuck_operations only resets operations older than 24 hours (STALE_THRESHOLD_SECONDS). Tests must backdate started_at to trigger resets.
|
|
30
|
+
- SCHEMA_VERSION constant lives in Store::SchemaManager module but is accessible as SQLiteStore::SCHEMA_VERSION via Ruby include-based constant lookup
|
|
16
31
|
- MCP tools return dual content (text summary) + structuredContent (JSON) via TextSummary module and Server#handle_tools_call. Compact mode (compact: true) omits receipts for ~60% smaller responses.
|
|
17
32
|
- ContentSanitizer strips system-reminder, local-command-caveat, command-message, command-name, command-args tags in addition to private/no-memory/secret/claude-memory-context.
|
|
18
33
|
- Core::RelativeTime module provides progressive time formatting: just now → Xm ago → Xh ago → Xd ago → YYYY-MM-DD. Used in ResponseFormatter for *_ago fields.
|
|
19
34
|
- MCP server registers memory_guide prompt via prompts/list and prompts/get endpoints. QueryGuide module holds prompt content.
|
|
20
35
|
- Claude Code plugin with marketplace.json, skill definitions, MCP server bundling. 5,700+ stars, by Tobi Lütke. Custom fine-tuned query expansion (Qwen3-1.7B, SFT+GRPO). Dual content/structuredContent MCP pattern.
|
|
21
36
|
- Cloud-backed Claude Code plugin (~1,195 LOC JavaScript) using Supermemory API for persistent memory across sessions. Uses hooks for SessionStart context injection and Stop transcript capture. No local database.
|
|
37
|
+
|
|
38
|
+
## Technical Constraints
|
|
39
|
+
|
|
40
|
+
- **Uses database**: sqlite
|
|
41
|
+
|
|
42
|
+
## Additional Knowledge
|
|
43
|
+
|
|
44
|
+
### Architecture
|
|
45
|
+
|
|
46
|
+
- MCP::Tools: Thin 104-line dispatcher that includes 6 handler modules in mcp/handlers/: QueryHandlers, ShortcutHandlers, ContextHandlers, ManagementHandlers, StatsHandlers, SetupHandlers
|
|
47
|
+
- Recall: 94-line facade delegating to @engine (DualEngine or LegacyEngine), both include shared QueryCore module with all store-level query logic
|
|
48
|
+
- SQLiteStore: 386-line CRUD class that includes RetryHandler (retry/connection logic) and SchemaManager (migrations/version sync) modules
|
|
49
|
+
- Embeddings: Pluggable providers via Embeddings.resolve(name, env:). Three providers: tfidf (default), fastembed, api. Duck-typed contract: name, dimensions, generate(text). ENV: CLAUDE_MEMORY_EMBEDDING_PROVIDER
|
|
50
|
+
- Embeddings::DimensionCheck: Pure value object — DimensionCheck.call(store, provider) returns Data.define Result with :fresh/:match/:mismatch status. No side effects; caller decides how to handle mismatch.
|
|
51
|
+
|
data/.claude/settings.json
CHANGED
|
@@ -5,17 +5,21 @@
|
|
|
5
5
|
"hooks": [
|
|
6
6
|
{
|
|
7
7
|
"type": "command",
|
|
8
|
-
"command": "claude-memory hook ingest",
|
|
9
|
-
"timeout": 5
|
|
8
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
9
|
+
"timeout": 5,
|
|
10
|
+
"statusMessage": "Saving memory..."
|
|
10
11
|
}
|
|
11
12
|
]
|
|
12
|
-
}
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"StopFailure": [
|
|
13
16
|
{
|
|
14
17
|
"hooks": [
|
|
15
18
|
{
|
|
16
19
|
"type": "command",
|
|
17
20
|
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
18
|
-
"timeout": 5
|
|
21
|
+
"timeout": 5,
|
|
22
|
+
"statusMessage": "Saving memory..."
|
|
19
23
|
}
|
|
20
24
|
]
|
|
21
25
|
}
|
|
@@ -26,87 +30,56 @@
|
|
|
26
30
|
{
|
|
27
31
|
"type": "command",
|
|
28
32
|
"command": "claude-memory hook context",
|
|
29
|
-
"timeout": 5
|
|
33
|
+
"timeout": 5,
|
|
34
|
+
"statusMessage": "Loading memory..."
|
|
30
35
|
}
|
|
31
36
|
]
|
|
32
37
|
}
|
|
33
38
|
],
|
|
34
39
|
"PreCompact": [
|
|
35
|
-
{
|
|
36
|
-
"hooks": [
|
|
37
|
-
{
|
|
38
|
-
"type": "command",
|
|
39
|
-
"command": "claude-memory hook ingest",
|
|
40
|
-
"timeout": 30
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"type": "command",
|
|
44
|
-
"command": "claude-memory hook sweep",
|
|
45
|
-
"timeout": 30
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
},
|
|
49
40
|
{
|
|
50
41
|
"hooks": [
|
|
51
42
|
{
|
|
52
43
|
"type": "command",
|
|
53
44
|
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
54
|
-
"timeout": 30
|
|
45
|
+
"timeout": 30,
|
|
46
|
+
"statusMessage": "Saving memory..."
|
|
55
47
|
},
|
|
56
48
|
{
|
|
57
49
|
"type": "command",
|
|
58
50
|
"command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
59
|
-
"timeout": 30
|
|
51
|
+
"timeout": 30,
|
|
52
|
+
"statusMessage": "Sweeping memory..."
|
|
60
53
|
}
|
|
61
54
|
]
|
|
62
55
|
}
|
|
63
56
|
],
|
|
64
57
|
"SessionEnd": [
|
|
65
|
-
{
|
|
66
|
-
"hooks": [
|
|
67
|
-
{
|
|
68
|
-
"type": "command",
|
|
69
|
-
"command": "claude-memory hook ingest",
|
|
70
|
-
"timeout": 30
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"type": "command",
|
|
74
|
-
"command": "claude-memory hook sweep",
|
|
75
|
-
"timeout": 30
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
},
|
|
79
58
|
{
|
|
80
59
|
"hooks": [
|
|
81
60
|
{
|
|
82
61
|
"type": "command",
|
|
83
62
|
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
84
|
-
"timeout": 30
|
|
63
|
+
"timeout": 30,
|
|
64
|
+
"statusMessage": "Saving memory..."
|
|
85
65
|
},
|
|
86
66
|
{
|
|
87
67
|
"type": "command",
|
|
88
68
|
"command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
89
|
-
"timeout": 30
|
|
69
|
+
"timeout": 30,
|
|
70
|
+
"statusMessage": "Sweeping memory..."
|
|
90
71
|
}
|
|
91
72
|
]
|
|
92
73
|
}
|
|
93
74
|
],
|
|
94
75
|
"TaskCompleted": [
|
|
95
|
-
{
|
|
96
|
-
"hooks": [
|
|
97
|
-
{
|
|
98
|
-
"type": "command",
|
|
99
|
-
"command": "claude-memory hook ingest",
|
|
100
|
-
"timeout": 10
|
|
101
|
-
}
|
|
102
|
-
]
|
|
103
|
-
},
|
|
104
76
|
{
|
|
105
77
|
"hooks": [
|
|
106
78
|
{
|
|
107
79
|
"type": "command",
|
|
108
80
|
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
109
|
-
"timeout": 10
|
|
81
|
+
"timeout": 10,
|
|
82
|
+
"statusMessage": "Saving memory..."
|
|
110
83
|
}
|
|
111
84
|
]
|
|
112
85
|
}
|
|
@@ -116,17 +89,22 @@
|
|
|
116
89
|
"hooks": [
|
|
117
90
|
{
|
|
118
91
|
"type": "command",
|
|
119
|
-
"command": "claude-memory hook ingest",
|
|
120
|
-
"timeout": 15
|
|
92
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
93
|
+
"timeout": 15,
|
|
94
|
+
"statusMessage": "Saving memory..."
|
|
121
95
|
}
|
|
122
96
|
]
|
|
123
|
-
}
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"Notification": [
|
|
124
100
|
{
|
|
101
|
+
"matcher": "idle_prompt",
|
|
125
102
|
"hooks": [
|
|
126
103
|
{
|
|
127
104
|
"type": "command",
|
|
128
|
-
"command": "claude-memory hook
|
|
129
|
-
"timeout":
|
|
105
|
+
"command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
106
|
+
"timeout": 10,
|
|
107
|
+
"statusMessage": "Sweeping memory..."
|
|
130
108
|
}
|
|
131
109
|
]
|
|
132
110
|
}
|
data/.claude/settings.local.json
CHANGED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-dependencies
|
|
3
|
+
description: "Upgrade all Ruby gem dependencies to their latest versions with release note review and codebase alignment checks. Use this skill whenever the user asks to update, upgrade, or bump dependencies, gems, or packages — even casually like 'update my gems' or 'are my deps up to date?'"
|
|
4
|
+
agent: general-purpose
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Bash, Edit, Write, Agent, WebFetch
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Dependency Upgrade Skill
|
|
9
|
+
|
|
10
|
+
Systematically upgrade Ruby gem dependencies by researching latest versions, reviewing release notes for breaking changes, updating version constraints, verifying with tests, and confirming codebase alignment.
|
|
11
|
+
|
|
12
|
+
The goal is a *thoughtful* upgrade — not blindly bumping versions, but understanding what changed and ensuring the codebase is compatible. This matters because a silent API change can introduce bugs that tests don't catch if the tests don't exercise the affected code path.
|
|
13
|
+
|
|
14
|
+
## Process Overview
|
|
15
|
+
|
|
16
|
+
1. **Discover** current dependencies and their constraints
|
|
17
|
+
2. **Research** latest versions and release notes (in parallel)
|
|
18
|
+
3. **Analyze** breaking changes and codebase impact
|
|
19
|
+
4. **Upgrade** version constraints and install
|
|
20
|
+
5. **Verify** with the full test suite
|
|
21
|
+
6. **Report** a summary table with upgrade details
|
|
22
|
+
|
|
23
|
+
## Step 1: Discover Current Dependencies
|
|
24
|
+
|
|
25
|
+
Read the gemspec and Gemfile to build a complete dependency inventory.
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Read *.gemspec → runtime dependencies (add_dependency)
|
|
29
|
+
Read Gemfile → development dependencies (gem declarations)
|
|
30
|
+
Run: bundle outdated → current vs latest versions, which are constrained
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Build a working list with these columns:
|
|
34
|
+
- **Gem name**
|
|
35
|
+
- **Source** (gemspec or Gemfile)
|
|
36
|
+
- **Current constraint** (e.g., `~> 5.0`)
|
|
37
|
+
- **Installed version** (from `bundle outdated` or `Gemfile.lock`)
|
|
38
|
+
- **Latest version** (from `bundle outdated`)
|
|
39
|
+
- **Constrained?** (is the version constraint preventing upgrade?)
|
|
40
|
+
|
|
41
|
+
## Step 2: Research Release Notes
|
|
42
|
+
|
|
43
|
+
For each gem that has a newer version available, research what changed. Launch these as parallel Agent subagents — one per gem — to avoid sequential delays.
|
|
44
|
+
|
|
45
|
+
Each research agent should:
|
|
46
|
+
|
|
47
|
+
1. Run `gem search <name> --exact --versions` to confirm the latest version
|
|
48
|
+
2. Fetch the changelog or release notes from GitHub (check CHANGELOG.md, CHANGES, HISTORY.md, or GitHub Releases)
|
|
49
|
+
3. Summarize changes between the installed version and latest version
|
|
50
|
+
4. Flag any **breaking changes**, **deprecations**, or **API changes**
|
|
51
|
+
5. Note if it's a **major version bump** (higher risk)
|
|
52
|
+
|
|
53
|
+
For transitive dependencies (not directly declared but showing in `bundle outdated`), research is optional — focus on direct dependencies. Transitive deps are upgraded automatically when their parent gem allows it.
|
|
54
|
+
|
|
55
|
+
### What to look for in release notes
|
|
56
|
+
|
|
57
|
+
- **Removed methods or classes** the codebase might use
|
|
58
|
+
- **Renamed options or changed defaults** that could silently alter behavior
|
|
59
|
+
- **New required arguments** to methods we call
|
|
60
|
+
- **Deprecated features** we rely on (working now, but will break later)
|
|
61
|
+
- **Changed return types** or data structures
|
|
62
|
+
- **Minimum Ruby version bumps** that could affect CI or deployment
|
|
63
|
+
|
|
64
|
+
## Step 3: Analyze Codebase Impact
|
|
65
|
+
|
|
66
|
+
For each gem with breaking changes or API modifications:
|
|
67
|
+
|
|
68
|
+
1. **Grep the codebase** for usage of affected APIs
|
|
69
|
+
2. **Check test coverage** — are the affected code paths tested?
|
|
70
|
+
3. **Determine if changes are needed** before or after the upgrade
|
|
71
|
+
|
|
72
|
+
Classify each upgrade:
|
|
73
|
+
|
|
74
|
+
- **Safe** — no breaking changes, or breaking changes don't affect our usage
|
|
75
|
+
- **Needs code changes** — our code uses a deprecated or removed API
|
|
76
|
+
- **Held back** — a transitive dependency constraint prevents the upgrade (explain which parent gem and why)
|
|
77
|
+
|
|
78
|
+
If code changes are needed, make them *before* bumping the version constraint so the upgrade commit is clean.
|
|
79
|
+
|
|
80
|
+
## Step 4: Upgrade Dependencies
|
|
81
|
+
|
|
82
|
+
### Gemspec dependencies (runtime)
|
|
83
|
+
|
|
84
|
+
Update version constraints to target the latest version. Use `~>` with the appropriate precision:
|
|
85
|
+
|
|
86
|
+
- For stable gems (1.0+): `~> X.Y` allows patch updates (e.g., `~> 5.102` allows 5.102.x)
|
|
87
|
+
- For pre-1.0 gems: `~> 0.X, ">= 0.X.Y"` to pin a minimum while allowing patches
|
|
88
|
+
- For gems where a specific fix matters: add `">= X.Y.Z"` as an additional constraint
|
|
89
|
+
|
|
90
|
+
### Gemfile dependencies (development)
|
|
91
|
+
|
|
92
|
+
Same approach. If a major version bump is available (e.g., lefthook 1.x → 2.x), check the migration guide before bumping.
|
|
93
|
+
|
|
94
|
+
### Install
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
bundle update
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If `bundle update` fails due to dependency conflicts, resolve them. Common strategies:
|
|
101
|
+
- Relax an overly tight constraint
|
|
102
|
+
- Update the conflicting parent gem first
|
|
103
|
+
- Accept that a gem can't be upgraded yet and document why
|
|
104
|
+
|
|
105
|
+
## Step 5: Verify with Tests
|
|
106
|
+
|
|
107
|
+
Run the full test suite:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
bundle exec rspec
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Also run the linter to catch any style issues:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
bundle exec rake standard
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If tests fail:
|
|
120
|
+
1. Read the failure carefully — is it caused by the upgrade or pre-existing?
|
|
121
|
+
2. If caused by the upgrade, fix the code to work with the new version
|
|
122
|
+
3. If unfixable, revert that specific gem's upgrade and note it in the report
|
|
123
|
+
|
|
124
|
+
## Step 6: Present Summary
|
|
125
|
+
|
|
126
|
+
Present a clear summary table of all changes:
|
|
127
|
+
|
|
128
|
+
```markdown
|
|
129
|
+
| Gem | Old Version | New Version | Old Constraint | New Constraint | Notes |
|
|
130
|
+
|-----|------------|-------------|----------------|----------------|-------|
|
|
131
|
+
| sequel | 5.100.0 | 5.102.0 | ~> 5.0 | ~> 5.102 | No breaking changes |
|
|
132
|
+
| lefthook | 1.13.6 | 2.1.4 | ~> 1.6 | ~> 2.1 | Major version bump, reviewed migration guide |
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Follow the table with:
|
|
136
|
+
|
|
137
|
+
1. **Breaking changes found** — what changed and how the codebase was updated
|
|
138
|
+
2. **Gems held back** — which gems couldn't be upgraded and why (e.g., "diff-lcs 2.0 held back by rspec's ~> 1.4 constraint")
|
|
139
|
+
3. **Notable new features** — anything worth adopting from the new versions
|
|
140
|
+
4. **Test results** — confirmation that all tests pass
|
|
141
|
+
|
|
142
|
+
## Edge Cases
|
|
143
|
+
|
|
144
|
+
### Gems with no GitHub repository
|
|
145
|
+
Fall back to `gem info <name>` and the RubyGems page for release history. Note reduced confidence in the review.
|
|
146
|
+
|
|
147
|
+
### Yanked versions
|
|
148
|
+
If `bundle update` fails because a version was yanked, try the next most recent version.
|
|
149
|
+
|
|
150
|
+
### Pre-release versions
|
|
151
|
+
Do not upgrade to pre-release or alpha versions unless the user explicitly asks. Stick to stable releases.
|
|
152
|
+
|
|
153
|
+
### Monorepo gems
|
|
154
|
+
Some gems (like rails components) are versioned together. Upgrade them as a group.
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
"plugins": [
|
|
8
8
|
{
|
|
9
9
|
"name": "claude-memory",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.9.0",
|
|
11
11
|
"source": "./",
|
|
12
|
-
"description": "Long-term
|
|
12
|
+
"description": "Long-term memory for Claude Code. Recalls architecture, conventions, and decisions across sessions — so Claude explains your codebase without file traversal, follows your patterns, and never re-asks what it already learned.",
|
|
13
13
|
"repository": "https://github.com/codenamev/claude_memory"
|
|
14
14
|
}
|
|
15
15
|
]
|
data/.claude-plugin/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-memory",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Long-term
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "Long-term memory for Claude Code. Recalls architecture, conventions, and decisions across sessions — so Claude explains your codebase without file traversal, follows your patterns, and never re-asks what it already learned.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Valentino Stoll",
|
|
7
7
|
"email": "v@codenamev.com"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"homepage": "https://github.com/codenamev/claude_memory",
|
|
10
10
|
"repository": "https://github.com/codenamev/claude_memory",
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"keywords": ["memory", "
|
|
12
|
+
"keywords": ["memory", "architecture", "conventions", "decisions", "recall", "preferences", "long-term-memory"],
|
|
13
13
|
"mcpServers": {
|
|
14
14
|
"memory": {
|
|
15
15
|
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/serve-mcp.sh",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Generic hook delegate for claude-memory.
|
|
3
|
+
# Used by the Claude Code plugin to run hook subcommands.
|
|
4
|
+
# Usage: hook-runner.sh <subcommand> [args...]
|
|
5
|
+
# Exit 0 on missing binary to avoid blocking Claude Code.
|
|
6
|
+
|
|
7
|
+
set -uo pipefail
|
|
8
|
+
|
|
9
|
+
if command -v claude-memory > /dev/null 2>&1; then
|
|
10
|
+
exec claude-memory hook "$@"
|
|
11
|
+
else
|
|
12
|
+
echo "claude-memory gem not found. Install with: gem install claude_memory" >&2
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Wrapper script for claude-memory MCP server.
|
|
3
|
+
# Used by the Claude Code plugin to launch the MCP server.
|
|
4
|
+
# Falls back to a JSON-RPC error if the gem is not installed.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
if command -v claude-memory > /dev/null 2>&1; then
|
|
9
|
+
exec claude-memory serve-mcp
|
|
10
|
+
else
|
|
11
|
+
# Return a JSON-RPC error so Claude Code surfaces it to the user
|
|
12
|
+
echo '{"jsonrpc":"2.0","id":1,"error":{"code":-32603,"message":"claude-memory gem not found. Install with: gem install claude_memory"}}'
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.0.
|
|
1
|
+
4.0.2
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,47 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.0] - 2026-04-16
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `claude-memory reject <id_or_docid>` command + `memory.reject_fact` MCP tool — explicitly mark distiller hallucinations as wrong, closing associated conflicts
|
|
12
|
+
- `claude-memory restore --predicate NAME` command — recover facts that were superseded by obsolete single-value predicate classifications (uses Jaccard-based token overlap to distinguish bug-caused supersession from real corrections)
|
|
13
|
+
- MCP tool-call telemetry: `mcp_tool_calls` table records every tool invocation with timing, result counts, and error classification. `claude-memory stats --tools [--since DAYS]` for usage reporting. 90-day retention via Sweep
|
|
14
|
+
- `CLAUDE_CONFIG_DIR` env var support for non-standard Claude Code config locations
|
|
15
|
+
- Predicate synonym canonicalization at insert time (`has_convention` → `convention`, `primary_language` → `uses_language`). Prevents drift from fragmenting the knowledge graph
|
|
16
|
+
- Novel predicate warnings at insert time — logged when the Resolver encounters a predicate not in PredicatePolicy
|
|
17
|
+
- NullDistiller now emits `uses_language` facts for detected language entities
|
|
18
|
+
- Proactive memory recall guidance in MCP instructions — Claude now checks conventions before code generation, architecture before explanations, decisions before refactoring
|
|
19
|
+
- YARD documentation across 13 core source files (+473 lines)
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`uses_framework` reclassified as multi-value** — real projects use multiple frameworks (Rails + Turbo + Tailwind). The prior single-value classification silently superseded valid facts in production databases. Run `claude-memory restore --predicate uses_framework` to recover affected facts
|
|
24
|
+
- `PredicatePolicy` is now the single source of truth for predicate vocabulary, snapshot section mapping, synonym canonicalization, and LLM guidance. `tool_definitions.rb`, `publish.rb`, and `distill-transcripts.md` all derive from the policy
|
|
25
|
+
- Predicate vocabulary curated from 13 → 8 based on multi-project usage data. Removed predicates (`preference`, `workflow`, `dependency`, `testing_strategy`, `tool_usage`, `ci_platform`, `primary_language`) had zero facts across all surveyed databases. They still work via DEFAULT_POLICY but are no longer advertised to the LLM
|
|
26
|
+
- `Registry::COMMANDS` stores `{class:, description:}` entries with direct class references instead of string class names
|
|
27
|
+
- Plugin and gem descriptions rewritten from mechanism-focused to outcome-focused
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **`StatsCommand` broken in production** — used `Sequel.sqlite` which requires the unlisted `sqlite3` gem. Now uses the extralite adapter consistently
|
|
32
|
+
- Missing `embeddings` command in shell completion output
|
|
33
|
+
|
|
34
|
+
### Upgrade Notes
|
|
35
|
+
|
|
36
|
+
**Schema**: v12 → v14 (two automatic migrations). Migration 013 adds `mcp_tool_calls` table. Migration 014 canonicalizes stale predicate names (`has_convention` → `convention`, `primary_language` → `uses_language`) in existing facts.
|
|
37
|
+
|
|
38
|
+
**Action required for `uses_framework` recovery**: If your project uses multiple frameworks (Rails + Turbo + Tailwind, etc.), past sessions may have superseded valid facts. After upgrading, run:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
claude-memory restore --predicate uses_framework --dry-run # preview
|
|
42
|
+
claude-memory restore --predicate uses_framework # restore
|
|
43
|
+
claude-memory restore --predicate uses_framework --scope global # if needed for global DB
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Pruned predicates still work**: `preference`, `workflow`, `dependency`, `testing_strategy`, `tool_usage`, `ci_platform` fall through to the default multi-value policy. Existing facts with these predicates are unaffected. They'll appear as "novel" in `memory.stats` but function normally.
|
|
47
|
+
|
|
7
48
|
## [0.8.0] - 2026-03-30
|
|
8
49
|
|
|
9
50
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -15,6 +15,12 @@ ClaudeMemory is a Ruby gem that provides long-term, self-managed memory for Clau
|
|
|
15
15
|
|
|
16
16
|
**Check memory before exploring code.** Use `memory.recall`, `memory.decisions`, `memory.architecture`, or `memory.conventions` to find existing knowledge before reading files.
|
|
17
17
|
|
|
18
|
+
### Git Usage & Best Practices
|
|
19
|
+
|
|
20
|
+
- Before each commit, apply the quality-review skill
|
|
21
|
+
- Iteratively commit related changes with their tests
|
|
22
|
+
|
|
23
|
+
|
|
18
24
|
## Development Commands
|
|
19
25
|
|
|
20
26
|
### Setup
|
|
@@ -157,7 +163,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
157
163
|
- Each command is a separate class (HelpCommand, DoctorCommand, etc.)
|
|
158
164
|
- All commands inherit from BaseCommand
|
|
159
165
|
- Dependency injection for I/O (stdout, stderr, stdin)
|
|
160
|
-
-
|
|
166
|
+
- 28 commands total, each focused on single responsibility
|
|
161
167
|
|
|
162
168
|
- **`Configuration`**: Centralized ENV access (`configuration.rb`)
|
|
163
169
|
- Single source of truth for paths and environment variables
|
|
@@ -166,7 +172,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
166
172
|
#### Core Domain Layer
|
|
167
173
|
|
|
168
174
|
- **`Domain`**: Rich domain models with business logic (`domain/`)
|
|
169
|
-
- `Fact`: Facts with validation, status checking (active?, superseded?)
|
|
175
|
+
- `Fact`: Facts with validation, status checking (active?, superseded?, rejected?)
|
|
170
176
|
- `Entity`: Entities with type checking (database?, framework?)
|
|
171
177
|
- `Provenance`: Evidence with strength checking (stated?, inferred?)
|
|
172
178
|
- `Conflict`: Conflicts with status tracking (open?, resolved?)
|
|
@@ -182,7 +188,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
182
188
|
- **`Store`**: SQLite database access via Sequel (`store/`)
|
|
183
189
|
- `SQLiteStore`: Database operations
|
|
184
190
|
- `StoreManager`: Dual-database connection manager
|
|
185
|
-
- Schema includes: content_items, entities, facts, provenance, fact_links, conflicts
|
|
191
|
+
- Schema includes: content_items, entities, facts, provenance, fact_links, conflicts, mcp_tool_calls
|
|
186
192
|
- Transaction safety for multi-step operations
|
|
187
193
|
|
|
188
194
|
- **`Infrastructure`**: I/O abstractions (`infrastructure/`)
|
|
@@ -205,7 +211,7 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
205
211
|
|
|
206
212
|
- **`Resolve`**: Truth maintenance and conflict resolution (`resolve/`)
|
|
207
213
|
- Determines equivalence, supersession, or conflicts
|
|
208
|
-
- PredicatePolicy
|
|
214
|
+
- PredicatePolicy: single source of truth for predicate vocabulary, cardinality, section mapping, and synonym canonicalization
|
|
209
215
|
- Transaction safety for atomic operations
|
|
210
216
|
|
|
211
217
|
- **`Recall`**: Query interface for facts (`recall.rb`)
|
|
@@ -220,7 +226,8 @@ New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipel
|
|
|
220
226
|
- Modes: shared (repo), local (uncommitted), home (user directory)
|
|
221
227
|
|
|
222
228
|
- **`MCP`**: Model Context Protocol server and tools (`mcp/`)
|
|
223
|
-
- Exposes memory tools to Claude Code (
|
|
229
|
+
- Exposes memory tools to Claude Code (24 tools total)
|
|
230
|
+
- `Telemetry`: Records tool invocations to `mcp_tool_calls` table for usage stats
|
|
224
231
|
- Dual content/structuredContent responses with compact mode
|
|
225
232
|
|
|
226
233
|
- **`Hook`**: Hook entrypoint handlers (`hook/`)
|
|
@@ -238,6 +245,7 @@ Key tables (defined in `sqlite_store.rb`):
|
|
|
238
245
|
- `provenance`: Links facts to source content_items
|
|
239
246
|
- `fact_links`: Supersession and conflict relationships
|
|
240
247
|
- `conflicts`: Open contradictions
|
|
248
|
+
- `mcp_tool_calls`: MCP server tool invocation telemetry (schema v13)
|
|
241
249
|
|
|
242
250
|
Facts include:
|
|
243
251
|
- `scope`: "global" or "project" (determines applicability)
|
|
@@ -290,28 +298,34 @@ end
|
|
|
290
298
|
|
|
291
299
|
### Adding a New MCP Tool
|
|
292
300
|
|
|
293
|
-
1. Add tool definition to `
|
|
294
|
-
2.
|
|
295
|
-
3.
|
|
296
|
-
4.
|
|
301
|
+
1. Add tool definition to `ToolDefinitions.all` array in `lib/claude_memory/mcp/tool_definitions.rb`
|
|
302
|
+
2. Add `when` clause in `Tools#call` dispatch in `lib/claude_memory/mcp/tools.rb`
|
|
303
|
+
3. Implement handler method in the appropriate handler module in `mcp/handlers/`
|
|
304
|
+
4. Ensure tool queries appropriate database(s) via StoreManager
|
|
305
|
+
5. Add tests in `spec/claude_memory/mcp/`
|
|
297
306
|
|
|
298
307
|
### Modifying Database Schema
|
|
299
308
|
|
|
300
|
-
1. Increment `SCHEMA_VERSION` in `
|
|
301
|
-
2.
|
|
302
|
-
3.
|
|
309
|
+
1. Increment `SCHEMA_VERSION` in `store/schema_manager.rb`
|
|
310
|
+
2. Create a new Sequel migration file in `db/migrations/` (e.g., `013_add_mcp_tool_calls.rb`)
|
|
311
|
+
3. Sequel::Migrator runs migrations automatically in `ensure_schema!`
|
|
303
312
|
4. Test migration on existing database files
|
|
304
313
|
5. Update documentation if schema changes affect external interfaces
|
|
305
314
|
|
|
306
|
-
### Adding a New Predicate
|
|
315
|
+
### Adding a New Predicate
|
|
316
|
+
|
|
317
|
+
Edit `PredicatePolicy::POLICIES` in `lib/claude_memory/resolve/predicate_policy.rb` — this is the single source of truth. Choose cardinality:
|
|
318
|
+
|
|
319
|
+
- **single** (exclusive: true): Facts supersede or conflict (e.g., `uses_database` — one per project)
|
|
320
|
+
- **multi** (exclusive: false): Facts accumulate (e.g., `convention`, `uses_framework`)
|
|
307
321
|
|
|
308
|
-
|
|
322
|
+
Also update `SECTION_MAP` if the predicate should appear in a specific snapshot section (`:decisions`, `:conventions`, `:constraints`). The `ToolDefinitions` predicate list updates automatically via `PredicatePolicy.known_predicates`. Add entries to `SYNONYMS` if the distiller might emit variant names.
|
|
309
323
|
|
|
310
324
|
## Important Files
|
|
311
325
|
|
|
312
326
|
- `lib/claude_memory.rb`: Main module, requires, database path helpers
|
|
313
327
|
- `lib/claude_memory/cli.rb`: Thin command router (41 lines)
|
|
314
|
-
- `lib/claude_memory/commands/`: Individual command classes (
|
|
328
|
+
- `lib/claude_memory/commands/`: Individual command classes (28 commands)
|
|
315
329
|
- `lib/claude_memory/configuration.rb`: Centralized configuration and ENV access
|
|
316
330
|
- `lib/claude_memory/domain/`: Domain models (Fact, Entity, Provenance, Conflict)
|
|
317
331
|
- `lib/claude_memory/core/`: Value objects and null objects
|
|
@@ -326,12 +340,12 @@ Single-value predicates (like "uses_database") supersede old values. Multi-value
|
|
|
326
340
|
|
|
327
341
|
The gem includes an MCP server (`claude-memory serve-mcp`) that exposes memory operations as tools. Configuration should be in `.mcp.json` at project root.
|
|
328
342
|
|
|
329
|
-
Available MCP tools (
|
|
343
|
+
Available MCP tools (24 total):
|
|
330
344
|
- **Query & Recall**: `memory.recall`, `memory.recall_index`, `memory.recall_details`, `memory.recall_semantic`, `memory.search_concepts`
|
|
331
345
|
- **Provenance**: `memory.explain`, `memory.fact_graph`
|
|
332
346
|
- **Shortcuts**: `memory.decisions`, `memory.conventions`, `memory.architecture`
|
|
333
347
|
- **Context**: `memory.facts_by_tool`, `memory.facts_by_context`
|
|
334
|
-
- **Management**: `memory.promote`, `memory.store_extraction`
|
|
348
|
+
- **Management**: `memory.promote`, `memory.reject_fact`, `memory.store_extraction`
|
|
335
349
|
- **Distillation**: `memory.undistilled`, `memory.mark_distilled`
|
|
336
350
|
- **Monitoring**: `memory.status`, `memory.stats`, `memory.changes`, `memory.conflicts`
|
|
337
351
|
- **Maintenance**: `memory.sweep_now`
|