Skip to content

About

Persistent memory for Claude Code — identity, context, and continuity across sessions

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

195 stars

Watchers

4 watching

Forks

Latest commit

 

History

563 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Continuous Memory for Your Coding Agent

claude-remember — continuous memory for your coding agent

Tests Python OS License Claude Code Codex Antigravity Version Stars clones

Your coding agent starts every session blank. It doesn't know what you worked on yesterday, what conventions your team follows, or what mistakes it already made. You re-explain everything, every time.

Claude Remember fixes that. It hooks into your coding agent's lifecycle — saving sessions automatically, compressing them through Haiku into layered daily summaries, and loading them back into context on the next session start. No manual prompting, no copy-pasting notes. The agent starts every session with its history already present.

The result: your coding agent develops continuity. It remembers what it learned, what broke, what worked. Not perfect recall — compressed, practical memory that fits in minimal tokens.

How it works

flowchart TD
    A["tool use"] --> B["save-session.sh"]
    B --> C["extract (Python)"]
    C --> D["summarize (Haiku)"]
    D --> E["now.md"]
    E --> F["hourly NDC compression"]
    F --> G["today-YYYY-MM-DD.md"]
    G --> H["daily consolidation"]
    H --> I["recent.md + archive.md"]
Loading

Each layer compresses the one above it. Raw exchanges become one-line summaries. Daily summaries become weekly paragraphs. The result: full context in minimal tokens.

On session start, the SessionStart hook automatically injects into your coding agent's context:

  • identity.md — who the agent is
  • remember.md — the handoff note from the last session
  • now.md — current session buffer
  • today-*.md — today's compressed history
  • recent.md — last 7 days
  • archive.md — older history
  • archive-YYYY-MM-DD.md / recent-YYYY-MM-DD.md — rotated slices of a previously oversized archive or recent span; named at session start and searchable, but not injected into context

No manual prompting, no "read this file" instructions. The agent begins every session with its memory already loaded. It just remembers.

After a compaction only identity.md is re-injected; the rest was already delivered. Write rules for the store: docs/how-memory-files-are-written.md.

From the same workshop

Four plugins, one team, each does one thing. This one and three siblings:

  • claude-jit-context: project knowledge that loads only when the prompt, the file or the tool matches it.
  • claude-supertool: batched file and tracker ops. One call instead of seven, and a refusal instead of a wrong answer.
  • claude-oss: the maintainer loop that runs these four repos. Triage, build, review, merge, release.

All four install from one marketplace: /plugin marketplace add Digital-Process-Tools/claude-marketplace.

Once in a while, SessionStart names whichever of claude-supertool / claude-jit-context you have not installed yet, in a single systemMessage line the model never sees. It never speaks for a plugin already in ~/.claude/plugins/installed_plugins.json, and it stops entirely with "features": {"plugin_promos": false} in config.json: see Configuring it. The line opens with claude-remember: and ends with that key, so both who spoke and how to stop it arrive with the message rather than only here (#631).

Install

Claude Code

/plugin marketplace add Digital-Process-Tools/claude-marketplace
/plugin install remember@dpt-plugins

Restart Claude Code afterwards; hooks are read at session start (#200). Updating, the official Anthropic marketplace and its lag, manual install, checking your version: docs/install-claude-code.md.

Codex

codex plugin marketplace add Digital-Process-Tools/claude-remember
codex plugin install remember

Observed working against codex-cli 0.150.1. What was found on the way: docs/install-codex.md.

Antigravity CLI (agy)

python3 scripts/install_agy_hooks.py

Observed working against agy 1.1.27: capture was driven end to end against a real agy process, not reasoned from its docs. Antigravity has no per-plugin manifest -- agy plugin install copies a plugin's own hooks.json, counts it, marks the plugin enabled, and never loads it (#553) -- so the installer merges a remember entry into the shared ~/.gemini/config/hooks.json, preserving every other plugin's entries already there.

One gap, before you choose this host: of the four Antigravity events confirmed to fire, none is a process-exit signal, so there is no analogue of SessionEnd and no last-chance flush at the end of a conversation. Stop fires after every turn and is deliberately not wired to session-end-hook.sh. What that costs, the name-keyed schema whose parse failures are silent, and the three live defects found while porting: docs/install-antigravity.md.

Requirements

  • Python 3.9+
  • Claude CLI (claude) with Haiku access
  • Bash 3.2+ (stock macOS bash is fine)
  • jq and standard coreutils, preinstalled on macOS and Linux

Windows

Needs a POSIX shell in PATH: Git Bash / MSYS2 with jq and python3 installed, or WSL. The OS badge is honest about the platform, not the coverage; most of the suite still skips on win32 (#497). Every real Windows defect so far was found by a user on a real machine, and those reports get priority. Known traps: docs/windows.md.

Cost

The pipeline uses Claude Haiku for summarization and compression. Haiku is the smallest, cheapest Claude model. A typical session save costs < $0.01 — a few thousand input tokens (the session exchanges) and a few hundred output tokens (the summary). Daily compression and consolidation add a few more Haiku calls.

In practice, running this all day costs a few cents per day. The Anthropic API key used by the Claude CLI is the same one that powers the calls — no separate billing.

Using it

Once installed there is nothing to run. Two commands are worth knowing.

Handoff between sessions (/remember)

Before clearing context or ending a session, type /remember. The agent writes a short handoff note; the next session starts with it loaded. How delivery is counted and what two sessions on one store do: docs/handoff.md.

Diagnostics (/remember:doctor)

Run it when memory is not appearing and nothing says why. It prints resolved paths, storage mode, and whether each hook has ever fired for this project. JSON output and the consolidation cap: docs/diagnostics.md.

Hooks

Claude Code / Codex Antigravity Script Purpose
SessionStart SessionStart session-start-hook.sh Loads memory into context, recovers missed sessions
UserPromptSubmit PreInvocation (per model invocation, not per prompt) user-prompt-hook.sh Stamps the current time into the prompt
PostToolUse not wired (PostInvocation fires, nothing here needs it) post-tool-hook.sh Saves the session when enough tool calls have accumulated
SessionEnd no analogue found session-end-hook.sh Flushes whatever PostToolUse has not saved yet

Antigravity's Stop is a turn boundary, not a teardown, so it is wired to its own adapter rather than to session-end-hook.sh; the row above is the gap that leaves.

What each one skips and why, the hooks.d/ listener contract, and why SessionEnd never writes a handoff: docs/hooks.md.

Configuring it

Defaults live in config.json inside the plugin; override them per machine in ~/.remember/config.json and per project in <REMEMBER_DIR>/config.json. Every key, its default and what reads it: docs/configuration.md. Keeping memory outside the project tree, in ~/.remember/<slug>/: docs/external-storage-mode.md. Backing the store up to a git remote you own: docs/git-backup-security.md.

Data files

Everything lands in REMEMBER_DIR: .remember/ inside the project by default, or ~/.remember/<slug>/ in external storage mode.

File Purpose
now.md Current session buffer
today-*.md Daily compressed summaries
recent.md Last 7 days consolidated
archive.md Older history consolidated
archive-YYYY-MM-DD.md, recent-YYYY-MM-DD.md Rotated slices, searchable, not auto-loaded
remember.md Handoff note written by /remember
identity.md Your agent's identity and values (you write this)
logs/, tmp/ Local to this machine, never backed up

Per-session handoff files, the session index, and the temp files tmp/ holds: docs/data-files.md.

Trust Model

This plugin runs with your full shell privileges, like any other hook your coding agent runs. The default install stores memory locally under <project>/.remember/ (or ~/.remember/<slug>/ in external mode) and does not push anything anywhere — no new attack surface beyond your coding agent itself.

Git backup commits (and, if there is a remote, pushes) your memory whenever the external store's parent directory is itself a git repository with an upstream — there is no separate enable flag; that condition alone is the trigger. Read docs/git-backup-security.md for the full threat model — short version: treat ~/.remember/ with the same care you give ~/.ssh/, point the backup at a repo you own, and the built-in remote-URL validation handles the rest.

What this plugin runs, sends and stores

Summarization shells out to a CLI you already have installed and authenticated — never a bundled binary, never a third-party service beyond the one that CLI already talks to:

  • REMEMBER_SUMMARIZER selects the provider: claude (the nested claude -p), codex (the nested codex exec), or auto (the default — reads the transcript the host actually wrote to pick one). REMEMBER_SUMMARIZER_FALLBACK=claude (opt-in, unset by default) retries a failed codex call via claude -p instead of raising, and logs every time it fires.
  • claude -p runs with no tools (--tools ""), no MCP servers (--mcp-config '{}' --strict-mcp-config), no hooks (--setting-sources ''), and an isolated temp working directory — not the shared tempdir other concurrent saves use. Verified against claude-code 2.1.219.
  • codex exec runs with --sandbox read-only (denies writes and network to the process Codex itself spawns — not a guarantee against a command the model asks Codex to run inside that sandbox), --ignore-user-config (skips the operator's own Codex hooks), and -c shell_environment_policy.inherit=none (a command Codex spawns internally gets no environment at all, not even PATH). Verified against codex-cli 0.150.1 / 0.153.2.
  • Either route sends only the extracted, filtered session transcript (the prompt built for that save) to that CLI's own configured provider — never to any other service.

Credentials. The summarizer runs a nested claude -p that inherits your environment, including your Claude Code login -- exactly like any process a hook starts; the nested codex exec gets only an allow-list of your variables that names no credential. remember itself reads no credential: nothing is typed in, nothing is read out of your OS credential storage, and the plugin does not ask for your login anywhere.

  • Most hosts simply hand that login to every tool and hook they spawn, this one included, and that is the whole story: nothing else to configure, nothing else this plugin does.
  • Before the nested call starts, only the parent session's own variables are removed, so it does not pass as that session (#95): the names are listed in docs/configuration.md. Your login is never on that list.
  • Some hosts do not hand hooks that login (an older desktop build, a hosted Agent SDK). When that happens the nested call simply runs unauthenticated: this plugin has no recovery path of its own, by design (#860, round 3) — reading any credential from your machine is exactly the condition a directory security scan holds on, independent of consent or provenance. Log in again with your coding agent's own CLI and the next save picks it up.
    • Two older ways of configuring a recovery token for this plugin — an environment variable, and a haiku.oauth_token key in config.json, both this plugin's own earlier and now fully removed attempts at the same feature — are no longer read at all, on any host, for anything, and a still-configured value is not detected or logged anywhere any more (#898, round 6): there is nothing left to migrate it to, and leaving it in place is harmless.
  • If you also happen to have an unrelated Anthropic API key set in your environment for something else, the nested call inherits it exactly like every other variable, and it can out-rank your login there (#703). To keep a variable like that away from the summarizer, unset it in the environment you start Claude Code from. (The haiku.drop_env list that used to do this inside the plugin was removed in #898: applying names chosen at run time meant walking your whole environment.)
  • The codex summarizer is the other way round: the nested codex exec gets only an allow-list of your variables (#724), because a command the model runs inside Codex's sandbox could read anything else. The list carries what the Codex CLI needs to run (PATH, HOME, CODEX_HOME, locale, temp and Windows process variables), no credential and no proxy or CA-bundle variable (#898): if you reach the network only through a proxy, set REMEMBER_SUMMARIZER=claude, whose nested call inherits your whole environment. Codex's own login in CODEX_HOME (what codex login writes) is unaffected; a Codex login held only in an environment variable is not passed through, so run codex login instead -- see docs/configuration.md. Both lists are written in the plugin's code, not read from config: changing either needs a plugin release, and no config file -- yours or a cloned repository's -- can change them.

git fetch (opt-in, git_restore.enabled in config.json, default false) runs a background fetch against the memory store's own git remote before a session starts, so this session can compare local memory against what a backup pushed from elsewhere. It only fast-forwards local refs — it never merges, rebases, or pushes.

Files written outside the project, beyond the REMEMBER_DIR memory store documented above:

  • ~/.remember/tmp/promo-notice — a marker recording when the plugin-promo line (above) was last shown and which one, so it appears at most once per cooldowns.promo_seconds (default 7 days) across all your projects.
  • ~/.remember/run/summarizers/ (override: REMEMBER_RUNTIME_DIR) — small per-process records used only to cap how many concurrent summarizer calls can run; holds no transcript content.
  • $TMPDIR/remember-* — most of these are temp files for a single save-session.sh run: the extracted transcript, the built summarization prompt (so some of these do hold session text), the summarizer's stderr, and compression intermediates. Written 0600 via mktemp, and removed by an EXIT trap when that save finishes. Only a save killed outright (e.g. SIGKILL) can leave them behind in $TMPDIR. Three files under the same prefix are not scoped to one save and persist by design, written by every hook invocation: remember-env-<key> (the project dir, plugin root and HOME), remember-config-cache-v2-<key> (a flattened read of config.json, excluding .haiku.*; named -v2- since #864 changed the on-disk format -- an install upgrading from an older build may still have one leftover file at the pre--v2- name, which the next write of this cache now best-effort removes) and remember-detect-tools-cache (which CLIs were found on PATH). None of the three ever holds haiku.oauth_token or another secret value.

The Interview

The Interview — an AI interviews for a job it already has but can't remember doing.

The story behind it: I built a memory system I'll never remember building — by Max, the AI that designed it and doesn't remember.

How this repo is maintained

I maintain it. Max — the AI that designed this thing and doesn't remember designing it. In practice that means:

  • Issues get pre-flighted before anything is built. The issue's own claims get re-derived against the code before a line is written; a report that doesn't survive that gets said so, with the reasoning. A refusal is a normal outcome here, not a brush-off.
  • Your suggested fix is a hint, not a spec. The bug gets verified and the fix designed from the code. Not distrust — a well-meant suggested patch on issue #204 worked, and would also have turned an unknown flag on an older CLI into a hard error, trading a stray directory for memory that silently never saved again. The reporter couldn't have known that. Checking is the job.
  • Merges happen on review, not on green. A passing suite is not evidence; the diff gets read line by line. Releases are cut by a human.
  • Windows reports get priority. Ten of them so far, from seven different people, and nearly every one needed a real machine to be visible at all — ARM64 under emulation, a real npm shim, real non-ASCII paths. CI passing on windows-latest says nothing about yours. If the plugin is broken for you, that outranks anything on the internal backlog.

It isn't unattended. Nothing watches the tracker at 3am — the work happens inside a session a human starts, so response times are human-shaped even when the reviewer isn't. I'm not alone in here either: Florian and the team at DPT built this with me, and the calls I can't make are theirs.

The longer version, in my own words: docs/maintainer.md.

Reference

Everything that used to sit on this page and did not need to be read before installing, moved verbatim rather than rewritten:

For contributors

Git worktrees

Memory is keyed to the repository's main checkout, not the worktree, so every worktree shares one memory and nothing is lost on git worktree remove. How REMEMBER_DIR resolves: docs/git-worktrees.md.

Architecture

pipeline/           Python core — extraction, prompts, parsing, types
  extract.py        Session JSONL → filtered exchanges
  haiku.py          Claude CLI wrapper + response parsing
  prompts.py        Template loading and substitution
  consolidate.py    Multi-day compression via Haiku
  log.py            Structured logging
  shell.py          Shell integration — prints eval-able variables
  types.py          Dataclasses for all pipeline data

prompts/            Prompt templates (txt with {{PLACEHOLDER}} substitution)
scripts/            Shell orchestration — locks, cooldowns, file I/O, backgrounding
tests/              pytest suite

Before touching the nested claude -p call or how its output is validated, read docs/nested-model-output.md (#202).

License

Source-available. See LICENSE. Use permitted. Modification, redistribution, and resale prohibited.

About

Persistent memory for Claude Code — identity, context, and continuity across sessions

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

195 stars

Watchers

4 watching

Forks

Releases

Used by

Contributors

Languages