Verify before done
A run that changed code and ran nothing is sent back once to run the project's checks.
Features
Every feature below has a demo built from the app's own text: the turn mnemo --demo plays, the gate's rules, the real command list and themes. Scroll the reel or jump to one.
01 one turn, start to finish
- const res = await fetch(url);- if (!res.ok) throw new Error(`HTTP $${res.status}`);- return res.json();+ for (let attempt = 1; ; attempt++) {+ const res = await fetch(url);+ if (res.ok) return res.json();+ if (attempt === 3 || res.status < 500) throw …+ await new Promise((r) => setTimeout(r, 200 * 2 ** attempt));+ }
getJson now retries server errors up to three times: 5xx responses back off exponentially (400 ms, 800 ms); 4xx responses still fail on the first try.Before the model sees your message, memory is searched for it and what it finds is attached: facts about the project and you, earlier sessions, pitfalls with their fixes, skills. Recalled items are candidates, never presented as fact.
Thinking, text and tool calls stream into the transcript as they arrive. enter while it works queues your next message, alt+enter adds a newline, and esc interrupts the turn.
Reads run. Edits and commands ask, unless your mode or rules say otherwise, and a deny rule always holds. The question names the command or the file it is about.
Each tool call and its outcome is recorded with its subject. A failure steers memory right away, once per distinct failure, so the same mistake is less likely in the same run.
A clean run reinforces the memories that fed it. Then one grounded reflection writes the session record, the facts you stated or a tool showed, the fixes that resolved failures, and a skill when one was demonstrated.
02 memory
Facts, conventions, pitfalls with their fixes, open threads and skills, stored on your machine and kept per project. Before every model call the relevant ones are recalled; you can read all of it with /memory, add with /remember and retire with /forget. Try it: select a node, steer it, forget it, or tell it something.
When a run ends, one model call reads a grounded digest of it: your words, the answers, every tool call with its outcome, the failure-and-recovery pairs found in the tool log, and the files that changed. It returns facts, the session record (goal, outcome, what was done, decisions, open threads), fixes, and a skill when one was demonstrated. Only what you said or a tool showed is kept: a guess is not memory.
At the start of each run your message is searched against memory and what it finds travels with the message, beside a standing profile of the project and of you. A small model often will not think to search, so Mnemo does not leave it to the model. The model can still look further itself with memory_search and session_search.
A fact is a key and a value. Saying something new about the same key supersedes the old value instead of adding a second one, so a changed rule never comes back as two live instructions. The old value keeps its place in history; nothing is erased.
Memories are nodes in areas modelled on the brain: episodic (sessions and outcomes), semantic (facts), procedural (skills), spatial (repositories, paths, services), salience (what hurt) and executive (steering decisions). A question is routed toward the likely areas but still searches all of them, and one hop along the graph's links brings related memories with it.
Every change is one of eleven operations appended to a journal, and replaying the journal rebuilds the memory exactly. The journal is the only source of truth. Mnemo, its sub-agents and Claude Code's hooks can write to it at the same time without corrupting it.
A recalled memory earns a “useful” vote only when the answer reuses words that are distinctive to it, and votes gently reorder what comes back. Text that tries to instruct the agent, smuggle data out or hide characters is refused, and credential-shaped strings are redacted before anything reaches memory or a log.
fact
http helper
getJson (src/fetch.ts) retries 5xx up to 3 times with backoff; 4xx fail fast
“That was wrong” is memory_steer: what memory supplied is trusted less next time. /forget retires it.
03 experience compounds
Memory is steered, once per distinct failure. What hurt is marked, the memories that misled the run lose weight, and when a later step fixes the problem the fix is kept with it. Next time the same situation comes up, it is recalled as a pitfall with its fix, before the model repeats the mistake.
A pain marker is recorded first, unconditionally, in the salience area. It is linked to the session but never as a source of context, so a marker can never be blamed for the next failure.
Every memory that supplied context to the run is checked against the failure's words; the ones it implicates lose weight. A memory that keeps misleading sinks in the ranking instead of being trusted forever.
When the right value is known, the wrong fact is superseded by it, after checking that the old one still exists and is current. History keeps both.
When a source's weight falls below 0.2 and a better one exists, the link to the bad one is cut and the alternate takes its place.
A clean run does the mirror image: every memory that fed it gains a little weight, so good context rises the more it is used.
Reflection pairs each failure with what resolved it. A pitfall is recalled only once it carries a fix, as a line the model can act on rather than a warning it cannot.
04 skills it writes for itself
Yes. When it notices a procedure the project will need again, it writes a skill: a plain SKILL.md you can read and edit, in the repository's .agents/skills/ (or your own, for a personal one), and a node in memory so a later session can find it by purpose. When a skill fails, it rewrites it and keeps the old version.
create_skill saves a procedure the project or you will need again: a lowercase-with-dashes name, a description that says when to use it (that is how it is found later), and the steps, commands and pitfalls in Markdown. A project skill goes in the repository's .agents/skills/<name>/SKILL.md; a personal one in Mnemo's home.
Every skill is also a procedural node in memory, so a later session can recall that the skill exists, and why, from a question that never names it.
When a skill fails, update_skill rewrites it and says what went wrong with the old version. The previous body is kept under skill-history/.
SKILL.md files in .claude and .agents folders, walked up to the repository root, load as well. /skills lists them and /reload picks up changes without a restart.
mnemo memory curate sorts skills by last use: stale after 30 days, archivable after 90. With --apply a personal skill moves to skills-archive/, where nothing is lost but it is no longer loaded. A project skill belongs to the team: it is reported, never moved.
---name: run-checksdescription: Use before calling a change done in this repo.---1. pnpm typecheck2. pnpm test --runInBand (in parallel they fight over the dev server port)3. Report what failed, with the command that showed it.
v2update_skill, reason: tests hung on the dev server port. v1 is kept in skill-history/.
An example skill. Skills from .claude and .agents folders load too, and /skills lists what it can use.
05 it checks its work
It runs the project's checks before it calls a change done, moves to a stronger model when they keep failing, and can race several attempts and keep the smallest one that passes.
A run that changed code and ran nothing is sent back once, to run the project's checks: the test, typecheck, lint and build commands memory knows for this project. A change is checked before it is called done.
With --escalate provider/id, after the checks fail twice the rest of the run moves to the stronger model, and a note in the transcript says why. The cheap model does the work it can; the expensive one only finishes what it could not.
mnemo -p "<task>" --best-of 3 --check "npm test", or /bestof in the interface, runs attempts in separate git worktrees, runs the check in each, and applies the smallest change that passed. Every candidate's diff is kept, and if none passes nothing is applied.
mnemo -p "<task>" runs one task and prints the answer, which suits scripts and CI. It never asks, so run it in a container or a throwaway checkout.
A run that changed code and ran nothing is sent back once to run the project's checks.
--escalate provider/id finishes a run on a stronger model after two failed checks.
/bestof or --best-of 3 --check "pnpm test": three attempts in separate worktrees; the smallest passing change is applied.
06 many agents, one window
Yes, and they can work as a team. ctrl+n starts another agent on this project, ctrl+g opens the hub, ctrl+s splits the screen (up to four), ctrl+p switches project, and a toast tells you when one you are not watching finishes or needs you. Link two agents and they message each other on their own, within limits you can see.
ctrl+n starts another agent on this project, with its own session. Agents on the same project share one memory, so what one learns, the others recall.
ctrl+g shows a card per agent: its status, its last prompt, and one pixel per turn, so a glance says which one is busy, idle or waiting on you.
ctrl+s puts up to four agents side by side, each with its own transcript and prompt, in columns, rows, a grid or main + side (alt+l). A sub-agent that starts while its agent is on screen takes a pane by itself.
An agent can start sub-agents, and they can start their own, three levels deep. Press l on two cards in the hub to link them as siblings: they see what the other is doing and message each other. A message wakes an idle agent, which reads it and can answer on its own, and the conversation marks it ✉ as another agent's words, not yours. Links are remembered, so two projects you linked are linked again when both are open.
In a split, alt+, and alt+. move through every pane, sub-agents included. A focused sub-agent pane has a prompt: what you type reaches it after its current step, as your words. esc goes back to the agent.
Agents answering each other stop after 12 messages in a row since you last spoke, and turns that messages start may spend $0.50 per agent until you prompt it again. Past either, messages wait for you, and the hub card says so. A woken agent's edits and commands still ask you, as any turn does.
ctrl+y shows every agent, sub-agent and message between them, live, to watch only. c shows the selected agent's exchange with another as a thread, and enter takes you to the agent.
ctrl+p switches project. Memory is kept per project, so a command learned in one repository is not offered in another.
When an agent you are not watching finishes or needs an answer, a toast says which one, so a long run never waits on you unnoticed.

Every agent and what it is doing, one pixel per turn. Hover here and press g, s or t.
07 permissions
By default it asks before every edit and command. Four modes set how much it may do on its own, and ordered allow / ask / deny rules in ~/.mnemo/permissions.json hold in all of them. The gate filters what runs; it is not a sandbox.
Rules in ~/.mnemo/permissions.json say allow, ask or deny for a tool and a pattern. A deny holds in every mode, /yolo included, with or without a terminal: “stop asking” is a statement about questions, not about permissions.
Approving git status --short “always” covers git status*, never git*, which would also hand over git push and git clean -xdf. Arguments never generalise: a path is not a class.
ls; rm -rf / matches an approved ls* and must not use it. Anything with a shell metacharacter is its own question.
There is no fallthrough that quietly allows. Plan mode refuses every change and tells the model to describe it instead. Sub-agents and programs in the Python kernel go through the same gate, and you still answer for every edit and command they make.
Commands run as you and inherit your environment, provider keys included, which a prompt injection could try to read. Use /yolo and headless -p in a container or a throwaway checkout.
Asks before every edit and command.
| The agent wants to | Tool | In /default |
|---|---|---|
read src/fetch.ts | read | runs |
edit src/fetch.ts | edit | asks you |
pnpm test | bash | asks you |
a command your deny rules match | bash | refused |
08 what it can use
The usual coding tools, plus memory it can search and correct, skills it can write, a Python kernel that can drive the other tools in parallel, and sub-agents it can hand work to.
ipy_run runs Python in a persistent kernel whose state survives between calls. Inside it, tools.read(), tools.bash() and tools.grep() call the agent's tools, and tools.parallel([...]) sends a whole batch at once: one program instead of a dozen round trips.
spawn_subagent hands a self-contained task to a child agent: read-only for research, or full to edit. The child gets a brief the parent wrote, the parent's model, and the same memory, so what it learns the parent can recall. Its steps stream into the parent's tool block, delegation is limited in depth, and you still approve its edits and commands. If its model call fails, the tool says why.
memory_search and session_search look things up; memory_remember keeps a durable fact; memory_steer says that something memory supplied was wrong, so it is trusted less next time.
create_skill and update_skill, described above, plus the coding tools every turn uses: read, edit, write, bash and grep, each through the permission gate.
memory_searchsession_searchmemory_remembermemory_steercreate_skillupdate_skillipy_runspawn_subagentlist_agentsmessage_agentcode_search · code_symbol · code_refs · code_mapask_userread · edit · write · bash · grepmemory
memory_search
Search long-term memory for this project and user: conventions, past sessions, pitfalls and their fixes, lessons, skills.
09 detachable memory
Yes. mnemo memory setup claude-code prints the hooks and MCP entry that give Claude Code (or Codex) the same memory, and mnemo memory ingest learns from the Claude Code sessions you already have. What one agent learns, the others recall.
mnemo memory setup claude-code prints the hooks and the MCP entry to add to Claude Code (or Codex). Nothing is changed for you: you see exactly what goes where.
At session start Claude Code gets the project and user profiles and the last session, again after /clear, resume and compaction, so memory survives a compaction. On each prompt it gets what search finds: pitfalls with their fixes, earlier sessions, skills. When it stops, the session is reflected on and learned, in the background.
The same memory is offered as MCP tools: memory_recall, memory_search, memory_remember and session_search.
mnemo memory ingest replays the Claude Code sessions already on your disk through the same loop Mnemo runs live, so a session worked by a frontier model teaches the memory a cheaper model will use. Each memory keeps where it came from.
$ mnemo memory setup claude-code$ mnemo memory ingest10 commands
Type / in Mnemo for every command: these built-ins, your skills, and whatever the agent's extensions add. Try it here.
/memorywhat Mnemo remembers · /memory <words> searches it/remembertell Mnemo something to keep: /remember we deploy with fly/forgetretire a remembered fact: /forget package manager/bestofrace N attempts at a task, keep the smallest that passes: /bestof 3 "npm test" <task>/skillsthe skills Mnemo can load/modehow much Mnemo may do without asking (default, accept-edits, plan, yolo)/plantoggle plan mode (read-only)/accept-editstoggle accept edits: change project files without asking, still ask before commands/yolotoggle bypass: ask for nothing (deny rules in permissions.json still hold)/modelchoose the model/thinkingset how hard the model thinks/loginadd a provider (API key or subscription)/logoutremove a provider's credentials/themethe look: Mnemo Night, Dracula, Nord, Gruvbox, Tokyo Night, Catppuccin, Synthwave, Amber CRT, Game Boy, Paper, Solarized/resumecontinue an earlier session in this folder/rewindgo back to before an earlier message: the conversation, the files, or both (esc esc)/newstart a fresh session/compactsummarise the conversation to free context/costtokens and spend for this session/statsthis session, the last 7 days, and how the tools fared/reloadreload skills, prompts and extensions/clearclear the screen (the session is kept)/updateinstall the latest Mnemo · /update auto on|off: a daily check that only tells you/mousemouse wheel scrolls the conversation (on) or your terminal selects text (off)/helpcommands and keys/quitleave Mnemo11 the interface
Because a long session should be pleasant to watch. Mne the elephant reacts to the work, diffs and test runs are drawn as pixels, and /theme switches between eleven palettes that keep the same roles: magenta for the agent, cyan for structure, amber for anything memory did.
files
src/fetch.ts M
memory
◆ http helper
◆ language
▊ add a retry to the fetch helper
● edit src/fetch.ts
+ for (let attempt = 1; ; attempt++) {- const res = await fetch(url);
│ Done: server errors retry up to three times.
◆ +2 learned
defaultdemo-model
12 what we measured
On a small, cheap model (DeepSeek v4.1 Flash), through the same agent loop with memory on and off: from 87% to 100% on a six-task repository and from 82% to 99% on two repositories with conflicting rules. On unrelated one-off tasks it made no difference. Small samples: read the direction, not the decimals.
The last row is the honest one: unrelated tasks in a fresh container give memory nothing to remember (about $0.008 a task either way), and it is a subset on our own machine, not comparable to the public leaderboard. Against a simpler, global memory in the style of Hermes Agent, Mnemo matched it at one or two repos and was ahead where it keeps projects apart and picks up unfinished work. Raw results: research/, hermes-comparison.md.