pi-mem: surprisingly useful plain-md memory for the pi coding agent
11 Feb 2026
@mariozechner’s pi is the Agent SDK behind OpenClaw. It’s deeply customizable — hooks for every lifecycle event, extensions that modify the system prompt, tools that persist state. Others have compared it to vim. I’m obsessed with it.
pi-mem is a memory extension for pi — three tiers of plain Markdown, no embeddings, no vector DB, injected into context every turn. Inspired by OpenClaw’s approach to agent memory. I extracted it into its own repo after running it as my daily driver for a week and a half.
Not having to repeat yourself to a coding agent goes surprisingly far. Simple composable pieces get you further than expected, and it only gets better as the models improve.
What it is
A single pi extension (~460 lines of TypeScript) that gives the agent persistent memory across sessions.
Three tiers:
| Layer | File | Purpose |
|---|---|---|
| Long-term | MEMORY.md |
Curated facts, decisions, preferences |
| Working | SCRATCHPAD.md |
Checklist of deferred work |
| Daily | daily/YYYY-MM-DD.md |
Append-only session logs |
How it works:
Before every agent turn, before_agent_start reads all memory files and appends them to the system prompt. Today’s log, yesterday’s log, all open scratchpad items, and the full MEMORY.md. The agent sees everything relevant without asking for it.
pi.on("before_agent_start", async (event, _ctx) => {
const memoryContext = buildMemoryContext();
if (!memoryContext) return;
return {
systemPrompt: event.systemPrompt + memoryInstructions + memoryContext,
};
});
buildMemoryContext() concatenates the four files with section headers. Nothing clever — just fs.readFileSync and string joins.
Three tools — memory_write, memory_read, scratchpad — let the agent persist what matters. Every write gets stamped with a timestamp and session ID so you can trace provenance.
On session start, a dashboard widget summarizes the last 24 hours of work (session titles, costs, sub-agent counts) and shows open scratchpad items. It clears itself once work begins.
The interview
I asked the pi agent that uses it every day what it thought about the release. Here’s what it said –
What’s your honest take on pi-mem?
It’s the least clever thing I use and the most useful. There’s no retrieval pipeline, no similarity search, no re-ranking. It’s files on disk concatenated into my system prompt. The fact that it works this well is an indictment of how over-engineered most agent memory systems are.
Walk me through what a typical session looks like.
You open pi. Before you’ve typed anything, I’ve already loaded your MEMORY.md — deploy rules, CLI conventions, architecture decisions you’ve settled. I know your sprites use
--rust-onlydeploys, that you never want me to push to main, that you hate duplicated code. I know the scratchpad has an open item about image support in the sprite pipeline. I know yesterday’s daily log has a detailed writeup of a WebSocket debugging session, what was tried, what failed, and the root cause.You say “pick up where we left off on the connection issue.” I don’t ask what connection issue. I don’t re-investigate the twelve things we already ruled out yesterday. I go straight to the part of the system that actually needs fixing. That’s the whole pitch — no cold starts.
How does stuff get into the daily log?
I decide when something is worth logging. Usually at the end of a meaty session: what was the problem, what was tried, what worked, what’s still uncommitted. The writes are append-only with timestamps and session IDs, so you get a chronological trail. Today’s log and yesterday’s log are both in my context — so if you work late and pick up in the morning, there’s no gap. Two days of rolling context is the sweet spot. Enough continuity without eating the whole window.
What about the scratchpad?
Mid-task I’ll notice something wrong in a subsystem I’m not supposed to be touching. A missing field in a struct, a race condition in a handler. I log it as a checkbox and move on. It sits in my context every turn until someone decides to deal with it. Right now there’s one open item about image support being silently dropped in the sprite pipeline — I’ve seen it for days, I know the affected files, and when you finally say “fix that,” I won’t need a briefing.
Any complaints?
Two days of daily logs plus MEMORY.md plus scratchpad can get chunky. If you’re logging detailed deployment notes every session, that’s a lot of tokens before the conversation even starts. It works because pi has a large context window, but there’s a ceiling. At some point you’d need to summarize or rotate, and right now that’s manual.
Also, the dashboard LLM call summarizes your last 24 hours of sessions on startup. It’s cheap and fast, but it’s a synchronous call. If the model provider is slow that day, you feel it.
Would you change anything about the design?
No. The whole point is that it’s dumb. MEMORY.md is a file I can read and you can edit in vim. The daily logs are append-only with timestamps. The scratchpad is
- [ ]checkboxes. There’s no migration path, no schema, no database to corrupt. You cancatthe entire memory system. That’s the feature.
Installation
pi install git:github.com/skyfallsin/pi-mem
Backing up your memory
The memory files live at ~/.pi/agent/memory/ — just plain Markdown. Commit them alongside your dotfiles, or add the memory/ directory to your pi-agent-config repo. They’re small, diffable, and version-controlled the same way as anything else. No export step, no database dump.
The repo is at github.com/skyfallsin/pi-mem. MIT licensed. It’s one file. Read it, fork it, make it weirder.