~ ❯ cat blog/one-memory-for-every-agent.md
One memory for every agent
Run enough coding agents and you notice how much each one starts from zero. The Claude session you open after lunch doesn’t know the test database needs seeding first. The Codex session reviewing a branch doesn’t know you decided, two days ago, that form state belongs in a hook and not the page. You end up retyping the same context, or pasting it from a notes file, or watching an agent rediscover something the last one already worked out.
Every agent CLI has some answer to this, and each answer lives inside that agent: its own memory file, its own project instructions, its own format. That’s fine if you use one agent. We don’t. We move work between Claude and Codex several times a day, run them side by side on different workstreams, and try new CLIs as they come out. Memory that belongs to one agent doesn’t survive any of that.
So wrkstrms keeps memory itself, in one place every agent shares.
What’s in it
Each item is a short piece of Markdown with a kind:
- facts about the code or setup: “Run
bin/setup_dbbefore the specs” - decisions and why they were made: “Form state lives in
useCheckoutForm” - preferences for how you like things done: “Small PRs, one feature each”
- tasks: where a piece of work stands
- handoffs: what was done, where things are, what’s next, what’s still open
Items are scoped to where they apply: the whole machine, a repo (by its
origin, so every clone and worktree shares them), a workspace, a
workstream or a project. It’s all one SQLite file on your machine, readable
only by you. ws never sends it anywhere.
You can add to it by hand:
ws mem add "Run bin/setup_db before specs" --kind factws mem add --kind preference --scope global "Small PRs, one feature each"ws mem search setup dbMostly, though, it fills itself.
How agents get it
At the start. When ws starts an agent, or you start Claude Code or Codex
yourself in a pane, the agent gets a context pack: a short Markdown summary of the memory
that applies where it’s running. Pinned items and preferences come first,
then decisions and facts, current tasks, the latest handoffs and the last few
sessions in this repo. It’s capped at a token budget, 1,500 by default, and
every item carries an id the agent can look up for more detail. It comes
again after /clear and after compaction, the two moments an agent would
otherwise forget.
While it works. ws mcp serves memory over MCP, so any agent that speaks
it can search memory and save to it as it goes. One command per agent sets
that up:
ws integrate claude --mcpws integrate codex --mcpWhen it stops. ws already hears every agent’s lifecycle hooks, because that’s how it shows who’s blocked, working or done. It uses the same events to record each session: the agent and model, the first and last prompt, the commits made and the uncommitted change. When a session in a workstream ends after doing something, ws writes a handoff for the next agent there.
You stay in charge of what’s shared
An agent that writes to memory is making a claim on every future session, so not every write goes straight in.
Working notes in an agent’s own workstream or project are saved at once.
Anything shared, for the repo, a workspace or globally, is only proposed.
It waits until you approve it, and until then no other agent is told about
it. The top bar shows how many are waiting, and the memory panel (prefix y)
lets you read each one with who wrote it, from which session and commit, and
approve or reject it with a key.
Secrets are redacted before anything is stored: GitHub, OpenAI, Anthropic,
AWS and Slack tokens, JWTs, private keys, NAME=value lines whose name says
secret, token, password or API key, and long random-looking strings. An item
that’s mostly secret is refused.
⌃␣ y: everything agents are told about this repo. The Proposed tab holds what waits for your approval.
Moving work between agents
The part we use most is the handoff. prefix A on a pane, or ws handoff
in it, opens the same work in another agent:
ws handoff --to codexws handoff --to claude --model opus --replaceThe new agent starts with the usual context pack, headed by a section on what came before: the last agent’s first and last prompt, its commits, the uncommitted change, its handoff and a path to its transcript. Its first prompt tells it to check the current state and carry on. Switching agents stops meaning starting over.
Going back works too. Hand the work from Claude to Codex and later back to Claude, and ws resumes Claude’s own earlier session instead of starting a new one, then tells it only what happened since its turn: what the other agents were asked and handed off, the commits made since, and what was added to memory. If Claude is still open in its pane, the update is typed right into it.
Which agents get context, how big a pack can be, and the summarizer are all
on one page of Settings (⌃␣ S), and changes save as you make them:
What’s next
Memory is the part of wrkstrms we expect to change the most. There’s already an opt-in summarizer that turns a finished session into a summary and a few proposed facts, using a model you choose, local or hosted, and off until you turn it on.
The memory guide covers all of it, from the item format to where the file lives.