Open plain-text memory for AI, covering both history and code

Your assistant's memory becomes files on your disk that you can open, grep and keep: .dai for documents and session history, .cai for a graph of your code. One of the most complete memory systems available, this approach solves a split that most tools have: they remember either conversations or code, but not both. Here both live in the same plain-text, local-first format, and a router knows which half a question belongs to.

Second on the LongMemEval-S leaderboard among memory systems anyone can re-run, the system scores 22.40 points above the same model with no memory at all. It reads roughly 10x fewer tokens per question. The .cai code graph answers callers, callees and rename-impact from a small fraction of the tokens needed to read the files themselves. Every number ships with per-question judge verdicts and a sha256 manifest so the results can be independently verified.

Two formats, one store

.dai holds documents and session history: past conversations, decisions, facts, preferences. .cai holds a deterministic graph of callers, callees, imports, definitions and transitive dependencies. Both are plain text on disk, both answer to grep and git, and both exist for the same reason: so a model reads a small, question-specific slice instead of the whole history or the whole repository. They also cross-link. A document that names a code symbol is linked to it both ways, so a single query can return the code and the prose that explains it. The ask router then decides which tier answers: code graph, documents, or past sessions.

.dai on its own is a complete document-and-history memory; .cai on its own is a complete code graph. Install one, or install both and let the router join them.

.cai is a plain-text code graph

On real repositories it matches or beats Graphify on accuracy while putting a fraction of the tokens in front of the model. Headline results from real repositories rebuilt from source offline (no API, XERJ not included):

  • psf/requests, 16 ast-graded questions: 16/16 at 55 tok vs 13/16 at 689 tok (13x less) vs 16/16 at 9,023 tok (164x less)
  • httpx imports (who does X import): 100% at 22 tok vs 91% at 4,696 tok (218x less) vs 100% at 64,075 tok (2,976x less)
  • Make this change, 6 httpx edits: 1.00 recall, 6/6 sets at 38 tok vs 0.64, 3/6 at 1,651 vs 0.61, 1/6 at 64,075 (43x less vs 1,686x less)

At 35x scale (the CPython standard library, 7,469 symbols) the per-query cost stays flat: .cai averages 69 tokens to Graphify's 178.

.dai format

A .dai file is three plain-text zones: a YAML header, a fenced JSON block, and the text. No binary, no database, no SDK required to read it. Any programming language can be handled—the reference engine is Node, and a reader in Python, Rust or Go is an afternoon's work, and the spec is normative, written so that two independent implementations agree. Any model can read the store—the store is written once by a cheap observer model and read by whichever model answers. The same store measured with five answering models scored 78% to 92%. Any tool can read it: grep, git log, diff, your editor, a shell script.

Benchmark results

Second on the LongMemEval-S leaderboard. One setup for every row: LongMemEval-S, GPT-4o answering, all 500 questions, micro-averaged, and only configurations somebody who does not work for the vendor could re-run. The bottom row is that same GPT-4o with no memory system, reading the whole history pasted into its context: 22.40 points below this system. Every figure carries a caveat that travels with it, documented in RESULTS.md. Not in that table? Other systems publish figures measured on a different answering model, a different denominator or a different benchmark, so they cannot be set beside a GPT-4o 500/500 row in either direction.

One memory layer, five answering models, 500 questions each. Retrieval identical for every row (proved by a byte-identical diagnostics file). Details and caveats in RESULTS-ACTORS.md.

Memory as a format, not a service

Every memory product on the market keeps your history inside its own service and hands it back through its own API. .dai takes the opposite bet: memory is a file format, the way a photo is a JPEG. Three plain-text zones per conversation, a small derived index beside them, and any model, any tool, or grep can read it.

memory as a servicememory as a format (.dai)
where your history livestheir databaseyour disk, plain text
who can read ittheir SDKClaude, GPT, Gemini, Cursor, local models, grep, git
when the vendor disappearsso does the memorythe files stay readable in any editor
how you inspect a recalllogs, if anyopen the file the answer cites
what a benchmark number meansone product's pipelineone store, measured per answering model, so you can pick the model

The store is built once by a cheap observer model and read by any actor model. Convert with a good model, then answer with whatever is cheapest, fastest or local.

One store, connected over MCP

One store, connected over MCP, read and written by the tools you already use. node setup.js detects and configures each of these and backs up what it touches; install has the per-tool commands.

assistantseditors and IDEsCLI and any MCP client
Claude Desktop, Claude Code, any model over MCPCursor, Windsurf, Zed, Cline, ContinueCodex CLI, plus any MCP client via --client generic --config <file>

Any MCP-capable runtime, too. The server is a plain stdio MCP server, so frameworks that speak MCP call save_memory and recall_memory with no adapter to write: the OpenAI Agents SDK, the Vercel AI SDK, LangGraph, LangChain, CrewAI and LlamaIndex all consume an MCP server as a tool source. Point them at node mcp_server.mjs.

Bring your history. Claude Code sessions on this machine convert automatically. From any other tool, export a folder of .txt, .md or .jsonl and run node daidocs.js convert. Native history import from more tools is on the roadmap.

DaiDocs also ships a browser extension that captures your AI chats (ChatGPT, Claude, Gemini) and, opt-in, your X timeline and the websites you choose, straight into a local DaiDocs store. It is local only: nothing leaves your machine, capture is off by default, and sensitive sites (banking, health, webmail, password managers) are never touched. It lives in browser-extension/, and it is not installed automatically: you load it once in your browser. In short: start the local capture server from browser-extension/: node capture_server.mjs (no extra install needed). In Chrome or Edge, open the extensions page, turn on Developer mode, then Load unpacked the browser-extension/extension folder. In Firefox, open about:debugging and load browser-extension/extension/manifest.json. Accept the one-time consent, then use the on-page pill to turn capture on for a site.

Installation

Two halves, two package managers. Install the one you want, or both for the full system.

  • npx daidocs setup — .dai: documents + session history (Node 18+)
  • pip install kerneta-cai — .cai: the code graph (Python 3.10+)

Want both? Install both, one with npm and one with pip. npx daidocs setup --ask also offers the .cai code tier as part of its flow. The two halves share nothing at install time and never collide: .dai is Node, .cai is Python, each is independently useful, and the ask router joins them when both are present.

Node 18 or newer. npx daidocs setup. One command. It detects Claude Desktop, Claude Code, Cursor, Windsurf, Codex, Cline, Continue and Zed, configures all of them, installs the session hooks, the reading protocol and the .dai icon, and backs up every file it touches. On a Claude subscription there is no API key and nothing to pay.

Want the source and the benchmark artifacts too? Clone it and run setup from there instead: git clone https://github.com/Kerneta/daidocs daidocs-app && cd daidocs-app && node setup.js. The clone is named daidocs-app on purpose—git clone would otherwise make a folder called daidocs, and the default memory store is DaiDocs: on Windows and macOS those are the same folder, so a clone made from your home directory would land on top of your own memory. Setup refuses to run from inside the store if it ever happens.

Python 3.10 or newer. One install brings the engine, the tree-sitter grammars for all 10 languages, and a kerneta command that drives every operation: pip install kerneta-cai. kerneta doctor verifies the interpreter, the engine and the grammars. kerneta setup then makes .cai automatic for a project: it builds the code graph once, installs a skill so Claude Code queries the store instead of reading source files (far fewer tokens), and adds a PostToolUse hook that refreshes the store after every edit, so the graph is always current with no manual rebuild. To make it load in every project at once, kerneta setup --global --auto. The graph is deterministic, built by tree-sitter rather than a model, so it needs no API key and costs nothing to keep fresh. When a .dai session store sits beside the project, kerneta setup links it automatically and the ask router answers code, document and history questions from one command.

This is the .dai side, a separate package from the .cai code tier above. Prefer Python? Read your .dai stores from code, and drive the engine from a daidocs command: pip install daidocs. from daidocs import Store. store = Store("~/DaiDocs") — your memory store. for entry in store.manifest(): — every document. doc = store.read(store.ids()[0]) — one document, fully parsed. print(doc["understanding"]["summary"]). print(store.search("deploy")) — find documents by keyword.

Two things in one install: Reader (pure Python, no Node): from daidocs import Store reads the manifest, any document, and the facts / events / profile indexes. daidocs command: drives the Node engine, so daidocs setup and daidocs convert behave like npx daidocs. This needs Node 18+; if Node is missing it says so and offers to install it. Full guide: readers/python/. setup.js installs the dependencies on its first run and then configures everything.

Setup asks nothing. It detects what you have and configures all of it: Claude Desktop, Claude Code, the session hooks, Cursor, Windsurf, Codex, Cline, Continue, Zed, the reading protocol and the .dai file icon. It backs up every file it touches. node setup.js --status — what is on, and the command that changes each one. node setup.js —ask — choose each surface yourself instead. node setup.js —restore — put the machine back exactly as it was.

The one thing it never does on its own is convert the history you already have, because that can run for a while and, with an API key, it spends money. It is one command when you want it, and it is worth wanting: see Bring what you already have.

Another MCP client? One command each, rather than a config to edit: node setup.js --client codex (or cursor, windsurf, cline, continue, zed), and node setup.js --client generic --config <that client's config file> for anything else. node setup.js --client list shows the names and where each one keeps its config.

In Claude Code every session saves itself as you work, so there is nothing to remember. On any other connected assistant, say "save this chat to memory". To give a folder its own project memory, say "make this folder a project" in it, or in a subfolder to make a sub-project.

Most people installing this have months of conversations sitting on disk already. One command turns them into memory, which is the difference between a store that is useful this afternoon and one that fills up slowly from here: node daidocs.js convert. It reads three kinds of history, all the same way: Claude Code sessions on this machine from ~/.claude/projects, sessions already captured but not yet converted, the _pending markers with their text in_unconverted/, a folder of exports from anywhere else: .txt, .md or .jsonl. It lists what it found with dates, projects and sizes, asks which ones (all, or 1,3,5-8), asks where the store goes, and quotes the worst-cases...