{"id":50818123,"url":"https://github.com/noreff/memory-agent","last_synced_at":"2026-06-13T11:04:50.388Z","repository":{"id":364398636,"uuid":"1267760888","full_name":"noreff/memory-agent","owner":"noreff","description":"Memory for coding agents - your AI history compiled into markdown notes you own, every fact with receipts","archived":false,"fork":false,"pushed_at":"2026-06-12T21:03:57.000Z","size":98,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T23:06:13.744Z","etag":null,"topics":["agentic-memory","claude-code","knowledge-base","llm","local-first","markdown"],"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/noreff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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-12T20:51:48.000Z","updated_at":"2026-06-12T21:07:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/noreff/memory-agent","commit_stats":null,"previous_names":["noreff/memory-agent"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/noreff/memory-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noreff%2Fmemory-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noreff%2Fmemory-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noreff%2Fmemory-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noreff%2Fmemory-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noreff","download_url":"https://codeload.github.com/noreff/memory-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noreff%2Fmemory-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34281706,"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-13T02:00:06.617Z","response_time":62,"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":["agentic-memory","claude-code","knowledge-base","llm","local-first","markdown"],"created_at":"2026-06-13T11:04:49.895Z","updated_at":"2026-06-13T11:04:50.375Z","avatar_url":"https://github.com/noreff.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# memory-agent\n\nYour coding agent forgets everything between sessions. The history is all there on disk - hundreds of transcripts where you explained your stack, your ports, your decisions. Nobody reads it.\n\nmemory-agent reads it. It compiles your AI conversation history into a knowledge base of plain markdown notes, keeps it fresh in the background, and hands it to your agent when a session starts. Open a fresh session, ask \"what do you know about me\", get a real answer.\n\n## Install\n\nOne command:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/noreff/memory-agent/main/install.sh | sh\n```\n\nAlready in Claude Code? Same result without leaving it:\n\n```\n/plugin marketplace add noreff/memory-agent\n/plugin install memory-agent@memory-agent\n```\n\nThen say `/memory-setup`. The agent shows you what it would remember from your last session, asks three questions, finds your history with your consent and backfills it. First results arrive in minutes. That is the last mechanical thing you do here - everything after it is conversation.\n\nRequirements: Python 3.10+ (stdlib only) and Claude Code. A local model server is optional - with LM Studio running, extraction is free and transcripts never leave your machine. Without one, extraction runs on your Claude plan. The backend is detected per run, nothing to configure.\n\n## Why markdown files\n\n- Every fact carries `sources` (the sessions it came from) and `conflicts` (what the note used to say, dated). Memory with receipts.\n- Your memory is yours to read, grep, edit and version. Wrong fact? Edit the note.\n- No vector DB, no daemon, no server. Retrieval is an index file the model reads, which holds up fine at personal scale - a few hundred notes.\n- A new topic needs 3+ independent facts before it earns a note. No one-fact stubs.\n- Injected memory is stripped before extraction, so the system never re-memorizes its own output.\n- Contradictions resolve by recency and the losing fact stays in the log. Nothing is silently overwritten.\n\n## How it works\n\n```\ncapture  notice new transcripts              -\u003e state/inbox/          no model, just file diffs\nrefresh  inbox -\u003e distill -\u003e extract atoms   -\u003e state/derived/atoms   cheap model, local-friendly\nmerge    route atoms into notes, re-write    -\u003e knowledge/            strong model\n         only the touched ones\ninject   knowledge/ -\u003e into a new session                             read-only\n```\n\nTwo speeds on purpose. Extraction is high-volume and low-judgment, so a free local model handles it. Consolidation needs judgment - deciding which note a fact belongs to, what it supersedes - so a strong model handles that, a few calls a day. Note frontmatter is always built by code, never by the model.\n\nAtoms are routed against the existing knowledge base: into an existing note, to a gated new topic, or out as a duplicate. Merges apply automatically with timestamped backups (`merge.autoPromote: false` if you want a review gate instead). A periodic full recompile stays available as the deep clean.\n\n## Backfill your history\n\nThis is the main event. Point the backfill at everything you have - Claude Code transcripts, a ChatGPT export, old machine dumps, random docs. Agents figure out each format, chunk it, extract atoms, dedupe globally and write canonical notes. Raw files are never modified.\n\nFrom a Claude Code session:\n\n```\nWorkflow -\u003e { scriptPath: \"\u003cROOT\u003e/engine/backfill.js\",\n              args: { rawDir: \"/path/to/raw\", derivedDir: \"\u003cROOT\u003e/state/derived\",\n                      maxChunks: 400, model: \"sonnet\" } }\n```\n\nthen\n\n```bash\npython3 mem.py adopt   # derived notes -\u003e knowledge/ + index\n```\n\nReference run: 103 sessions became 6,419 atoms and 33 notes in 47 minutes. Format hints live in `input/handlers/` - there is one for Claude Code transcripts and one for ChatGPT exports.\n\n## CLI\n\n```\npython3 mem.py status      paths, detected backend, queue depth\npython3 mem.py capture     scan for new sessions (first run baselines, nothing floods)\npython3 mem.py refresh     extract atoms from queued sessions\npython3 mem.py merge       consolidate atoms into notes\npython3 mem.py adopt       promote backfill output into the live KB\npython3 mem.py inject      print what a new session would receive\npython3 mem.py eval        score your memory against your own gold set\n```\n\n`refresh` and `merge` are batched, locked against concurrent runs, and safe to fire from cron. The `/memory-refresh` command wraps the whole cycle and replies in one line.\n\n## Config\n\n```jsonc\n{\n  \"agents\": [\n    { \"adapter\": \"claude-code\", \"enabled\": true },\n    { \"adapter\": \"generic\", \"name\": \"my-tool\", \"enabled\": false,\n      \"transcripts\": { \"dir\": \"~/.my-tool/logs\", \"format\": \"auto\" },\n      \"inject\": { \"file\": \"~/.my-tool/memory.md\" } }\n  ],\n  \"merge\": { \"autoPromote\": true, \"newNoteThreshold\": 3 },\n  \"model\": {\n    \"extract\": { \"backend\": \"auto\",\n                 \"models\": { \"local\": \"qwen/qwen3.6-35b-a3b\", \"subscription\": \"haiku\" } },\n    \"route\":   { \"backend\": \"subscription\", \"model\": \"sonnet\" },\n    \"merge\":   { \"backend\": \"subscription\", \"model\": \"sonnet\" }\n  }\n}\n```\n\n`agents` is a list - several tools can feed one knowledge base, and any tool you can point at a folder works through the generic adapter with zero code. Plugin installs override config by dropping a `config.json` into the plugin data dir, which survives updates.\n\n## Eval\n\n`mem.py eval` scores three things against a gold set you write yourself (`eval/` is git-ignored, it is personal data): recall (re-extract frozen fixtures, do known facts come back), lookup (pick the right note from the index, answer from its body), inject (what is answerable from the index alone). Every run appends to `eval/history.jsonl`, so a prompt or model change shows up as a score delta instead of a feeling.\n\n## Security model\n\nMemory built from conversations is an injection surface. The defenses are structural: the knowledge base is only written by code, from staged artifacts, after a gate. Note frontmatter is built in code. Atom payloads are fenced as untrusted data in every prompt. The system's own model calls are sentinel-tagged so they can never be re-memorized. Raw transcripts are read-only.\n\nResidual risk: consolidation agents run with your host's tool permissions, so check your platform's sandboxing if you process transcripts you don't trust. Promoted notes get injected into future sessions - treat `knowledge/` like you treat CLAUDE.md.\n\nThe background extractor never uses your Claude plan. It runs local-only, and if no local server is up it just queues work for your next in-session run.\n\n## Layout\n\n```\ncore/        config, on-disk pipeline contract, prompt rubrics\ninput/       format handlers + the mechanical chunker\nadapters/\n  agent/     claude_code (hooks, commands, launchd), generic (any tool)\n  model/     local (LM Studio), cloud (API), subscription (claude CLI), stub\nengine/      capture, refresh, merge, backfill.js, evals, inject\ntests/       python3 -m unittest discover tests\nmem.py       the CLI        install.py  hooks + commands + macOS collector\n```\n\nMIT. Built on a Mac, runs on anything with Python; the launchd collector is macOS-only (Linux: cron `mem.py capture \u0026\u0026 mem.py refresh`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoreff%2Fmemory-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoreff%2Fmemory-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoreff%2Fmemory-agent/lists"}