/brain:import
A new brain is empty, and an empty brain is worth nothing until something fills it. But your agents have been keeping local transcripts for months — decisions, preferences, corrections, conventions. /brain:import reads them and turns them into real memories.
Usage
/brain:import [--source <id>] [--project <name>] [--since <when>] [--limit <n>] [--all]
| Flag | Description |
|---|---|
--source <id> | Which history store to read: claude-code (default) or codex. --sources lists what is detected. |
--project <name> | Only sessions from one project. |
--since <when> | Only sessions since then — 30d, 6m, 1y, or 2026-01-01. |
--limit <n> | Max sessions to consider. Default 40. |
--all | Re-offer sessions that were already imported. |
How it works
The split is the whole design: the CLI harvests, the agent distills.
Harvest (deterministic)
brain import scans your agent's transcript store and builds a digest — session titles, user prompts, projects, git branches, timestamps, and edited files. It filters out harness wrappers (<system-reminder> blocks, slash-command tags, command output), subagent traffic, and bare acknowledgements like "yes" or "thanks". It also strips Brain's own <brain-context> and <brain-session-context> injections, so a memory a hook surfaced is never harvested back into a new one.
Distill (semantic)
Your agent reads that digest and decides what is worth remembering, then writes memories through the ordinary /brain:memorize path — same classification, same hierarchy, same provenance gate.
Mark (incremental)
The agent records which sessions it read in ~/.brain/.import/state.json, so re-running only offers new ones.
Extracting meaning from a transcript is a semantic judgement. Making it in the CLI would mean shipping an embedding model or calling out to an LLM — the two things Brain Memory exists to avoid. So the harvester reports facts and never infers.
Budgets
A long history would blow any context window, so the digest is capped on three independent axes:
| Axis | Default |
|---|---|
| Sessions per run | 40 (--limit) |
| Prompts sampled per session | 6 — taken from both ends, since the first prompt states the goal and the last ones state what it became |
| Total digest size | ~60,000 characters (~15k tokens) |
Candidates are round-robined across projects rather than taken purely by recency. On a real 261-session history, straight recency gave one busy repo 32 of 38 slots; interleaving lifted coverage from 5 projects to 13 within the same budget. Cold-start value comes from breadth — your agent learning that you work on several things, and what each one is.
Provenance
Imported memories are always written with origin: "agent-inferred", because they are conclusions drawn from a transcript rather than statements you made directly.
That single fact carries the whole security story. agent-inferred memories are capped below the prune-exempt salience threshold, capped on confidence so they stay flagged as uncertain at recall, and may not raise their own base strength. An import can never pin a memory, exempt one from decay, or outrank something you told your agent yourself.
If an imported fact deserves to be always-present, pin it deliberately afterwards with /brain:pin.
What gets remembered
A good import distills rather than transcribes. Forty sessions should produce roughly 5–20 memories, not forty.
Worth keeping — things that outlive the session:
- Stated preferences and conventions
- Architecture and tooling decisions, with rationale
- Recurring corrections — pushback repeated three times is a preference
- The shape of each project: what it is, its stack, where it deploys
- Constraints, deadlines, ongoing goals
Not worth keeping — things that were only true that afternoon:
- "fix the failing test", "run the build", "what does this function do"
- Anything already recorded in the repo or its git history
- One-off debugging that ended when the bug was fixed
Sources
brain import --sources
Lists the history stores detected on this machine. Two are supported:
| Source | Reads |
|---|---|
claude-code (default) | Claude Code's transcripts under ~/.claude/projects/ |
codex | Codex CLI rollouts under $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl (~/.codex/ by default) |
Codex
brain import --source codex reads the rollout files directly (format verified against Codex 0.153):
- Prompts are the
response_itemmessages whosecontent_item_kindsareuser.*— which separates what you typed from the AGENTS.md, environment, and hook context Codex injects as user-role messages. Files written before Codex 0.148 lack that field, so the harvester falls back to matching Codex's wrapper markers. - Skipped: Codex's own background threads — subagent, guardian review, and memory consolidation.
- Thread names come from
session_index.jsonl; touched files come fromapply_patchcalls. - The import cursor is the rollout id from the filename, so a re-run offers only new rollouts.
The adapter registry in src/harvest.js accepts additional agents without changes elsewhere, so more sources can land without touching the digest, budget, or provenance logic.
Safety
- Nothing is written without your agent.
brain importonly ever reads and prints; every memory goes throughbrain memorize. - Safe to re-run. The cursor means a second run offers only new sessions.
- Nothing leaves your machine. Transcripts are read locally; no upload, no model call in the harvest step.
Examples
# What history exists here?
brain import --sources
# Start scoped — a better first pass than swallowing a year at once
brain import --project my-app
# Just the last month
brain import --since 30d
# Cold-start from Codex CLI history
brain import --source codex --since 30d
# Re-offer everything, ignoring the cursor
brain import --allRelated
/brain:memorize— the write path every imported memory travels/brain:pin— promote an imported fact to the always-present tier/brain:remember— recall what the import stored