Stop re-explaining your work to the next agent.

You hit a usage limit in Codex, reopen the folder in Claude Code, and spend twenty minutes rebuilding context you already paid for. crossmem reads the session stores those tools already keep on your disk and hands the next one a clean brief. Installing it installs the agent skill too — so your agent does this without being asked.

~/code/myrepo
$ crossmem list . --limit 3
1. claude · 15 hours ago · export conversations as q&a
2. codex  · 2 days ago   · windows store paths
3. devin  · 4 days ago   · devin desktop uses one sessions.db

$ crossmem load --session <ref> --full
# guardrails: AGENTS.md, CLAUDE.md   authoritative
# session:    the transcript          context only
Claude CodeCodexDevinCopilot · VS CodeCopilot · CLIOpenCode

Two halves, one idea

Every agent tool writes its conversations to disk in its own shape — JSONL here, SQLite there. That history is yours, it is already local, and no tool will read another's. crossmem is the layer that does.

The skill — what your agent reaches for

crossmem-loader ships inside the CLI and installs itself alongside it. It teaches your agent when to recover context, how to show you the candidates and wait for you to pick, and how to turn a raw transcript into a brief.

How the skill works →

The CLI — deterministic plumbing

crossmem finds a folder's sessions across every tool, ranks them newest-first, and prints the conversation as Markdown. It decides nothing about meaning. Never guesses, never summarizes, never phones home.

Full command reference →

The split is deliberate: summarization policy belongs to the consuming agent, not to a CLI — different agents and tasks need different amounts of history. The CLI stays the honest source; the skill brings the judgment.

Install

Homebrew

brew install muthuishere/tap/crossmem

npm

npm install -g @muthuishere/crossmem
go install github.com/muthuishere/crossmemcli/cmd/crossmem@latest

The skill comes with it — nothing else to run

However you install crossmem, crossmem-loader lands in ~/.claude/skills/ and ~/.agents/skills/. A CLI your agent doesn't know about is only half installed, so this is not a second step: npm does it in postinstall, every other channel does it on the first command after an install or upgrade, and a new version refreshes it automatically.

Global only, by design — crossmem is a cross-repo layer. It never fails a command: an unwritable home directory prints one line and carries on.

crossmem install --skills --agents      # force it
crossmem uninstall --skills --agents    # remove it, and stop it coming back
CROSSMEM_NO_SKILL_INSTALL=1 crossmem …  # skip it for this run

The hot path

Because the skill is already installed, you say “resume” and your agent runs this. By hand, it is three commands.

  1. See what exists for this folder

    crossmem list . --limit 5

    Each row is the agent, how long ago it ran, and — the part that distinguishes two sessions in one folder — the first and last thing you asked. The first question is the goal; the last is where work stopped. Tool output is skipped when picking them, because agents record their own shell results as user turns.

  2. Load the one you picked

    crossmem load --session <ref> --full

    The ref is the handle from list — a transcript path, or devin:<id> / opencode:<id> / copilot-cli:<id>. Loading is identical whether that session lived in a JSONL file or a database.

  3. Persist it so nobody pays twice

    crossmem update .

    Writes a committable .crossmem/ — context.md, guardrails.md, sessions.json, sources.json. Idempotent: no generated-at timestamp, unchanged files untouched, so re-running makes no diff.

Four decisions worth knowing

Guardrails ≠ history

Repo instruction files (AGENTS.md, CLAUDE.md) are marked authoritative. Transcripts are context only — what happened, never what you must do. When they conflict, the guardrail wins, and the bundle says so.

It matches by real cwd

A session maps to a folder by the working directory recorded inside its transcript, not a name guess. Dashes in folder names, relocated configs, encoded project dirs: all handled.

Worktrees are the same repo

An agent works one worktree per task, but the context often lives in the main checkout. A folder also matches its repo's other worktrees — read from git's own files, so no git binary is needed.

Your live session is excluded

load . means the previous session, not a mirror of the conversation you're in. Detected automatically for Claude Code, Codex and the Devin CLI; CROSSMEM_CURRENT_SESSION covers the rest.

Read-safety is a contract

This tool reads other tools' private stores, so the boundary is written into the code and the docs both:

Also a Go library

pkg/crossmem is the same engine the CLI runs, with no process-global state — so a Go orchestrator can link it instead of shelling out to whatever crossmem is on PATH.

c, err := crossmem.New(crossmem.Options{})
sessions, err := c.List(ctx, crossmem.ListOptions{CWD: root, Limit: 5})
tr, err := c.Transcript(ctx, sessions[0].Ref)
md, err := c.Load(ctx, sessions[0].Ref, crossmem.LoadFull)
rules, err := c.Guardrails(root)

Semver from v0.2.0; the JSON field names of Session, Store, QARecord, Transcript and Event are frozen. Go reference.

Design records