{"id":50696814,"url":"https://github.com/bnimit/memor-ai","last_synced_at":"2026-06-09T07:01:33.028Z","repository":{"id":362336911,"uuid":"1258553890","full_name":"bnimit/memor-ai","owner":"bnimit","description":"Measured memory layer for coding agents — store, distill, and retrieve past session context instead of re-sending full history to the LLM. 99.7% token savings, 11ms retrieval, built-in eval harness.","archived":false,"fork":false,"pushed_at":"2026-06-03T18:41:52.000Z","size":125,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T20:09:39.285Z","etag":null,"topics":["agent","ai","claude","coding-agent","context-management","developer-tools","distillation","embeddings","llm","memory","rag","retrieval","sqlite"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bnimit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-03T17:32:20.000Z","updated_at":"2026-06-03T18:41:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bnimit/memor-ai","commit_stats":null,"previous_names":["bnimit/memor-ai"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/bnimit/memor-ai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bnimit%2Fmemor-ai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bnimit%2Fmemor-ai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bnimit%2Fmemor-ai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bnimit%2Fmemor-ai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bnimit","download_url":"https://codeload.github.com/bnimit/memor-ai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bnimit%2Fmemor-ai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33964401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","ai","claude","coding-agent","context-management","developer-tools","distillation","embeddings","llm","memory","rag","retrieval","sqlite"],"created_at":"2026-06-09T07:00:50.269Z","updated_at":"2026-06-09T07:01:33.017Z","avatar_url":"https://github.com/bnimit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"```\n                                                _\n _ __ ___   ___ _ __ ___   ___  _ __       __ _(_)\n| '_ ` _ \\ / _ \\ '_ ` _ \\ / _ \\| '__|____ / _` | |\n| | | | | |  __/ | | | | | (_) | | |_____| (_| | |\n|_| |_| |_|\\___|_| |_| |_|\\___/|_|        \\__,_|_|\n\n  Measured memory for coding agents.\n```\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Tests](https://img.shields.io/badge/tests-256%20passing-brightgreen.svg)]()\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)]()\n[![PyPI](https://img.shields.io/pypi/v/memor-cli.svg)](https://pypi.org/project/memor-cli/)\n\n**Automatic background memory for Claude Code.** Fire and forget — no API keys needed.\n\nMemor watches your coding sessions, extracts decisions and patterns, and recalls relevant context on every prompt. Zero configuration. One install. Your agent remembers everything.\n\n---\n\n## Quick Start\n\n```bash\n# Install globally (recommended)\npipx install memor-cli\n\n# Install the Claude Code hook + download embedding model (~60MB)\nmemor install-hook\n\n# Start as a background service (macOS/Linux)\nmemor service install\n\n# Or run in the foreground\nmemor daemon\n```\n\nThat's it. Every Claude Code prompt now gets automatic context recall. Open the dashboard to see it working:\n\n```bash\nmemor dashboard\n# Opens http://localhost:8420\n```\n\n\u003e **Alternative install:** `pip install memor-cli` works too — just make sure `~/.local/bin` is on your PATH so the `memor` command is available.\n\n---\n\n## How It Works\n\n```\n  You type a prompt in Claude Code\n      |\n      v\n  Hook fires (UserPromptSubmit)\n      |\n      v\n  Embed query locally (model2vec, ~2ms)\n      |\n      v\n  Hybrid retrieval: dense vectors + lexical BM25, fused (RRF)\n      |\n      v\n  Relevance gate drops off-topic matches (inject nothing if nothing fits)\n      |\n      v\n  Rank: similarity + recency + kind weight + quality\n      |\n      v\n  Inject relevant context into prompt\n      |\n      v\n  Claude sees your past decisions, bugfixes,\n  architecture choices — without you re-explaining\n```\n\n**Two background processes:**\n\n1. **Daemon** — polls `~/.claude/projects/` for transcripts, embeds chunks, runs distillation, analyzes feedback (positive and negative), promotes cross-project patterns to global scope, compacts duplicates, tracks session-level token usage. All local.\n2. **Hook** — fires on every prompt, recalls relevant memories, injects them as context. Sub-15ms.\n\n**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.\n\n---\n\n## Hybrid Retrieval\n\nMemor retrieves over two channels and fuses them, so it catches both semantic matches and exact terms:\n\n- **Dense** — local vector similarity (model2vec) for semantic recall.\n- **Lexical** — SQLite FTS5 / BM25 over the raw text, to recover exact identifiers, error strings, and API names that static embeddings blur together.\n\nThe two rankings are combined with **Reciprocal Rank Fusion (RRF)**. A **relevance gate** drops anti-correlated (off-topic) candidates *before* ranking, so an unrelated prompt injects nothing rather than the least-bad guess. The lexical channel only activates when the dense channel finds the query on-topic, preventing generic words from pulling in noise.\n\n\u003e Tunable via `MEMOR_MIN_SIMILARITY` (relevance floor, default 0.0) and `MEMOR_MAX_TOKENS` (injection budget, default 1500).\n\n## Scoring\n\nSurviving candidates are ranked by four signals:\n\n| Signal | Weight | How it works |\n|---|---|---|\n| **Semantic similarity** | 50% | Dense + lexical relevance, fused via RRF |\n| **Recency** | 25% | Exponential decay with 14-day half-life — recent decisions rank higher |\n| **Kind weight** | 15% | Distilled memories (1.3x) rank above raw session chunks (1.0x) |\n| **Quality** | 10% | Bayesian score from implicit feedback — memories the agent actually uses rank higher |\n\nThis means a relevant decision from yesterday beats a vaguely-related chunk from a month ago — even if the raw embedding similarity is similar.\n\n### Feedback Loop\n\nMemor tracks whether recalled memories actually get used by the agent — and whether they actively hurt. After each session, the daemon analyzes the transcript in both directions:\n\n- **Positive signal** — n-gram overlap or semantic similarity between recalled content and the agent's response. Memories that consistently prove useful get quality boosts.\n- **Negative signal** — user rejection (\"no that's wrong\", \"we switched to X\") or assistant contradiction (\"however, looking at the current code, we actually use Y\"). Memories that get corrected receive a quality penalty, making them less likely to be recalled next time.\n\nThe quality formula is Bayesian: `(uses - negatives + 1) / (recalls + 2)`. One correction weighs as much as one positive use, so harmful memories drop fast. Memories never recalled in 30+ days get automatically deactivated. Near-duplicate memories are compacted into one.\n\n---\n\n## What Gets Stored\n\n| Kind | Source | Description |\n|---|---|---|\n| `session_chunk` | Daemon auto-ingest | Filtered turns from Claude Code transcripts |\n| `memory` | Extractive distillation | Key decisions, patterns, bugfixes per session |\n\nMemories 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).\n\n---\n\n## Global Memories\n\nSome patterns aren't project-specific — they're yours. \"Always use type hints.\" \"Structure FastAPI apps with a `routes/` directory.\" \"Prefer composition over inheritance.\"\n\nMemor detects these automatically. When the same pattern appears in **3 or more projects** (measured by embedding similarity), the daemon promotes it to a `_global` scope:\n\n- **Global memories are recalled everywhere** — they show up in every project's search results alongside project-specific memories.\n- **Source duplicates are deactivated** — the per-project copies get superseded by the single global version, reducing clutter.\n- **No manual tagging** — promotion is fully automatic, based on cross-project clustering.\n\nThis means your coding habits and preferences follow you into new projects from the first prompt, without you having to re-explain anything.\n\n---\n\n## Dashboard\n\n```bash\nmemor dashboard\n```\n\nDark fintech-inspired UI showing:\n- **Hero metrics** — total memories, recall count, avg latency, coverage — with sparkline bars\n- **Daily recall activity** — stacked bar chart of hits vs misses over time\n- **Session efficiency** — real token savings measured from API usage data (avg tokens/turn with vs without recall)\n- **Per-project breakdown** — artifact counts, token totals, last activity\n- **Recent recalls** — every hook event with scores, latency, and status\n\n---\n\n## Commands\n\n```\nmemor help                           Print the full manual\nmemor install-hook                   Install Claude Code hook + download model\nmemor daemon                         Auto-ingest + distill (background watcher)\nmemor dashboard                      Web dashboard on localhost:8420\nmemor version                        Print installed version\nmemor service install                Run daemon as background service (launchd/systemd)\nmemor service stop                   Stop the background service\nmemor service uninstall              Remove the background service\nmemor service status                 Check if the service is running\nmemor query \u003ctext\u003e                   Search memories from the CLI\nmemor reingest                       Wipe DB and re-ingest everything\nmemor reingest --project \u003cname\u003e      Re-ingest only one project\nmemor forget-stale                   Deactivate memories unused for 30+ days\nmemor scan                           Audit DB for leaked secrets\nmemor scan --purge                   Redact secrets in place\nmemor setup-model                    Download/retry the embedding model\nmemor ingest-cc \u003cfile\u003e               Ingest a single transcript\nmemor ingest-project \u003cdir\u003e           Bulk ingest a project directory\nmemor ingest-doc \u003cfile\u003e              Ingest a markdown document\nmemor distill --project \u003cname\u003e       Run distillation manually\nmemor eval \u003ccases.json\u003e              Run eval suite\nmemor eval-counterfactual --project  Win/tie/loss vs no-memory baseline\nmemor bench-embed --project \u003cname\u003e   Compare embedding models\n```\n\n---\n\n## Architecture\n\n```\nmemor/\n+-- types.py              Core dataclasses: Artifact, Scope, Hit, RetrievalTrace\n+-- interfaces.py         Protocols: Embedder, LLM, MemoryStore\n+-- cli.py                Typer CLI entry point\n+-- daemon.py             Auto-ingest + auto-distill + compaction watcher\n+-- project.py            Git-root project resolver (filesystem-aware)\n+-- recall.py             Shared recall core (used by hook + skill)\n+-- redact.py             Secret detection and redaction at ingest\n+-- feedback.py           Feedback analyzer (positive usage + negative signals)\n+-- global_memories.py    Cross-project promotion to _global scope\n|\n+-- retrieve/\n|   +-- retriever.py      Hybrid retrieval (dense + BM25, RRF) + relevance gate + scoring\n|\n+-- store/\n|   +-- sqlite_store.py   SQLite + sqlite-vec + FTS5 (WAL mode, dimension safety)\n|\n+-- embed/\n|   +-- local.py          model2vec (potion-base-8M, 256-dim, ~60MB)\n|   +-- api.py            OpenAI-compatible embedding API (optional)\n|   +-- fake.py           Deterministic SHA-256 embedder (tests)\n|\n+-- service.py            Background service management (launchd/systemd)\n+-- dashboard/\n|   +-- server.py         FastAPI dashboard backend\n|   +-- static/index.html Self-contained dashboard (no CDN deps)\n|\n+-- distill/\n|   +-- extractive.py     TF-IDF + clustering + auto-classification\n|   +-- distiller.py      Extractive + optional LLM abstractive\n|\n+-- eval/\n    +-- runner.py          4-baseline eval runner\n    +-- judge.py           LLM-as-judge evaluation\n    +-- embed_benchmark.py Embedding model comparison\n\nmemor/hook_cli.py          Claude Code hook entry point (thin client)\nskill/recall.py            Standalone recall script\n```\n\n---\n\n## Security\n\n**Nothing leaves your machine.** In the default configuration:\n\n- **No telemetry, no analytics, no phone-home.** Zero outbound network calls.\n- **Embeddings run locally** via model2vec static token embeddings — no inference runtime, no GPU (one-time model download from HuggingFace — no user data sent).\n- **Hook transport is a Unix socket** (`~/.memor/hook.sock`), not a network port.\n- **Dashboard binds localhost only.**\n\nThe 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.\n\n### Secret redaction\n\nMemor automatically redacts secrets **at ingest**, before anything is embedded or stored:\n\n- API keys (AWS `AKIA...`, OpenAI `sk-...`, Anthropic `sk-ant-...`, GitHub `ghp_...`, Stripe, Slack)\n- JWTs, PEM private key blocks\n- Connection strings (`postgres://`, `mongodb://`, `redis://`, etc.)\n- `.env`-style assignments (`DB_PASSWORD=...`, `API_KEY=...`)\n- High-entropy tokens (Shannon entropy \u003e 4.0, length \u003e 20)\n\nRedacted 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).\n\n### Contradiction handling\n\nWhen 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.\n\n### Local storage\n\nThe 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.\n\n---\n\n## Development\n\n```bash\ngit clone https://github.com/bnimit/memor-ai.git\ncd memor-ai\npython3 -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -e \".[dev]\"\n\npytest  # 251 tests\n```\n\n---\n\n## License\n\nMIT. See [LICENSE](LICENSE) for the full text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbnimit%2Fmemor-ai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbnimit%2Fmemor-ai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbnimit%2Fmemor-ai/lists"}