Wife

remembers everything

Local, persistent and auditable memory layer for Claude Code and Codex.
Your agent stops treating you like a stranger every morning.

WhyWhat it doesInstallHow it worksCommandsSecurityFAQ


$ wife show

Identity (5 facts)
  Who
  - Full-stack developer, mostly backend
  - Ships side projects solo, nights and weekends
  Preferences
  - Prefers short, implementation-first answers
  - Dislikes long explanations of things already known
  Working style
  - Always answer in Spanish
  █░░░░░░░░░░░░░░░░░░░░░░░ 61/1200 tokens

Project · checkout-api (3 facts)
  Stack
  - Uses Postgres, Fastify and Vitest
  Conventions
  - Never commit directly to main
  - Run the migrations before the test suite
  ░░░░░░░░░░░░░░░░░░░░░░░░ 27/800 tokens

Injected at session start
  ██░░░░░░░░░░░░░░░░░░░░░░ 174/2000 tokens

That block is handed to Claude Code and Codex at the start of every session. You never typed it. Wife learned it from things you already said, and it forgets anything you delete.


Why

You explain your stack. You explain that you want short answers. You explain that this repo runs migrations before tests. The session ends.

Tomorrow, you explain all of it again.

That is not a context-window problem — a model handles one session fine. The problem is that nothing survives the session boundary, and nothing ever learns. Instruction files are documents you maintain by hand. Session resume only reaches backwards into a single conversation. Compaction throws away the parts of a session it judges irrelevant to the current task, which is exactly where facts about you live.

Wife closes that gap with the only thing that actually works: a curator.


What it actually does

Storing text is trivial. The hard part — the entire product — is deciding what deserves to be remembered, what replaces what, and what has to go.

It waits before it believes you

A fact you mention once is staged, not stored. It has to come back in a different session before it reaches long-term memory. State it deliberately — remember that…, always…, never…, or wife remember — and it lands immediately, because you meant it.

This single rule is why Wife's memory stays small enough to trust.

It has a hard ceiling

1200 tokens for who you are. 800 for the current project. When a section fills up, the lowest-scoring fact is evicted, not appended.

score = confidence × recency × repetition × intent

Recency decays on a 90-day half-life for identity, 45 days for project memory. Pinned facts never decay and are never evicted. The ceiling is the design: without it, memory grows until it costs you tokens on every single turn.

It resolves contradictions instead of stacking them

Move off a framework and the old fact is replaced, with the change recorded. Restate something more precisely and the vaguer version is absorbed.

Two statements only merge when one strictly contains the other:

Statement A Statement B Result
Prefers short answers Prefers short direct answers merged — B is more specific
Deploys to production on Friday Deploys to staging on Friday kept apart — each says something the other does not
Uses Postgres Uses MySQL kept apart
Uses Redis Never uses Redis superseded — you changed your mind

It lets go of what you stopped believing

Contradict a fact and it is replaced on the spot. But most beliefs don't die that cleanly — you just quietly stop working that way, and never say so.

Go quiet about something for long enough and it goes dormant: out of the injected context, still visible in the file under ## Dormant. Say it again and it comes straight back. Delete the line and it's gone for good.

## Dormant
_Not mentioned in a long time, so these are no longer sent to the agent._
_Say one again and it comes back. Delete the line to forget it for good._
- Uses Redis for caching

120 days for identity, 60 for the project, doubled for anything you stated deliberately. Pinned facts never go dormant — that's what pinning is for.

It notices what follows you between repos

Say "never commit directly to main" in one codebase and it's a house rule. Say it in your last three codebases and it's how you work. At three repos, a project fact is promoted into identity automatically, where it follows you everywhere.

wife spread shows what's on its way there.

It follows you between machines

Push your memory folder to a private repo and it works — right up to the day you use two machines in the same week. Then git hands you a text conflict in a file full of facts and asks you to pick a side, and every side loses something.

wife sync setup git@github.com:you/wife-memory.git   # once, per machine
wife sync                                            # commit, merge, push
wife clone git@github.com:you/wife-memory.git        # set up a new machine

Facts are content-addressed and carry their own provenance, so they merge by meaning rather than by line:

Situation What happens
Same fact on both machines sessions are unioned, latest sighting wins
Only on one, and it was in the ancestor the other machine deleted it — deletion wins
Only on one, and it is new kept
Contradiction across machines the newer statement wins, the old one is dropped
Candidate waiting on both sessions merge — the two-session gate now spans machines

That last row is the quiet win: say something once on the laptop and once on the desktop, and it is finally enough to be remembered.

None of this is limited to two machines. Seven laptops converge as cleanly as two. And sessions/ is git-ignored, so raw prompts never leave the machine they were typed on.

It enforces what can be enforced

Injected text is a suggestion. The agent almost always follows it. Almost is not a guarantee — and for some rules that gap matters.

wife harden

Wife ships with no rules of its own. A fresh install has an empty memory and zero guards; everything below comes from things you said. wife harden scans your rules for the ones an agent hook can actually enforce, shows you each one, and turns on only what you approve.

If you happened to have written these, here is what it would offer:

A rule of yours What the guard would do
Never commit directly to main block git commit while you are on main, allow it on a feature branch
Never force push block --force, still allow --force-with-lease
Don't use npm, use pnpm block npm install, leave pnpm alone
Never rm -rf block recursive deletes, allow deleting one file
Don't touch .env block edits to .env, not to environment.ts

Those shapes — git, package managers, deletes, protected files — are the ones recognised automatically because they are what people repeat most. They are not everybody's list, so any rule can be enforced directly:

wife guards --add "Never terraform apply against prod" --blocks "terraform apply"
wife guards --add "Don't touch prod config" --blocks "config/prod" --tool Edit
wife guards --add "No commits on release" --blocks "git commit" --on-branch release

wife guards --test "terraform apply -auto-approve"   # see what would happen

The rule stays in memory too, and that is deliberate: the guard stops the action, the memory stops the attempt. Without the memory the agent tries the forbidden thing and eats the block every round — deterministic, and a wasted turn each time.

Three constraints this is built under. Nothing is ever enforced without you approving it one rule at a time, because a guard invented from a sentence you never meant as a hard rule blocks work you asked for. A description is never a guard: Uses pnpm states a preference and blocks nothing, only Never use npm does. And guards fail open — a broken pattern allows the call, because a bug that blocks every command is far worse than a rule that missed once.

Most of what Wife knows maps to no tool call at all — tone, language, what you prefer to see first — so it stays as context by design. PreToolUse is only registered once you have a guard, so with none there is no hook in the path of your work.

It only reads what you wrote

Your agent's replies are never mined. When a model suggests "let's use Postgres" and you answer "ok", it has not learned a fact about you — it has heard its own idea repeated back. Wife reads your prompts and nothing else.

It separates you from your repo

Facts about you follow you everywhere. Facts about this codebase stay in this codebase.

"always answer in Spanish"           →  identity      (follows you to every repo)
"never commit directly to main"      →  checkout-api  (stays here)
"I never deploy on Fridays"          →  identity      (your habit, not the repo's)
"this project uses Fastify"          →  checkout-api

Every single fact is traceable

$ wife why "short answers"

Prefers short, implementation-first answers
  store       identity · section "Preferences"
  source      it came up in enough separate sessions to be promoted
  confidence  0.75
  seen        3 times across 3 sessions
  first       2026-07-14 09:22:41
  last        2026-07-29 18:03:12
  score       0.847 (confidence x recency x repetition x intent)
  you wrote   "prefiero respuestas cortas, sin tanta explicación"

If you cannot see where a memory came from, you cannot trust it. Wife shows you.

It is a markdown file you own

~/.wife/identity.md is the source of truth. Open it in any editor. Delete a line and it is forgotten — no command needed. Add a line by hand and it is kept at full confidence. git init it if you want history.

No database. No daemon. No account. No network call. Ever.


Install

Option 1 — let your agent do it

Copy this and paste it into Claude Code or Codex:

Install "Wife", a local memory layer for coding agents, from
https://github.com/ma-nucho-pro/wife

Do exactly this:
1. git clone https://github.com/ma-nucho-pro/wife.git ~/.local/share/wife
2. cd ~/.local/share/wife
3. npm link          (this puts the `wife` command on my PATH)
4. wife init
5. wife attach claude          (use `wife attach codex` if you are Codex)
6. wife status                 and show me the output

Do not modify any of my existing hooks or settings beyond what
`wife attach` does. It merges into my settings file without
removing anything. If `npm link` fails with a permission error,
tell me instead of using sudo.

Then restart your agent. That is it.

This repo ships a CLAUDE.md and an AGENTS.md, so if your agent is already sitting inside the cloned folder it knows how to install itself without any prompt at all.

Option 2 — one command

curl -fsSL https://raw.githubusercontent.com/ma-nucho-pro/wife/main/install.sh | bash

Option 3 — by hand

git clone https://github.com/ma-nucho-pro/wife.git
cd wife
npm link          # puts the `wife` command on your PATH
wife init         # creates ~/.wife and attaches whatever it finds
wife attach claude

On Windows, use Option 3 in PowerShell — the install script needs bash.

Requires Node 18.17 or newer, which you already have if you are running Claude Code. There is no build step and zero runtime dependencies: the whole tool is plain Node with nothing pulled from npm.

Already have a CLAUDE.md? Start from it.

wife import          # --dry-run to see it first

Reads ~/.claude/CLAUDE.md, ~/.codex/AGENTS.md, and this repo's CLAUDE.md or AGENTS.md, and seeds memory from them. The scope of the file decides the scope of the fact: your user file becomes identity, the repo's file becomes project memory.

Credentials are screened out before anything is written, code blocks and install steps are ignored, and Wife never re-reads its own managed block.

Check it worked

wife status

Then open a new session. In Claude Code, /hooks will list three entries. Nothing else about how you work changes.

Uninstall

wife detach claude
wife detach codex
rm -rf ~/.wife        # only if you also want the memory gone

detach removes Wife's hooks and leaves every other hook in your settings exactly as it was.


Which agents, and how far

Not every agent exposes the same lifecycle, so this is exactly what each one does.

Injects memory Learns from your sessions Enforces guards
Claude Code SessionStart UserPromptSubmit + SessionEnd PreToolUse
Codex SessionStart UserPromptSubmit + Stop PreToolUse
Cursor rules file, rewritten at stop beforeSubmitPrompt + stop beforeShellExecution
Gemini CLI GEMINI.md no no
wife attach claude
wife attach codex
wife attach cursor
wife attach gemini

All four read the same memory, so a fact learned in Claude Code shows up in Codex.

Codex needs hooks, which went stable in v0.124.0. wife attach codex also enables [features] codex_hooks for older builds and writes an AGENTS.md block as a fallback for versions predating the hook engine entirely.

Cursor has no session-start event whose output becomes context, so memory is injected through an always-applied rule at .cursor/rules/wife-memory.mdc, rewritten by the stop hook at the end of every session. The loop still closes; it is just one session behind on facts learned minutes ago.

Gemini CLI gets injection only. Its hook engine exists, but wiring to an event name this integration cannot verify would fail silently — the worst outcome for a memory tool — so GEMINI.md it is. Refresh with wife sync-gemini, or let a Claude Code or Codex session on the same machine keep the store current.

Blocking works differently in each: Claude Code takes a permissionDecision, Codex wants exit code 2, Cursor wants { permission: "deny" }. Cursor also names things differently — conversation_id and text where the others send session_id and prompt. All of that is handled, and tested against each agent's documented payload.

How it works

Three hooks. No wrapper around your agent, so your workflow is untouched.

SessionStart      →  wife inject     puts your memory into the session
UserPromptSubmit  →  wife capture    buffers what you typed, silently
SessionEnd        →  wife harvest    curates the session into memory

The curator runs in four steps:

      what you typed
            │
   1. extract      pattern rules, Spanish and English,
            │      tuned to miss rather than to invent
            ▼
   2. gate         explicit? store now.
            │      otherwise stage it and wait for a second session
            ▼
   3. reconcile    reinforce · supersede on contradiction · add
            │
            ▼
   4. prune        enforce the token ceiling, lowest score first
            │
            ▼
     identity.md + projects/<repo>/project.md

Extraction is deterministic pattern matching, not an LLM call. No API key, no cost per session, no network, and behaviour you can read in one file and predict. It fires on the phrasings people actually use when stating something durable — recuerda que, siempre, nunca, prefiero, no uses, usamos, me llamo, and their English equivalents — and throws out anything that is a question, a task, code, a path, a URL, a pasted log, or a credential.

Facts are written in the language you said them in. Spanish in, Spanish out.

Crash safety. If your agent is killed, your laptop dies, or SessionEnd never fires, the buffer is picked up at the next SessionStart. Session buffers are the only place raw prompt text is written, and they are deleted the moment they are harvested.

The injected block reads as plain factual statements, never as commands, so it is used as context instead of being flagged and surfaced back to you.


Commands

Memory

Command What it does
wife import seed from your existing CLAUDE.md / AGENTS.md — --dry-run
wife review decide what stays: waiting candidates and dormant facts
wife spread facts showing up in more than one repo
wife harden turn rules a hook can enforce into real guards
wife guards what is enforced — --add … --blocks …, --test …, --off …
wife remember "<fact>" store it now — --project, --section X
wife forget "<text>" remove it entirely
wife pin "<text>" exempt from decay and eviction
wife unpin "<text>" undo that
wife why "<text>" where it came from and what it replaced
wife edit open the memory file in $EDITOR--project

Inspect

Command What it does
wife show exactly what your agent will be given — --raw, --verbose
wife status memory size, wiring, pending buffers
wife journal audit trail of every change — -n 50, --event added
wife doctor duplicates, drift, broken wiring — --fix
wife config [key] [value] read or change settings

Setup

Command What it does
wife init create ~/.wife and attach whatever is installed
wife attach <agent> claude · codex · cursor · gemini--project
wife detach <agent> remove it cleanly
wife sync-gemini refresh the Gemini block
wife sync setup <url> wire ~/.wife up to a private git repo
wife sync commit, merge the other machines in, push
wife sync status how far this machine has drifted
wife clone <url> set up a new machine from your memory repo
wife sync-codex refresh Wife's block in AGENTS.md

Lifecycle

wife inject, wife capture and wife harvest are what the hooks call. You rarely run them by hand, though wife harvest --verbose is the best way to see what the curator accepted and why it rejected the rest.


Security

Wife reads every prompt you type. That is only acceptable under strict rules, so here they are.

Credentials never reach disk. Anything matching a credential shape disqualifies the entire candidate — it is dropped, not masked, because a masked fact still leaks its context.

Screened Examples
Provider keys sk-…, sk-ant-…, ghp_…, AKIA…, AIza…, xox…, sk_live_…
Tokens JWTs, Bearer …, Authorization: headers
Secrets in assignments password=, api_key=, secret=, token=
Connection strings postgres://user:pass@…, mongodb+srv://…, redis://…
Key material -----BEGIN … PRIVATE KEY-----
Entropy long hex digests and high-entropy base64 blobs

Add your own with wife config denyPatterns '["client-name","internal-codename"]'.

Nothing leaves your machine. No telemetry, no analytics, no network calls, no accounts. ~/.wife is a folder of markdown and JSON on your disk.

Raw prompts are transient. They live in a session buffer only until that session is curated, then the buffer is deleted.

Everything is reversible. wife forget removes a fact completely. Deleting a line from identity.md does the same. The journal records that a removal happened and when, never resurrecting the content.

Pause it whenever you want: wife config capture false stops learning while still injecting what it already knows.


Architecture

~/.wife/
  identity.md            you. hand-editable, the source of truth
  identity.index.json    confidence, seen counts, provenance
  projects/
    checkout-api-a1b2c3d4/
      project.md         this repo. same rules
      project.index.json
      meta.json
  sessions/              prompt buffers, deleted once curated
  cross-project.json     which facts have shown up in more than one repo
  journal.jsonl          append-only audit log
  config.json

The .md files are what you read and edit. The .json sidecars hold metadata that has no readable place in a bullet list.

Markdown always wins. On every load Wife reconciles the index against the file, so a line you delete by hand is forgotten and a line you add is adopted at full confidence. You are never fighting the tool for control of your own memory.


Configuration

wife config                              # show everything
wife config budget.identity 2000         # more room for who you are
wife config promotionThreshold 3         # be even more sceptical
wife config halfLife.project 30          # project facts go stale faster
wife config denyPatterns '["acme-corp"]' # never store anything matching this
wife config capture false                # pause learning, keep injecting
wife config dormancy.identity 180        # be slower to let go of who you are
wife config crossProjectThreshold 2      # promote to identity sooner

FAQ

Does this send anything anywhere? No. There is no network code in this repo outside of git clone during install. Memory is markdown on your disk.

Does it cost tokens? About 150–250 tokens per session, once, at the start. That is roughly what you spend re-explaining your stack in a single message.

Does it need an API key? No. Extraction is pattern matching, not a model call.

What if it remembers something wrong? wife forget "<text>", or open ~/.wife/identity.md and delete the line. Both are permanent.

What if it misses something important? wife remember "<fact>" stores it immediately at full confidence. Saying remember that… or always… in a normal prompt does the same thing.

Isn't a rule in a prompt just a suggestion? For some rules, yes, and that is a fair criticism. wife harden finds the ones a hook can enforce and turns them into PreToolUse guards you approve one by one. The rest — tone, language, preferences — correspond to no tool call, so a hook cannot express them either way.

What happens to something that stops being true? Three ways out. Contradict it and the old fact is replaced immediately, with the change recorded. Say nothing for long enough and it goes dormant — out of the context, still in the file, revived the moment you mention it again. Or delete the line yourself. Nothing silently rots.

Can I use it on several machines? Yes, and properly. wife sync setup <private-repo-url> on each machine, then wife sync. Memory merges by meaning rather than by line, so two machines that both learned things in the same week end up with everything, not with one of them winning. There is no two-machine limit.

Does it work with both Claude Code and Codex at the same time? Yes. Both read the same memory, so a fact learned in one shows up in the other.

Can I edit the memory by hand? That is the intended way to use it. The markdown file is the source of truth and your edits always win.

Which languages does it understand? Spanish and English out of the box, and it writes each fact back in the language you said it in. Adding a language is a rule block in src/core/extract.js — pull requests welcome.


Verify it yourself

npm run check

247 unit tests, a 78-check end-to-end run, a 67-check multi-agent run, and a 55-check multi-machine convergence run using real git that spawns the real CLI and feeds it the exact JSON Claude Code puts on a hook's stdin. Among the things it proves:

  • a credential pasted into a prompt never appears anywhere under ~/.wife
  • a task ("fix the login bug") never becomes a memory
  • a preference stated once is not stored; stated again in a different session, it is
  • attaching over an existing settings file preserves every other hook and setting
  • attaching three times produces three handlers, not nine
  • every hook command exits 0 given no stdin, garbage stdin, a null prompt, a 500 KB prompt, or a session id of ../../../etc/passwd
  • a corrupt index file is quarantined and recovered from instead of crashing
  • a buffer from a session that never ended is picked up at the next start
  • the CLI works through npm's real platform launcher (wife on POSIX and wife.cmd on Windows), not just as a direct file
  • a credential inside an imported CLAUDE.md is dropped, underscores and all
  • a fact gone quiet for months stops being injected but stays in the file
  • saying a dormant fact again revives it, back to its original section
  • one repo repeating itself never triggers cross-project promotion; three do
  • three machines diverging in parallel converge to an identical set of facts
  • a fact deleted on one machine stays deleted on the others after a sync
  • a candidate seen once on each of two machines is promoted, exactly as it would be within one
  • a description ("Uses pnpm", "Deploys on Thursdays") never becomes a blocking guard
  • a commit guard blocks on main and allows the identical command on a feature branch
  • a malformed guard pattern allows the call instead of throwing
  • PreToolUse is not registered at all until a guard exists
  • Codex wires Stop, not SessionEnd — Codex has no such event, and a hook on a name that does not exist never fires and never says so
  • Cursor's conversation_id / text payload is understood, and Cursor gets an explicit allow rather than silence
  • a Codex guard denies with exit code 2, not with a JSON decision object
  • attaching to Codex three times leaves one codex_hooks = true, and the rest of your config.toml untouched, blank lines included

CI runs the whole suite on Linux, macOS and Windows across Node 18, 20 and 22.


Author

Roberto Manuel Jara Peche

If Wife saves you from re-explaining yourself, a ⭐ on the repo helps other people find it.