memor-cli 0.1.0__tar.gz
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.
- memor_cli-0.1.0/LICENSE +21 -0
- memor_cli-0.1.0/PKG-INFO +273 -0
- memor_cli-0.1.0/README.md +236 -0
- memor_cli-0.1.0/memor/__init__.py +0 -0
- memor_cli-0.1.0/memor/cli.py +463 -0
- memor_cli-0.1.0/memor/daemon.py +294 -0
- memor_cli-0.1.0/memor/dashboard/__init__.py +0 -0
- memor_cli-0.1.0/memor/dashboard/server.py +153 -0
- memor_cli-0.1.0/memor/dashboard/static/index.html +688 -0
- memor_cli-0.1.0/memor/distill/__init__.py +0 -0
- memor_cli-0.1.0/memor/distill/distiller.py +112 -0
- memor_cli-0.1.0/memor/distill/extractive.py +161 -0
- memor_cli-0.1.0/memor/embed/__init__.py +0 -0
- memor_cli-0.1.0/memor/embed/api.py +15 -0
- memor_cli-0.1.0/memor/embed/fake.py +16 -0
- memor_cli-0.1.0/memor/embed/local.py +16 -0
- memor_cli-0.1.0/memor/eval/__init__.py +0 -0
- memor_cli-0.1.0/memor/eval/baselines/__init__.py +5 -0
- memor_cli-0.1.0/memor/eval/baselines/base.py +15 -0
- memor_cli-0.1.0/memor/eval/baselines/claude_mem.py +19 -0
- memor_cli-0.1.0/memor/eval/baselines/graphiti.py +25 -0
- memor_cli-0.1.0/memor/eval/dataset.py +48 -0
- memor_cli-0.1.0/memor/eval/embed_benchmark.py +67 -0
- memor_cli-0.1.0/memor/eval/judge.py +137 -0
- memor_cli-0.1.0/memor/eval/metrics.py +13 -0
- memor_cli-0.1.0/memor/eval/runner.py +78 -0
- memor_cli-0.1.0/memor/feedback.py +96 -0
- memor_cli-0.1.0/memor/hook_server.py +144 -0
- memor_cli-0.1.0/memor/ingest/__init__.py +0 -0
- memor_cli-0.1.0/memor/ingest/claude_code.py +135 -0
- memor_cli-0.1.0/memor/ingest/documents.py +28 -0
- memor_cli-0.1.0/memor/interfaces.py +20 -0
- memor_cli-0.1.0/memor/llm/__init__.py +0 -0
- memor_cli-0.1.0/memor/llm/anthropic.py +14 -0
- memor_cli-0.1.0/memor/llm/base.py +7 -0
- memor_cli-0.1.0/memor/llm/openai_compat.py +20 -0
- memor_cli-0.1.0/memor/project.py +69 -0
- memor_cli-0.1.0/memor/recall.py +115 -0
- memor_cli-0.1.0/memor/redact.py +129 -0
- memor_cli-0.1.0/memor/retrieve/__init__.py +0 -0
- memor_cli-0.1.0/memor/retrieve/retriever.py +78 -0
- memor_cli-0.1.0/memor/store/__init__.py +0 -0
- memor_cli-0.1.0/memor/store/sqlite_store.py +336 -0
- memor_cli-0.1.0/memor/tokencount.py +9 -0
- memor_cli-0.1.0/memor/types.py +45 -0
- memor_cli-0.1.0/memor_cli.egg-info/PKG-INFO +273 -0
- memor_cli-0.1.0/memor_cli.egg-info/SOURCES.txt +82 -0
- memor_cli-0.1.0/memor_cli.egg-info/dependency_links.txt +1 -0
- memor_cli-0.1.0/memor_cli.egg-info/entry_points.txt +2 -0
- memor_cli-0.1.0/memor_cli.egg-info/requires.txt +18 -0
- memor_cli-0.1.0/memor_cli.egg-info/top_level.txt +1 -0
- memor_cli-0.1.0/pyproject.toml +58 -0
- memor_cli-0.1.0/setup.cfg +4 -0
- memor_cli-0.1.0/tests/test_cli_smoke.py +13 -0
- memor_cli-0.1.0/tests/test_daemon.py +265 -0
- memor_cli-0.1.0/tests/test_dashboard.py +138 -0
- memor_cli-0.1.0/tests/test_dataset_builder.py +19 -0
- memor_cli-0.1.0/tests/test_dimension_safety.py +37 -0
- memor_cli-0.1.0/tests/test_distiller.py +42 -0
- memor_cli-0.1.0/tests/test_embed.py +10 -0
- memor_cli-0.1.0/tests/test_embed_benchmark.py +52 -0
- memor_cli-0.1.0/tests/test_eval_ablation.py +26 -0
- memor_cli-0.1.0/tests/test_eval_runner.py +20 -0
- memor_cli-0.1.0/tests/test_external_baselines.py +15 -0
- memor_cli-0.1.0/tests/test_extractive.py +126 -0
- memor_cli-0.1.0/tests/test_feedback.py +120 -0
- memor_cli-0.1.0/tests/test_hook.py +40 -0
- memor_cli-0.1.0/tests/test_hook_server.py +42 -0
- memor_cli-0.1.0/tests/test_ingest_claude_code.py +12 -0
- memor_cli-0.1.0/tests/test_ingest_documents.py +10 -0
- memor_cli-0.1.0/tests/test_install_hook.py +72 -0
- memor_cli-0.1.0/tests/test_interfaces.py +12 -0
- memor_cli-0.1.0/tests/test_judge.py +77 -0
- memor_cli-0.1.0/tests/test_metrics.py +11 -0
- memor_cli-0.1.0/tests/test_noise_filter.py +71 -0
- memor_cli-0.1.0/tests/test_project_resolver.py +43 -0
- memor_cli-0.1.0/tests/test_recall_core.py +94 -0
- memor_cli-0.1.0/tests/test_redact.py +211 -0
- memor_cli-0.1.0/tests/test_retriever.py +33 -0
- memor_cli-0.1.0/tests/test_skill_recall.py +38 -0
- memor_cli-0.1.0/tests/test_store.py +34 -0
- memor_cli-0.1.0/tests/test_supersession.py +105 -0
- memor_cli-0.1.0/tests/test_tokencount.py +21 -0
- memor_cli-0.1.0/tests/test_types.py +11 -0
memor_cli-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nimit Bhandari
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
memor_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memor-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Measured memory for coding agents. Fire and forget — no API keys needed.
|
|
5
|
+
Author-email: Nimit Bhandari <nimitbhandari17@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bnimit/memor-ai
|
|
8
|
+
Project-URL: Repository, https://github.com/bnimit/memor-ai
|
|
9
|
+
Project-URL: Issues, https://github.com/bnimit/memor-ai/issues
|
|
10
|
+
Keywords: memory,agent,claude,embeddings,coding-assistant
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: sqlite-vec>=0.1.6
|
|
22
|
+
Requires-Dist: numpy>=1.26
|
|
23
|
+
Requires-Dist: typer>=0.12
|
|
24
|
+
Requires-Dist: httpx>=0.27
|
|
25
|
+
Requires-Dist: tiktoken>=0.7
|
|
26
|
+
Requires-Dist: fastapi>=0.111
|
|
27
|
+
Requires-Dist: uvicorn>=0.30
|
|
28
|
+
Requires-Dist: model2vec>=0.8
|
|
29
|
+
Provides-Extra: api-embed
|
|
30
|
+
Requires-Dist: openai>=1.0; extra == "api-embed"
|
|
31
|
+
Provides-Extra: anthropic
|
|
32
|
+
Requires-Dist: anthropic>=0.40; extra == "anthropic"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
_
|
|
40
|
+
_ __ ___ ___ _ __ ___ ___ _ __ __ _(_)
|
|
41
|
+
| '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__|____ / _` | |
|
|
42
|
+
| | | | | | __/ | | | | | (_) | | |_____| (_| | |
|
|
43
|
+
|_| |_| |_|\___|_| |_| |_|\___/|_| \__,_|_|
|
|
44
|
+
|
|
45
|
+
Measured memory for coding agents.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
[]()
|
|
50
|
+
[]()
|
|
51
|
+
[](https://pypi.org/project/memor-cli/)
|
|
52
|
+
|
|
53
|
+
**Automatic background memory for Claude Code.** Fire and forget — no API keys needed.
|
|
54
|
+
|
|
55
|
+
Memor watches your coding sessions, extracts decisions and patterns, and recalls relevant context on every prompt. Zero configuration. One install. Your agent remembers everything.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Install globally (recommended)
|
|
63
|
+
pipx install memor-cli
|
|
64
|
+
|
|
65
|
+
# Install the Claude Code hook + download embedding model (~60MB)
|
|
66
|
+
memor install-hook
|
|
67
|
+
|
|
68
|
+
# Start the background daemon
|
|
69
|
+
memor daemon
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
That's it. Every Claude Code prompt now gets automatic context recall. Open the dashboard to see it working:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
memor dashboard
|
|
76
|
+
# Opens http://localhost:8420
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> **Alternative install:** `pip install memor-cli` works too — just make sure `~/.local/bin` is on your PATH so the `memor` command is available.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## How It Works
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
You type a prompt in Claude Code
|
|
87
|
+
|
|
|
88
|
+
v
|
|
89
|
+
Hook fires (UserPromptSubmit)
|
|
90
|
+
|
|
|
91
|
+
v
|
|
92
|
+
Embed query locally (model2vec, ~2ms)
|
|
93
|
+
|
|
|
94
|
+
v
|
|
95
|
+
Hybrid scoring: similarity + recency + kind weight + quality
|
|
96
|
+
|
|
|
97
|
+
v
|
|
98
|
+
Inject relevant context into prompt
|
|
99
|
+
|
|
|
100
|
+
v
|
|
101
|
+
Claude sees your past decisions, bugfixes,
|
|
102
|
+
architecture choices — without you re-explaining
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Two background processes:**
|
|
106
|
+
|
|
107
|
+
1. **Daemon** — polls `~/.claude/projects/` for transcripts, embeds chunks, runs distillation, analyzes feedback, compacts duplicates. All local.
|
|
108
|
+
2. **Hook** — fires on every prompt, recalls relevant memories, injects them as context. Sub-15ms.
|
|
109
|
+
|
|
110
|
+
**No API keys required.** Embeddings run locally via [model2vec](https://github.com/MinishLab/model2vec) (potion-base-8M, 256-dim). Vectors stored in [sqlite-vec](https://github.com/asg017/sqlite-vec). Everything runs on your machine.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Hybrid Scoring
|
|
115
|
+
|
|
116
|
+
Memor doesn't just match keywords. Each memory is scored by four signals:
|
|
117
|
+
|
|
118
|
+
| Signal | Weight | How it works |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| **Semantic similarity** | 50% | Vector cosine distance between query and memory |
|
|
121
|
+
| **Recency** | 25% | Exponential decay with 14-day half-life — recent decisions rank higher |
|
|
122
|
+
| **Kind weight** | 15% | Distilled memories (1.3x) rank above raw session chunks (1.0x) |
|
|
123
|
+
| **Quality** | 10% | Bayesian score from implicit feedback — memories the agent actually uses rank higher |
|
|
124
|
+
|
|
125
|
+
This means a relevant decision from yesterday beats a vaguely-related chunk from a month ago — even if the raw embedding similarity is similar.
|
|
126
|
+
|
|
127
|
+
### Feedback Loop
|
|
128
|
+
|
|
129
|
+
Memor tracks whether recalled memories actually get used by the agent. After each session, the daemon analyzes the transcript to detect if recalled content appeared in the agent's responses. Memories that consistently prove useful get quality boosts; memories never recalled in 30+ days get automatically deactivated. Near-duplicate memories are compacted into one.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## What Gets Stored
|
|
134
|
+
|
|
135
|
+
| Kind | Source | Description |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| `session_chunk` | Daemon auto-ingest | Filtered turns from Claude Code transcripts |
|
|
138
|
+
| `memory` | Extractive distillation | Key decisions, patterns, bugfixes per session |
|
|
139
|
+
|
|
140
|
+
Memories are automatically classified as `decision`, `bugfix`, `lesson`, `snippet`, or generic `extract` based on content patterns. The daemon runs a signal filter that keeps decisions, bugfixes, lessons, and code rationale while skipping noise (tool calls, file listings, boilerplate).
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Dashboard
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
memor dashboard
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Shows:
|
|
151
|
+
- **Memory bank** — session chunks, distilled memories, projects tracked
|
|
152
|
+
- **Context efficiency** — overhead %, recall precision, quality scores per session
|
|
153
|
+
- **Per-project breakdown** — which projects have the most context
|
|
154
|
+
- **Recent recalls** — every hook event with scores, latency, and status
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Commands
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
memor help Print the full manual
|
|
162
|
+
memor install-hook Install Claude Code hook + download model
|
|
163
|
+
memor daemon Auto-ingest + distill (background watcher)
|
|
164
|
+
memor dashboard Web dashboard on localhost:8420
|
|
165
|
+
memor query <text> Search memories from the CLI
|
|
166
|
+
memor reingest Wipe DB and re-ingest everything
|
|
167
|
+
memor reingest --project <name> Re-ingest only one project
|
|
168
|
+
memor forget-stale Deactivate memories unused for 30+ days
|
|
169
|
+
memor scan Audit DB for leaked secrets
|
|
170
|
+
memor scan --purge Redact secrets in place
|
|
171
|
+
memor setup-model Download/retry the embedding model
|
|
172
|
+
memor ingest-cc <file> Ingest a single transcript
|
|
173
|
+
memor ingest-project <dir> Bulk ingest a project directory
|
|
174
|
+
memor ingest-doc <file> Ingest a markdown document
|
|
175
|
+
memor distill --project <name> Run distillation manually
|
|
176
|
+
memor eval <cases.json> Run eval suite
|
|
177
|
+
memor bench-embed --project <name> Compare embedding models
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Architecture
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
memor/
|
|
186
|
+
+-- types.py Core dataclasses: Artifact, Scope, Hit, RetrievalTrace
|
|
187
|
+
+-- interfaces.py Protocols: Embedder, LLM, MemoryStore
|
|
188
|
+
+-- cli.py Typer CLI entry point
|
|
189
|
+
+-- daemon.py Auto-ingest + auto-distill + compaction watcher
|
|
190
|
+
+-- project.py Git-root project resolver (filesystem-aware)
|
|
191
|
+
+-- recall.py Shared recall core (used by hook + skill)
|
|
192
|
+
+-- redact.py Secret detection and redaction at ingest
|
|
193
|
+
+-- feedback.py Implicit feedback analyzer (usage detection)
|
|
194
|
+
|
|
|
195
|
+
+-- retrieve/
|
|
196
|
+
| +-- retriever.py Hybrid scoring: similarity + recency + kind + quality
|
|
197
|
+
|
|
|
198
|
+
+-- store/
|
|
199
|
+
| +-- sqlite_store.py SQLite + sqlite-vec (WAL mode, dimension safety)
|
|
200
|
+
|
|
|
201
|
+
+-- embed/
|
|
202
|
+
| +-- local.py model2vec (potion-base-8M, 256-dim, ~60MB)
|
|
203
|
+
| +-- api.py OpenAI-compatible embedding API (optional)
|
|
204
|
+
| +-- fake.py Deterministic SHA-256 embedder (tests)
|
|
205
|
+
|
|
|
206
|
+
+-- dashboard/
|
|
207
|
+
| +-- server.py FastAPI dashboard backend
|
|
208
|
+
| +-- static/index.html Self-contained dashboard (no CDN deps)
|
|
209
|
+
|
|
|
210
|
+
+-- distill/
|
|
211
|
+
| +-- extractive.py TF-IDF + clustering + auto-classification
|
|
212
|
+
| +-- distiller.py Extractive + optional LLM abstractive
|
|
213
|
+
|
|
|
214
|
+
+-- eval/
|
|
215
|
+
+-- runner.py 4-baseline eval runner
|
|
216
|
+
+-- judge.py LLM-as-judge evaluation
|
|
217
|
+
+-- embed_benchmark.py Embedding model comparison
|
|
218
|
+
|
|
219
|
+
bin/memor-hook.py Claude Code hook (thin client)
|
|
220
|
+
skill/recall.py Standalone recall script
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Security
|
|
226
|
+
|
|
227
|
+
**Nothing leaves your machine.** In the default configuration:
|
|
228
|
+
|
|
229
|
+
- **No telemetry, no analytics, no phone-home.** Zero outbound network calls.
|
|
230
|
+
- **Embeddings run locally** via model2vec ONNX (one-time model download from HuggingFace — no user data sent).
|
|
231
|
+
- **Hook transport is a Unix socket** (`~/.memor/hook.sock`), not a network port.
|
|
232
|
+
- **Dashboard binds localhost only.**
|
|
233
|
+
|
|
234
|
+
The only optional network paths are the LLM-based abstractive distiller (requires explicitly setting `ANTHROPIC_API_KEY`) and the API embedding backend — both off by default.
|
|
235
|
+
|
|
236
|
+
### Secret redaction
|
|
237
|
+
|
|
238
|
+
Memor automatically redacts secrets **at ingest**, before anything is embedded or stored:
|
|
239
|
+
|
|
240
|
+
- API keys (AWS `AKIA...`, OpenAI `sk-...`, Anthropic `sk-ant-...`, GitHub `ghp_...`, Stripe, Slack)
|
|
241
|
+
- JWTs, PEM private key blocks
|
|
242
|
+
- Connection strings (`postgres://`, `mongodb://`, `redis://`, etc.)
|
|
243
|
+
- `.env`-style assignments (`DB_PASSWORD=...`, `API_KEY=...`)
|
|
244
|
+
- High-entropy tokens (Shannon entropy > 4.0, length > 20)
|
|
245
|
+
|
|
246
|
+
Redacted content is replaced with `[REDACTED]` in place, preserving surrounding context. To audit and clean an existing database: `memor scan` (audit) or `memor scan --purge` (redact in place).
|
|
247
|
+
|
|
248
|
+
### Contradiction handling
|
|
249
|
+
|
|
250
|
+
When a new memory contradicts an older one in the same project (detected via replacement cues like "switched from X to Y", "no longer", "ripped out"), the older memory is automatically deactivated. This prevents stale decisions from being recalled and misleading the agent.
|
|
251
|
+
|
|
252
|
+
### Local storage
|
|
253
|
+
|
|
254
|
+
The memory database (`~/.memor/memor.db`) is stored as plaintext SQLite on disk. For at-rest protection, we recommend enabling OS-level full-disk encryption (FileVault on macOS, LUKS on Linux) which covers all local files with zero performance overhead.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Development
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
git clone https://github.com/bnimit/memor-ai.git
|
|
262
|
+
cd memor-ai
|
|
263
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
264
|
+
pip install -e ".[dev]"
|
|
265
|
+
|
|
266
|
+
pytest # 153 tests
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT. See [LICENSE](LICENSE) for the full text.
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
```
|
|
2
|
+
_
|
|
3
|
+
_ __ ___ ___ _ __ ___ ___ _ __ __ _(_)
|
|
4
|
+
| '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__|____ / _` | |
|
|
5
|
+
| | | | | | __/ | | | | | (_) | | |_____| (_| | |
|
|
6
|
+
|_| |_| |_|\___|_| |_| |_|\___/|_| \__,_|_|
|
|
7
|
+
|
|
8
|
+
Measured memory for coding agents.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[]()
|
|
13
|
+
[]()
|
|
14
|
+
[](https://pypi.org/project/memor-cli/)
|
|
15
|
+
|
|
16
|
+
**Automatic background memory for Claude Code.** Fire and forget — no API keys needed.
|
|
17
|
+
|
|
18
|
+
Memor watches your coding sessions, extracts decisions and patterns, and recalls relevant context on every prompt. Zero configuration. One install. Your agent remembers everything.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Install globally (recommended)
|
|
26
|
+
pipx install memor-cli
|
|
27
|
+
|
|
28
|
+
# Install the Claude Code hook + download embedding model (~60MB)
|
|
29
|
+
memor install-hook
|
|
30
|
+
|
|
31
|
+
# Start the background daemon
|
|
32
|
+
memor daemon
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
That's it. Every Claude Code prompt now gets automatic context recall. Open the dashboard to see it working:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
memor dashboard
|
|
39
|
+
# Opens http://localhost:8420
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
> **Alternative install:** `pip install memor-cli` works too — just make sure `~/.local/bin` is on your PATH so the `memor` command is available.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## How It Works
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
You type a prompt in Claude Code
|
|
50
|
+
|
|
|
51
|
+
v
|
|
52
|
+
Hook fires (UserPromptSubmit)
|
|
53
|
+
|
|
|
54
|
+
v
|
|
55
|
+
Embed query locally (model2vec, ~2ms)
|
|
56
|
+
|
|
|
57
|
+
v
|
|
58
|
+
Hybrid scoring: similarity + recency + kind weight + quality
|
|
59
|
+
|
|
|
60
|
+
v
|
|
61
|
+
Inject relevant context into prompt
|
|
62
|
+
|
|
|
63
|
+
v
|
|
64
|
+
Claude sees your past decisions, bugfixes,
|
|
65
|
+
architecture choices — without you re-explaining
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Two background processes:**
|
|
69
|
+
|
|
70
|
+
1. **Daemon** — polls `~/.claude/projects/` for transcripts, embeds chunks, runs distillation, analyzes feedback, compacts duplicates. All local.
|
|
71
|
+
2. **Hook** — fires on every prompt, recalls relevant memories, injects them as context. Sub-15ms.
|
|
72
|
+
|
|
73
|
+
**No API keys required.** Embeddings run locally via [model2vec](https://github.com/MinishLab/model2vec) (potion-base-8M, 256-dim). Vectors stored in [sqlite-vec](https://github.com/asg017/sqlite-vec). Everything runs on your machine.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Hybrid Scoring
|
|
78
|
+
|
|
79
|
+
Memor doesn't just match keywords. Each memory is scored by four signals:
|
|
80
|
+
|
|
81
|
+
| Signal | Weight | How it works |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| **Semantic similarity** | 50% | Vector cosine distance between query and memory |
|
|
84
|
+
| **Recency** | 25% | Exponential decay with 14-day half-life — recent decisions rank higher |
|
|
85
|
+
| **Kind weight** | 15% | Distilled memories (1.3x) rank above raw session chunks (1.0x) |
|
|
86
|
+
| **Quality** | 10% | Bayesian score from implicit feedback — memories the agent actually uses rank higher |
|
|
87
|
+
|
|
88
|
+
This means a relevant decision from yesterday beats a vaguely-related chunk from a month ago — even if the raw embedding similarity is similar.
|
|
89
|
+
|
|
90
|
+
### Feedback Loop
|
|
91
|
+
|
|
92
|
+
Memor tracks whether recalled memories actually get used by the agent. After each session, the daemon analyzes the transcript to detect if recalled content appeared in the agent's responses. Memories that consistently prove useful get quality boosts; memories never recalled in 30+ days get automatically deactivated. Near-duplicate memories are compacted into one.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## What Gets Stored
|
|
97
|
+
|
|
98
|
+
| Kind | Source | Description |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `session_chunk` | Daemon auto-ingest | Filtered turns from Claude Code transcripts |
|
|
101
|
+
| `memory` | Extractive distillation | Key decisions, patterns, bugfixes per session |
|
|
102
|
+
|
|
103
|
+
Memories are automatically classified as `decision`, `bugfix`, `lesson`, `snippet`, or generic `extract` based on content patterns. The daemon runs a signal filter that keeps decisions, bugfixes, lessons, and code rationale while skipping noise (tool calls, file listings, boilerplate).
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Dashboard
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
memor dashboard
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Shows:
|
|
114
|
+
- **Memory bank** — session chunks, distilled memories, projects tracked
|
|
115
|
+
- **Context efficiency** — overhead %, recall precision, quality scores per session
|
|
116
|
+
- **Per-project breakdown** — which projects have the most context
|
|
117
|
+
- **Recent recalls** — every hook event with scores, latency, and status
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Commands
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
memor help Print the full manual
|
|
125
|
+
memor install-hook Install Claude Code hook + download model
|
|
126
|
+
memor daemon Auto-ingest + distill (background watcher)
|
|
127
|
+
memor dashboard Web dashboard on localhost:8420
|
|
128
|
+
memor query <text> Search memories from the CLI
|
|
129
|
+
memor reingest Wipe DB and re-ingest everything
|
|
130
|
+
memor reingest --project <name> Re-ingest only one project
|
|
131
|
+
memor forget-stale Deactivate memories unused for 30+ days
|
|
132
|
+
memor scan Audit DB for leaked secrets
|
|
133
|
+
memor scan --purge Redact secrets in place
|
|
134
|
+
memor setup-model Download/retry the embedding model
|
|
135
|
+
memor ingest-cc <file> Ingest a single transcript
|
|
136
|
+
memor ingest-project <dir> Bulk ingest a project directory
|
|
137
|
+
memor ingest-doc <file> Ingest a markdown document
|
|
138
|
+
memor distill --project <name> Run distillation manually
|
|
139
|
+
memor eval <cases.json> Run eval suite
|
|
140
|
+
memor bench-embed --project <name> Compare embedding models
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Architecture
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
memor/
|
|
149
|
+
+-- types.py Core dataclasses: Artifact, Scope, Hit, RetrievalTrace
|
|
150
|
+
+-- interfaces.py Protocols: Embedder, LLM, MemoryStore
|
|
151
|
+
+-- cli.py Typer CLI entry point
|
|
152
|
+
+-- daemon.py Auto-ingest + auto-distill + compaction watcher
|
|
153
|
+
+-- project.py Git-root project resolver (filesystem-aware)
|
|
154
|
+
+-- recall.py Shared recall core (used by hook + skill)
|
|
155
|
+
+-- redact.py Secret detection and redaction at ingest
|
|
156
|
+
+-- feedback.py Implicit feedback analyzer (usage detection)
|
|
157
|
+
|
|
|
158
|
+
+-- retrieve/
|
|
159
|
+
| +-- retriever.py Hybrid scoring: similarity + recency + kind + quality
|
|
160
|
+
|
|
|
161
|
+
+-- store/
|
|
162
|
+
| +-- sqlite_store.py SQLite + sqlite-vec (WAL mode, dimension safety)
|
|
163
|
+
|
|
|
164
|
+
+-- embed/
|
|
165
|
+
| +-- local.py model2vec (potion-base-8M, 256-dim, ~60MB)
|
|
166
|
+
| +-- api.py OpenAI-compatible embedding API (optional)
|
|
167
|
+
| +-- fake.py Deterministic SHA-256 embedder (tests)
|
|
168
|
+
|
|
|
169
|
+
+-- dashboard/
|
|
170
|
+
| +-- server.py FastAPI dashboard backend
|
|
171
|
+
| +-- static/index.html Self-contained dashboard (no CDN deps)
|
|
172
|
+
|
|
|
173
|
+
+-- distill/
|
|
174
|
+
| +-- extractive.py TF-IDF + clustering + auto-classification
|
|
175
|
+
| +-- distiller.py Extractive + optional LLM abstractive
|
|
176
|
+
|
|
|
177
|
+
+-- eval/
|
|
178
|
+
+-- runner.py 4-baseline eval runner
|
|
179
|
+
+-- judge.py LLM-as-judge evaluation
|
|
180
|
+
+-- embed_benchmark.py Embedding model comparison
|
|
181
|
+
|
|
182
|
+
bin/memor-hook.py Claude Code hook (thin client)
|
|
183
|
+
skill/recall.py Standalone recall script
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Security
|
|
189
|
+
|
|
190
|
+
**Nothing leaves your machine.** In the default configuration:
|
|
191
|
+
|
|
192
|
+
- **No telemetry, no analytics, no phone-home.** Zero outbound network calls.
|
|
193
|
+
- **Embeddings run locally** via model2vec ONNX (one-time model download from HuggingFace — no user data sent).
|
|
194
|
+
- **Hook transport is a Unix socket** (`~/.memor/hook.sock`), not a network port.
|
|
195
|
+
- **Dashboard binds localhost only.**
|
|
196
|
+
|
|
197
|
+
The only optional network paths are the LLM-based abstractive distiller (requires explicitly setting `ANTHROPIC_API_KEY`) and the API embedding backend — both off by default.
|
|
198
|
+
|
|
199
|
+
### Secret redaction
|
|
200
|
+
|
|
201
|
+
Memor automatically redacts secrets **at ingest**, before anything is embedded or stored:
|
|
202
|
+
|
|
203
|
+
- API keys (AWS `AKIA...`, OpenAI `sk-...`, Anthropic `sk-ant-...`, GitHub `ghp_...`, Stripe, Slack)
|
|
204
|
+
- JWTs, PEM private key blocks
|
|
205
|
+
- Connection strings (`postgres://`, `mongodb://`, `redis://`, etc.)
|
|
206
|
+
- `.env`-style assignments (`DB_PASSWORD=...`, `API_KEY=...`)
|
|
207
|
+
- High-entropy tokens (Shannon entropy > 4.0, length > 20)
|
|
208
|
+
|
|
209
|
+
Redacted content is replaced with `[REDACTED]` in place, preserving surrounding context. To audit and clean an existing database: `memor scan` (audit) or `memor scan --purge` (redact in place).
|
|
210
|
+
|
|
211
|
+
### Contradiction handling
|
|
212
|
+
|
|
213
|
+
When a new memory contradicts an older one in the same project (detected via replacement cues like "switched from X to Y", "no longer", "ripped out"), the older memory is automatically deactivated. This prevents stale decisions from being recalled and misleading the agent.
|
|
214
|
+
|
|
215
|
+
### Local storage
|
|
216
|
+
|
|
217
|
+
The memory database (`~/.memor/memor.db`) is stored as plaintext SQLite on disk. For at-rest protection, we recommend enabling OS-level full-disk encryption (FileVault on macOS, LUKS on Linux) which covers all local files with zero performance overhead.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Development
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
git clone https://github.com/bnimit/memor-ai.git
|
|
225
|
+
cd memor-ai
|
|
226
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
227
|
+
pip install -e ".[dev]"
|
|
228
|
+
|
|
229
|
+
pytest # 153 tests
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT. See [LICENSE](LICENSE) for the full text.
|
|
File without changes
|