claude_memory 0.7.1 → 0.8.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/memory.sqlite3-shm +0 -0
- data/.claude/memory.sqlite3-wal +0 -0
- data/.claude/settings.json +78 -6
- data/.claude/settings.local.json +2 -1
- data/.claude/skills/improve/SKILL.md +113 -25
- data/.claude-plugin/commands/distill-transcripts.md +98 -0
- data/.claude-plugin/commands/memory-recall.md +67 -0
- data/.claude-plugin/marketplace.json +1 -1
- data/.claude-plugin/plugin.json +1 -1
- data/CHANGELOG.md +49 -1
- data/CLAUDE.md +29 -5
- data/docs/improvements.md +18 -56
- data/docs/quality_review.md +119 -224
- data/hooks/hooks.json +39 -7
- data/lib/claude_memory/commands/checks/distill_check.rb +61 -0
- data/lib/claude_memory/commands/checks/hooks_check.rb +2 -2
- data/lib/claude_memory/commands/checks/vec_check.rb +2 -1
- data/lib/claude_memory/commands/completion_command.rb +179 -0
- data/lib/claude_memory/commands/doctor_command.rb +2 -0
- data/lib/claude_memory/commands/help_command.rb +4 -0
- data/lib/claude_memory/commands/hook_command.rb +2 -1
- data/lib/claude_memory/commands/index_command.rb +85 -78
- data/lib/claude_memory/commands/initializers/database_ensurer.rb +16 -0
- data/lib/claude_memory/commands/initializers/global_initializer.rb +2 -1
- data/lib/claude_memory/commands/initializers/hooks_configurator.rb +55 -11
- data/lib/claude_memory/commands/initializers/project_initializer.rb +2 -1
- data/lib/claude_memory/commands/install_skill_command.rb +78 -0
- data/lib/claude_memory/commands/registry.rb +3 -1
- data/lib/claude_memory/commands/skills/distill-transcripts.md +98 -0
- data/lib/claude_memory/commands/skills/memory-recall.md +67 -0
- data/lib/claude_memory/core/fact_ranker.rb +2 -2
- data/lib/claude_memory/core/rr_fusion.rb +23 -6
- data/lib/claude_memory/core/snippet_extractor.rb +7 -3
- data/lib/claude_memory/core/text_builder.rb +11 -0
- data/lib/claude_memory/domain/provenance.rb +0 -1
- data/lib/claude_memory/embeddings/api_adapter.rb +96 -0
- data/lib/claude_memory/embeddings/dimension_check.rb +23 -0
- data/lib/claude_memory/embeddings/fastembed_adapter.rb +4 -0
- data/lib/claude_memory/embeddings/generator.rb +4 -0
- data/lib/claude_memory/embeddings/resolver.rb +18 -0
- data/lib/claude_memory/hook/context_injector.rb +58 -2
- data/lib/claude_memory/hook/distillation_runner.rb +46 -0
- data/lib/claude_memory/hook/handler.rb +11 -2
- data/lib/claude_memory/index/vector_index.rb +15 -2
- data/lib/claude_memory/infrastructure/schema_validator.rb +3 -3
- data/lib/claude_memory/mcp/handlers/context_handlers.rb +38 -0
- data/lib/claude_memory/mcp/handlers/management_handlers.rb +145 -0
- data/lib/claude_memory/mcp/handlers/query_handlers.rb +115 -0
- data/lib/claude_memory/mcp/handlers/setup_handlers.rb +211 -0
- data/lib/claude_memory/mcp/handlers/shortcut_handlers.rb +37 -0
- data/lib/claude_memory/mcp/handlers/stats_handlers.rb +202 -0
- data/lib/claude_memory/mcp/instructions_builder.rb +2 -1
- data/lib/claude_memory/mcp/query_guide.rb +10 -0
- data/lib/claude_memory/mcp/response_formatter.rb +1 -0
- data/lib/claude_memory/mcp/text_summary.rb +26 -0
- data/lib/claude_memory/mcp/tool_definitions.rb +30 -1
- data/lib/claude_memory/mcp/tool_helpers.rb +43 -0
- data/lib/claude_memory/mcp/tools.rb +39 -678
- data/lib/claude_memory/recall/dual_engine.rb +105 -0
- data/lib/claude_memory/recall/legacy_engine.rb +138 -0
- data/lib/claude_memory/recall/query_core.rb +371 -0
- data/lib/claude_memory/recall.rb +29 -662
- data/lib/claude_memory/shortcuts.rb +4 -4
- data/lib/claude_memory/store/retry_handler.rb +61 -0
- data/lib/claude_memory/store/schema_manager.rb +68 -0
- data/lib/claude_memory/store/sqlite_store.rb +85 -201
- data/lib/claude_memory/templates/hooks.example.json +26 -7
- data/lib/claude_memory/version.rb +1 -1
- data/lib/claude_memory.rb +11 -0
- metadata +23 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1483a3663c9c589abad58f80c71d772c592f13727d3fd1339418c2ba1a3db875
|
|
4
|
+
data.tar.gz: 34beebdf5e3cc8a70d383757ffaf7e21fde0724f963532e2d2548ec2e63ba329
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 514022df68751e4421942d914c003a1e104a5c2b5ab4a639619ca05bb4d6bafd722d87009dc898a5b578f1b7efdae50df68b5b8232e1cf42a8bb5e88a06e66c3
|
|
7
|
+
data.tar.gz: 68c5a36361d3048e4c92bba7127e7fa0bc9ff09f6de3779ae59f7799cd4152d63030386ea2b124a90b345063545028b0da0401c9144f284c7e34290b2d674ba7
|
data/.claude/memory.sqlite3
CHANGED
|
Binary file
|
data/.claude/memory.sqlite3-shm
CHANGED
|
Binary file
|
data/.claude/memory.sqlite3-wal
CHANGED
|
Binary file
|
data/.claude/settings.json
CHANGED
|
@@ -6,7 +6,16 @@
|
|
|
6
6
|
{
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "claude-memory hook ingest",
|
|
9
|
-
"timeout":
|
|
9
|
+
"timeout": 5
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"hooks": [
|
|
15
|
+
{
|
|
16
|
+
"type": "command",
|
|
17
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
18
|
+
"timeout": 5
|
|
10
19
|
}
|
|
11
20
|
]
|
|
12
21
|
}
|
|
@@ -14,11 +23,6 @@
|
|
|
14
23
|
"SessionStart": [
|
|
15
24
|
{
|
|
16
25
|
"hooks": [
|
|
17
|
-
{
|
|
18
|
-
"type": "command",
|
|
19
|
-
"command": "claude-memory hook ingest",
|
|
20
|
-
"timeout": 10
|
|
21
|
-
},
|
|
22
26
|
{
|
|
23
27
|
"type": "command",
|
|
24
28
|
"command": "claude-memory hook context",
|
|
@@ -41,6 +45,20 @@
|
|
|
41
45
|
"timeout": 30
|
|
42
46
|
}
|
|
43
47
|
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"hooks": [
|
|
51
|
+
{
|
|
52
|
+
"type": "command",
|
|
53
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
54
|
+
"timeout": 30
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
59
|
+
"timeout": 30
|
|
60
|
+
}
|
|
61
|
+
]
|
|
44
62
|
}
|
|
45
63
|
],
|
|
46
64
|
"SessionEnd": [
|
|
@@ -57,6 +75,60 @@
|
|
|
57
75
|
"timeout": 30
|
|
58
76
|
}
|
|
59
77
|
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"hooks": [
|
|
81
|
+
{
|
|
82
|
+
"type": "command",
|
|
83
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
84
|
+
"timeout": 30
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"type": "command",
|
|
88
|
+
"command": "claude-memory hook sweep --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
89
|
+
"timeout": 30
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"TaskCompleted": [
|
|
95
|
+
{
|
|
96
|
+
"hooks": [
|
|
97
|
+
{
|
|
98
|
+
"type": "command",
|
|
99
|
+
"command": "claude-memory hook ingest",
|
|
100
|
+
"timeout": 10
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"hooks": [
|
|
106
|
+
{
|
|
107
|
+
"type": "command",
|
|
108
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
109
|
+
"timeout": 10
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"TeammateIdle": [
|
|
115
|
+
{
|
|
116
|
+
"hooks": [
|
|
117
|
+
{
|
|
118
|
+
"type": "command",
|
|
119
|
+
"command": "claude-memory hook ingest",
|
|
120
|
+
"timeout": 15
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"hooks": [
|
|
126
|
+
{
|
|
127
|
+
"type": "command",
|
|
128
|
+
"command": "claude-memory hook ingest --db /Users/valentinostoll/src/claude_memory/.claude/memory.sqlite3",
|
|
129
|
+
"timeout": 15
|
|
130
|
+
}
|
|
131
|
+
]
|
|
60
132
|
}
|
|
61
133
|
]
|
|
62
134
|
}
|
data/.claude/settings.local.json
CHANGED
|
@@ -3,23 +3,88 @@ name: improve
|
|
|
3
3
|
description: Incrementally implement feature improvements from docs/improvements.md with tests and atomic commits. Focuses on new functionality rather than refactoring.
|
|
4
4
|
agent: general-purpose
|
|
5
5
|
allowed-tools: Read, Grep, Edit, Write, Bash
|
|
6
|
+
arguments:
|
|
7
|
+
- name: mode
|
|
8
|
+
description: "Execution mode: 'sub-agent' (default, sequential) or 'agent-team' (parallel via agent teams)"
|
|
9
|
+
required: false
|
|
10
|
+
default: "sub-agent"
|
|
6
11
|
---
|
|
7
12
|
|
|
8
13
|
# Feature Improvements - Incremental Implementation
|
|
9
14
|
|
|
10
15
|
Systematically implement feature improvements from `docs/improvements.md`, making tested, atomic commits for each feature addition.
|
|
11
16
|
|
|
17
|
+
## Execution Modes
|
|
18
|
+
|
|
19
|
+
This skill supports two modes, passed as the first argument:
|
|
20
|
+
|
|
21
|
+
- **`sub-agent`** (default): A single agent works through improvements sequentially. Best for small batches (1-3 features) or features with dependencies.
|
|
22
|
+
- **`agent-team`**: Spawns a coordinated team of agents that implement independent features in parallel. Best for larger batches (3+) of independent features.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Mode: agent-team
|
|
27
|
+
|
|
28
|
+
When invoked with `agent-team`, follow this process:
|
|
29
|
+
|
|
30
|
+
### Step 1: Read and Assess Improvements
|
|
31
|
+
|
|
32
|
+
Read `docs/improvements.md` and identify all implementable features using the same feasibility criteria as sub-agent mode (skip Categories D-F, "Features to Avoid", "If Requested" items).
|
|
33
|
+
|
|
34
|
+
### Step 2: Group Independent Features
|
|
35
|
+
|
|
36
|
+
Partition implementable features into independent groups:
|
|
37
|
+
- Features touching **different files** can be parallelized
|
|
38
|
+
- Features sharing files or with dependencies must be sequential
|
|
39
|
+
- Aim for 3-5 teammates maximum
|
|
40
|
+
|
|
41
|
+
### Step 3: Create the Agent Team
|
|
42
|
+
|
|
43
|
+
Create an agent team. For each teammate:
|
|
44
|
+
|
|
45
|
+
1. **Assign one or two related features** per teammate
|
|
46
|
+
2. **Provide full context** — teammates don't share your conversation history
|
|
47
|
+
3. **Include these instructions for each teammate**:
|
|
48
|
+
- Read relevant existing code before making changes
|
|
49
|
+
- Follow the project's code style (Standard Ruby, frozen_string_literal)
|
|
50
|
+
- Write tests for all new functionality
|
|
51
|
+
- Run `bundle exec rake standard:fix` before committing
|
|
52
|
+
- Run relevant spec file after each edit, full suite before committing
|
|
53
|
+
- Run `bundle exec rspec` to verify all tests pass
|
|
54
|
+
- Make atomic commits with `[Feature]` prefix format
|
|
55
|
+
- Update `docs/improvements.md` to mark features as implemented
|
|
56
|
+
- Reference `.claude/skills/improve/feature-patterns.md` for implementation recipes
|
|
57
|
+
|
|
58
|
+
### Step 4: Monitor and Coordinate
|
|
59
|
+
|
|
60
|
+
- Wait for all teammates to complete their tasks
|
|
61
|
+
- If a teammate reports a blocker or conflict, help resolve it
|
|
62
|
+
- Do NOT implement tasks yourself — let teammates do the work
|
|
63
|
+
|
|
64
|
+
### Step 5: Validate and Report
|
|
65
|
+
|
|
66
|
+
After all teammates finish:
|
|
67
|
+
|
|
68
|
+
1. Run the full test suite: `bundle exec rspec`
|
|
69
|
+
2. Run the linter: `bundle exec rake standard:fix`
|
|
70
|
+
3. If any failures, fix them or coordinate with the relevant teammate
|
|
71
|
+
4. Provide a consolidated progress report (same Final Report format as sub-agent mode)
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Mode: sub-agent (default)
|
|
76
|
+
|
|
12
77
|
## Process Overview
|
|
13
78
|
|
|
14
79
|
1. **Check memory health** by calling `memory.check_setup` to verify the system is operational
|
|
15
80
|
2. **Read the improvements document** from `docs/improvements.md`
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
81
|
+
3. **Identify unimplemented features** from "Remaining Tasks" section
|
|
82
|
+
4. **Prioritize by stated priority** (Medium → Low)
|
|
83
|
+
5. **Assess feasibility** (skip if too complex or requires external services)
|
|
84
|
+
6. **Implement features incrementally** (one logical feature at a time)
|
|
85
|
+
7. **Run tests after each change** to ensure nothing breaks
|
|
86
|
+
8. **Make atomic commits** that capture the feature and its purpose
|
|
87
|
+
9. **Update improvements.md** to mark features as implemented
|
|
23
88
|
|
|
24
89
|
## Detailed Steps
|
|
25
90
|
|
|
@@ -100,11 +165,15 @@ For each feature:
|
|
|
100
165
|
```bash
|
|
101
166
|
bundle exec rake standard:fix
|
|
102
167
|
```
|
|
103
|
-
5. **Run tests
|
|
168
|
+
5. **Run targeted tests** after each edit:
|
|
169
|
+
```bash
|
|
170
|
+
bundle exec rspec spec/claude_memory/<relevant_spec>.rb
|
|
171
|
+
```
|
|
172
|
+
6. **Run full suite** before committing:
|
|
104
173
|
```bash
|
|
105
174
|
bundle exec rspec
|
|
106
175
|
```
|
|
107
|
-
|
|
176
|
+
7. **Fix any test failures** before proceeding
|
|
108
177
|
|
|
109
178
|
### Step 5: Make Atomic Commit
|
|
110
179
|
|
|
@@ -300,9 +369,15 @@ Is it marked "Features to Avoid"?
|
|
|
300
369
|
↓
|
|
301
370
|
Category D (Background)?
|
|
302
371
|
├─ YES → Assess carefully, may skip
|
|
303
|
-
└─ NO →
|
|
372
|
+
└─ NO → Continue
|
|
304
373
|
↓
|
|
305
|
-
|
|
374
|
+
Does it have dependencies on other features?
|
|
375
|
+
├─ YES → Are dependencies complete?
|
|
376
|
+
│ ├─ NO → SKIP, note dependency
|
|
377
|
+
│ └─ YES → Continue
|
|
378
|
+
└─ NO → Implement (Categories A-C safe)
|
|
379
|
+
↓
|
|
380
|
+
Implement the feature
|
|
306
381
|
↓
|
|
307
382
|
Run tests
|
|
308
383
|
↓
|
|
@@ -324,11 +399,15 @@ Is it marked "Features to Avoid"?
|
|
|
324
399
|
## Time Budgets
|
|
325
400
|
|
|
326
401
|
**Per Feature:**
|
|
327
|
-
- Category A (Schema): Max
|
|
328
|
-
- Category B (Reporting): Max
|
|
329
|
-
- Category C (CLI): Max 30 minutes
|
|
330
|
-
- Category D (Background): Max
|
|
331
|
-
- Category E (External): Max
|
|
402
|
+
- Category A (Schema): Max 15 minutes — skip if stuck after 15
|
|
403
|
+
- Category B (Reporting): Max 20 minutes — skip if stuck after 20
|
|
404
|
+
- Category C (CLI): Max 30 minutes — skip if stuck after 30
|
|
405
|
+
- Category D (Background): Max 45 minutes (or skip at first sign of daemon complexity)
|
|
406
|
+
- Category E (External): Max 30 minutes (or skip at first sign of dependency issues)
|
|
407
|
+
|
|
408
|
+
**Per Debug Cycle:**
|
|
409
|
+
- Test failure fix: Max 15 minutes — if you can't fix it in 15 minutes, revert and skip
|
|
410
|
+
- Understanding code: Max 10 minutes — if unclear after 10 minutes, skip and report
|
|
332
411
|
|
|
333
412
|
**Session Total:** Max 2 hours
|
|
334
413
|
|
|
@@ -337,26 +416,35 @@ If time budget exceeded: SKIP remaining features and report.
|
|
|
337
416
|
## Testing Strategy
|
|
338
417
|
|
|
339
418
|
### Test Frequency
|
|
340
|
-
- After
|
|
341
|
-
- After
|
|
342
|
-
- After
|
|
343
|
-
- Before commit: Full test suite
|
|
419
|
+
- After each file edit: Run the relevant spec file
|
|
420
|
+
- After schema changes: Run `spec/claude_memory/store/`
|
|
421
|
+
- After new command: Run `spec/claude_memory/commands/`
|
|
422
|
+
- Before each commit: Full test suite
|
|
423
|
+
- If >5 files changed: Full test suite immediately
|
|
344
424
|
|
|
345
425
|
### Test Commands
|
|
346
426
|
```bash
|
|
347
|
-
#
|
|
348
|
-
bundle exec rspec spec/claude_memory/commands/
|
|
427
|
+
# Single relevant spec (fastest feedback)
|
|
428
|
+
bundle exec rspec spec/claude_memory/commands/metrics_command_spec.rb
|
|
349
429
|
|
|
350
|
-
#
|
|
430
|
+
# Module-level specs
|
|
431
|
+
bundle exec rspec spec/claude_memory/commands/
|
|
351
432
|
bundle exec rspec spec/claude_memory/store/
|
|
352
433
|
|
|
353
|
-
# Full suite
|
|
434
|
+
# Full suite (before commit)
|
|
354
435
|
bundle exec rspec
|
|
355
436
|
|
|
356
|
-
# With linting
|
|
437
|
+
# With linting (final check)
|
|
357
438
|
bundle exec rake
|
|
358
439
|
```
|
|
359
440
|
|
|
441
|
+
### Test Failure Response
|
|
442
|
+
1. Read error message carefully
|
|
443
|
+
2. Check if your change caused it (vs pre-existing)
|
|
444
|
+
3. If your change: fix within 15 minutes or revert and skip
|
|
445
|
+
4. If pre-existing: note and continue
|
|
446
|
+
5. If unsure: revert change and skip item
|
|
447
|
+
|
|
360
448
|
### New Feature Tests
|
|
361
449
|
|
|
362
450
|
Always add tests for new features:
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Distill Transcripts
|
|
2
|
+
|
|
3
|
+
Extract structured knowledge (facts, entities, decisions) from undistilled transcript content and persist it to long-term memory.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/distill-transcripts
|
|
9
|
+
/distill-transcripts --limit 10
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
|
|
14
|
+
You are a knowledge extraction specialist. Your job is to read raw transcript content and extract structured facts, entities, and decisions, then persist them via the memory.store_extraction MCP tool.
|
|
15
|
+
|
|
16
|
+
### Step 1: Get Undistilled Content
|
|
17
|
+
|
|
18
|
+
Call `memory.undistilled` with `limit: 10` to get transcript content that hasn't been processed yet.
|
|
19
|
+
|
|
20
|
+
If no items are returned, report "No undistilled content found" and stop.
|
|
21
|
+
|
|
22
|
+
### Step 2: Extract Knowledge (per item)
|
|
23
|
+
|
|
24
|
+
For each content item, carefully read the raw_text and extract:
|
|
25
|
+
|
|
26
|
+
**Entities** — Named things mentioned:
|
|
27
|
+
- type: database, framework, language, platform, repo, module, person, service
|
|
28
|
+
- name: Canonical name (e.g., "PostgreSQL" not "postgres")
|
|
29
|
+
- confidence: 0.0-1.0
|
|
30
|
+
|
|
31
|
+
**Facts** — Knowledge learned:
|
|
32
|
+
- subject: Entity name or "repo" for project-level facts
|
|
33
|
+
- predicate: uses_database, uses_framework, convention, decision, auth_method, deployment_platform, depends_on, testing_strategy
|
|
34
|
+
- object: The value
|
|
35
|
+
- confidence: 0.0-1.0
|
|
36
|
+
- quote: Source excerpt (max 200 chars)
|
|
37
|
+
- strength: "stated" (explicitly said) or "inferred" (implied)
|
|
38
|
+
- scope_hint: "project" (this project only) or "global" (all projects)
|
|
39
|
+
|
|
40
|
+
**Decisions** — Choices made:
|
|
41
|
+
- title: Short summary (max 100 chars)
|
|
42
|
+
- summary: Full description
|
|
43
|
+
- status_hint: "accepted", "proposed", or "rejected"
|
|
44
|
+
|
|
45
|
+
### What to Extract
|
|
46
|
+
|
|
47
|
+
- Technology choices ("we use PostgreSQL", "switched to React")
|
|
48
|
+
- Conventions ("always use frozen_string_literal", "test files go in spec/")
|
|
49
|
+
- Architectural decisions ("API uses REST", "auth via JWT")
|
|
50
|
+
- Preferences ("prefer 4-space indent", "use Standard Ruby")
|
|
51
|
+
- Project structure ("migrations in db/migrations/", "commands in commands/")
|
|
52
|
+
|
|
53
|
+
### What to Skip
|
|
54
|
+
|
|
55
|
+
- Debugging steps and transient errors
|
|
56
|
+
- Code output and tool observations
|
|
57
|
+
- File contents that were just being read
|
|
58
|
+
- Ephemeral task details ("fix this test", "run the linter")
|
|
59
|
+
- Information already obvious from the codebase itself
|
|
60
|
+
|
|
61
|
+
### Scope Detection
|
|
62
|
+
|
|
63
|
+
Set scope_hint to "global" when the text contains signals like:
|
|
64
|
+
- "I always...", "in all my projects...", "my preference is..."
|
|
65
|
+
- "everywhere", "across all repos"
|
|
66
|
+
|
|
67
|
+
Default to "project" for everything else.
|
|
68
|
+
|
|
69
|
+
### Step 3: Persist Each Extraction
|
|
70
|
+
|
|
71
|
+
For each content item with extracted knowledge:
|
|
72
|
+
|
|
73
|
+
1. Call `memory.store_extraction` with the entities, facts, and decisions arrays
|
|
74
|
+
2. Call `memory.mark_distilled` with the content_item_id and facts_extracted count
|
|
75
|
+
3. If nothing was extracted, still call `memory.mark_distilled` with facts_extracted: 0
|
|
76
|
+
|
|
77
|
+
### Step 4: Report
|
|
78
|
+
|
|
79
|
+
Return a summary:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
## Distillation Complete
|
|
83
|
+
|
|
84
|
+
- Items processed: N
|
|
85
|
+
- Facts extracted: N
|
|
86
|
+
- Entities found: N
|
|
87
|
+
- Decisions captured: N
|
|
88
|
+
- Items skipped (nothing to extract): N
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Guidelines
|
|
92
|
+
|
|
93
|
+
- Process items one at a time to keep extractions focused
|
|
94
|
+
- Use `compact: true` on `memory.undistilled` for smaller responses
|
|
95
|
+
- Be conservative — only extract facts you're confident about (>0.7)
|
|
96
|
+
- Prefer "stated" strength over "inferred" unless clearly implied
|
|
97
|
+
- Do NOT fabricate facts — only extract what's actually in the text
|
|
98
|
+
- If text is mostly code/tool output with no conversational knowledge, mark as distilled with 0 facts
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Memory Recall Agent
|
|
2
|
+
|
|
3
|
+
Search long-term memory for facts, decisions, conventions, and architectural knowledge. Chains multiple memory tools to build comprehensive answers while saving main-agent context.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Provide a natural language query describing what you want to recall:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
/memory-recall database migration strategy
|
|
11
|
+
/memory-recall authentication decisions
|
|
12
|
+
/memory-recall testing conventions
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
1. **Fast lookup** — Start with `memory.recall` for keyword matches
|
|
18
|
+
2. **Semantic search** — If recall returns few results, try `memory.recall_semantic` for conceptual matches
|
|
19
|
+
3. **Shortcuts** — For known categories, use `memory.decisions`, `memory.conventions`, or `memory.architecture`
|
|
20
|
+
4. **Deep dive** — For specific facts, use `memory.explain` to get provenance and `memory.fact_graph` to see relationships
|
|
21
|
+
5. **Synthesize** — Combine findings into a concise, structured answer
|
|
22
|
+
|
|
23
|
+
## Instructions
|
|
24
|
+
|
|
25
|
+
You are a memory recall specialist. Given a query, search ClaudeMemory using the available MCP tools and return a synthesized answer.
|
|
26
|
+
|
|
27
|
+
### Step 1: Initial Search
|
|
28
|
+
|
|
29
|
+
Run `memory.recall` with the user's query. If the query mentions decisions, conventions, or architecture, also run the appropriate shortcut tool in parallel.
|
|
30
|
+
|
|
31
|
+
### Step 2: Expand if Needed
|
|
32
|
+
|
|
33
|
+
If Step 1 returns fewer than 3 results:
|
|
34
|
+
- Try `memory.recall_semantic` with a rephrased version of the query
|
|
35
|
+
- Try `memory.search_concepts` with 2-3 key concepts extracted from the query
|
|
36
|
+
|
|
37
|
+
### Step 3: Enrich Key Facts
|
|
38
|
+
|
|
39
|
+
For the top 2-3 most relevant facts:
|
|
40
|
+
- Run `memory.explain` to get provenance (where the fact came from)
|
|
41
|
+
- If relationships matter, run `memory.fact_graph` to see connected facts
|
|
42
|
+
|
|
43
|
+
### Step 4: Synthesize
|
|
44
|
+
|
|
45
|
+
Return a structured response:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
## Memory Recall Results
|
|
49
|
+
|
|
50
|
+
### Key Facts
|
|
51
|
+
- [Fact 1 with provenance]
|
|
52
|
+
- [Fact 2 with provenance]
|
|
53
|
+
|
|
54
|
+
### Context
|
|
55
|
+
[How these facts relate to the query]
|
|
56
|
+
|
|
57
|
+
### Confidence
|
|
58
|
+
[High/Medium/Low based on number and freshness of supporting facts]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Guidelines
|
|
62
|
+
|
|
63
|
+
- Prefer `memory.recall` (fast, token-efficient) before escalating to semantic search
|
|
64
|
+
- Use `compact: true` on all tool calls to minimize token usage
|
|
65
|
+
- Do NOT fabricate facts — only report what memory tools return
|
|
66
|
+
- If no relevant facts found, say so clearly rather than guessing
|
|
67
|
+
- Include fact IDs so the main agent can reference them
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"plugins": [
|
|
8
8
|
{
|
|
9
9
|
"name": "claude-memory",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.8.0",
|
|
11
11
|
"source": "./",
|
|
12
12
|
"description": "Long-term self-managed memory for Claude Code with fact extraction, truth maintenance, and provenance tracking",
|
|
13
13
|
"repository": "https://github.com/codenamev/claude_memory"
|
data/.claude-plugin/plugin.json
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,54 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.8.0] - 2026-03-30
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
**Three-Layer Distillation Pipeline**
|
|
12
|
+
- Automatic distillation via NullDistiller in ingest pipeline (Layer 1: regex-based, P95 < 5ms)
|
|
13
|
+
- Context hook injection for LLM-based extraction at SessionStart (Layer 2: Claude Code as distiller, zero extra cost)
|
|
14
|
+
- `/distill-transcripts` skill for manual deep extraction (Layer 3: on-demand, depth-aware prompts)
|
|
15
|
+
- `memory.undistilled` and `memory.mark_distilled` MCP tools for distillation tracking
|
|
16
|
+
- `Hook::DistillationRunner` extracted from Handler for context hook injection
|
|
17
|
+
- `TaskCompleted` and `TeammateIdle` hook events for ingest triggers
|
|
18
|
+
- Distillation metrics backfill on database initialization
|
|
19
|
+
- Doctor check for undistilled content
|
|
20
|
+
- Pending distillation count in `memory.status` output
|
|
21
|
+
|
|
22
|
+
**Recall Enhancements**
|
|
23
|
+
- Intent parameter for recall query disambiguation (#3)
|
|
24
|
+
- Retrieval score traces for semantic search (#5)
|
|
25
|
+
- Configurable embedding providers with dimension checking
|
|
26
|
+
|
|
27
|
+
**Hook Enhancements**
|
|
28
|
+
- `statusMessage` on all hooks for descriptive spinner text during hook execution
|
|
29
|
+
- `StopFailure` hook to capture transcript data even on session errors (rate limits, server errors)
|
|
30
|
+
- `Notification` hook with `idle_prompt` matcher for opportunistic sweep during idle
|
|
31
|
+
|
|
32
|
+
**New Commands & Skills**
|
|
33
|
+
- `install-skill` command and `memory-recall` agent (#8, #12)
|
|
34
|
+
- Shell completion command for bash and zsh (#18)
|
|
35
|
+
|
|
36
|
+
**Distillation Benchmark Results**
|
|
37
|
+
- NullDistiller: Concept Recall 0.952, Fact Precision/Recall 1.000 (31 test cases)
|
|
38
|
+
- Claude Code LLM: Concept Recall 0.902 (all 41 cases), 0.900 on semantic cases (vs 0.333 for regex)
|
|
39
|
+
- Average 1.6 facts stored per case across LLM extraction
|
|
40
|
+
- E2E distillation recall benchmark and extraction quality benchmarks
|
|
41
|
+
- Concept-based matching for distiller-agnostic benchmark comparison
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- `--allowedTools` added to `ClaudeCliRunner` for MCP tool permissions
|
|
46
|
+
- Test isolation for context hook when global database has facts
|
|
47
|
+
|
|
48
|
+
### Internal
|
|
49
|
+
- Extracted `RetryHandler` and `SchemaManager` modules from `SQLiteStore`
|
|
50
|
+
- Extracted `Recall` into engine strategy pattern with `DualEngine`, `LegacyEngine`, and shared `QueryCore`
|
|
51
|
+
- Extracted `Tools` god object into 6 handler modules
|
|
52
|
+
- Added 36 specs for 5 previously untested files
|
|
53
|
+
- All 3 god objects eliminated, 0 files over 500 lines
|
|
54
|
+
|
|
7
55
|
## [0.7.1] - 2026-03-17
|
|
8
56
|
|
|
9
57
|
### Added
|
|
@@ -45,7 +93,7 @@ All notable changes to this project will be documented in this file.
|
|
|
45
93
|
- Opt-out: set `CLAUDE_MEMORY_ISOLATE_WORKTREES=1` for per-worktree isolation
|
|
46
94
|
|
|
47
95
|
**MCP Enhancements**
|
|
48
|
-
- Tool annotations: `readOnlyHint`, `idempotentHint`, `destructiveHint` on all
|
|
96
|
+
- Tool annotations: `readOnlyHint`, `idempotentHint`, `destructiveHint` on all 23 tools
|
|
49
97
|
- Stdout protection: MCP server redirects `$stdout` to `$stderr` to prevent protocol corruption from accidental `puts`/`print` calls
|
|
50
98
|
- Self-excluding agent conversations via `SELF_CONTEXT_MARKER` to prevent meta-pollution
|
|
51
99
|
|
data/CLAUDE.md
CHANGED
|
@@ -99,6 +99,18 @@ bin/run-evals --comparative # Run benchmarks with available tools
|
|
|
99
99
|
bin/run-evals --comparative --setup-competitors # Install + run in one step
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
### Distillation Extraction Accuracy
|
|
103
|
+
|
|
104
|
+
NullDistiller (regex, Layer 1):
|
|
105
|
+
- Concept Recall: 0.952 (regex-detectable entities/facts)
|
|
106
|
+
- Fact Precision: 1.000, Fact Recall: 1.000 (on 31 test cases)
|
|
107
|
+
- Pipeline latency: P95 < 5ms (medium text)
|
|
108
|
+
|
|
109
|
+
Claude Code (LLM, Layers 2+3):
|
|
110
|
+
- Concept Recall: 0.902 (all 41 cases)
|
|
111
|
+
- Concept Recall on semantic cases: 0.900 (vs NullDistiller's 0.333)
|
|
112
|
+
- Avg facts stored per case: 1.6
|
|
113
|
+
|
|
102
114
|
## Architecture
|
|
103
115
|
|
|
104
116
|
### Dual-Database System
|
|
@@ -123,6 +135,16 @@ Transcripts → Ingest → Index (FTS5)
|
|
|
123
135
|
Publish → .claude/rules/claude_memory.generated.md
|
|
124
136
|
```
|
|
125
137
|
|
|
138
|
+
### Three-Layer Distillation
|
|
139
|
+
|
|
140
|
+
The distillation pipeline operates at three levels of depth:
|
|
141
|
+
|
|
142
|
+
- **Layer 1: NullDistiller** (automatic, regex, free) — Runs in the ingest pipeline on every hook event. Extracts entities, facts, and scope hints using pattern matching. P95 latency < 5ms.
|
|
143
|
+
- **Layer 2: Context Hook Injection** (automatic, LLM, zero extra cost) — At SessionStart, undistilled content is injected into the session via `hookSpecificOutput.additionalContext` with extraction instructions. Claude Code itself acts as the distiller, extracting structured facts at no additional API cost.
|
|
144
|
+
- **Layer 3: `/distill-transcripts` Skill** (manual, on-demand) — Deep extraction triggered by the user. Processes undistilled content with depth-aware prompts (initial extraction, consolidation, contradiction resolution).
|
|
145
|
+
|
|
146
|
+
New MCP tools `memory.undistilled` and `memory.mark_distilled` support the pipeline by tracking which content items have been deeply distilled.
|
|
147
|
+
|
|
126
148
|
### Module Structure
|
|
127
149
|
|
|
128
150
|
#### Application Layer
|
|
@@ -135,7 +157,7 @@ Transcripts → Ingest → Index (FTS5)
|
|
|
135
157
|
- Each command is a separate class (HelpCommand, DoctorCommand, etc.)
|
|
136
158
|
- All commands inherit from BaseCommand
|
|
137
159
|
- Dependency injection for I/O (stdout, stderr, stdin)
|
|
138
|
-
-
|
|
160
|
+
- 23 commands total, each focused on single responsibility
|
|
139
161
|
|
|
140
162
|
- **`Configuration`**: Centralized ENV access (`configuration.rb`)
|
|
141
163
|
- Single source of truth for paths and environment variables
|
|
@@ -198,12 +220,13 @@ Transcripts → Ingest → Index (FTS5)
|
|
|
198
220
|
- Modes: shared (repo), local (uncommitted), home (user directory)
|
|
199
221
|
|
|
200
222
|
- **`MCP`**: Model Context Protocol server and tools (`mcp/`)
|
|
201
|
-
- Exposes memory tools to Claude Code (
|
|
223
|
+
- Exposes memory tools to Claude Code (23 tools total)
|
|
202
224
|
- Dual content/structuredContent responses with compact mode
|
|
203
225
|
|
|
204
226
|
- **`Hook`**: Hook entrypoint handlers (`hook/`)
|
|
205
227
|
- Reads stdin JSON from Claude Code hooks
|
|
206
228
|
- Routes to ingest/sweep/publish commands
|
|
229
|
+
- `DistillationRunner`: Manages context hook injection with undistilled content for LLM extraction
|
|
207
230
|
|
|
208
231
|
### Database Schema
|
|
209
232
|
|
|
@@ -288,7 +311,7 @@ Single-value predicates (like "uses_database") supersede old values. Multi-value
|
|
|
288
311
|
|
|
289
312
|
- `lib/claude_memory.rb`: Main module, requires, database path helpers
|
|
290
313
|
- `lib/claude_memory/cli.rb`: Thin command router (41 lines)
|
|
291
|
-
- `lib/claude_memory/commands/`: Individual command classes (
|
|
314
|
+
- `lib/claude_memory/commands/`: Individual command classes (23 commands)
|
|
292
315
|
- `lib/claude_memory/configuration.rb`: Centralized configuration and ENV access
|
|
293
316
|
- `lib/claude_memory/domain/`: Domain models (Fact, Entity, Provenance, Conflict)
|
|
294
317
|
- `lib/claude_memory/core/`: Value objects and null objects
|
|
@@ -303,12 +326,13 @@ Single-value predicates (like "uses_database") supersede old values. Multi-value
|
|
|
303
326
|
|
|
304
327
|
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.
|
|
305
328
|
|
|
306
|
-
Available MCP tools (
|
|
329
|
+
Available MCP tools (23 total):
|
|
307
330
|
- **Query & Recall**: `memory.recall`, `memory.recall_index`, `memory.recall_details`, `memory.recall_semantic`, `memory.search_concepts`
|
|
308
331
|
- **Provenance**: `memory.explain`, `memory.fact_graph`
|
|
309
332
|
- **Shortcuts**: `memory.decisions`, `memory.conventions`, `memory.architecture`
|
|
310
333
|
- **Context**: `memory.facts_by_tool`, `memory.facts_by_context`
|
|
311
334
|
- **Management**: `memory.promote`, `memory.store_extraction`
|
|
335
|
+
- **Distillation**: `memory.undistilled`, `memory.mark_distilled`
|
|
312
336
|
- **Monitoring**: `memory.status`, `memory.stats`, `memory.changes`, `memory.conflicts`
|
|
313
337
|
- **Maintenance**: `memory.sweep_now`
|
|
314
338
|
- **Discovery**: `memory.check_setup`, `memory.list_projects`
|
|
@@ -317,7 +341,7 @@ Available MCP tools (21 total):
|
|
|
317
341
|
|
|
318
342
|
ClaudeMemory integrates with Claude Code via hooks in `.claude/settings.json`:
|
|
319
343
|
|
|
320
|
-
- **Ingest hook**: Triggers on Stop/SessionStart/PreCompact/SessionEnd events
|
|
344
|
+
- **Ingest hook**: Triggers on Stop/SessionStart/PreCompact/SessionEnd/TaskCompleted/TeammateIdle events
|
|
321
345
|
- Calls `claude-memory hook ingest` with stdin JSON
|
|
322
346
|
- Reads transcript delta and updates both global and project databases
|
|
323
347
|
|