Memory from the CLI
Review the memories your agents wrote in their harnesses, ranked by how often runs used them, and promote the ones worth keeping into steering records.
Your agents already write down what they learn, each in its own harness: Claude Code in its memory folder, Codex in its memory store, Stella in its context store. Oxagen collects those memories from every enrolled host as soon as an agent saves them, checks again every five minutes, and counts the runs that use each one. A Claude Code folder uploads only when its checkout belongs to one of the workspace's repositories, or when it is a personal folder. Agent memory explains what makes a memory worth keeping. oxagen memory lists them, shows one in full, promotes the ones worth keeping into steering records, and dismisses the rest. It also drops one record from a memory PR.
A memory steers only the agent that wrote it, and its harness already does that. Oxagen sends no waiting memory to another agent. A memory reaches other agents only once you promote it into a steering record and the memory PR merges in git. After that, at each prompt, the collector on every enrolled machine asks Oxagen for the merged memory records that best fit the prompt and passes them to the agent with it.
List memories
oxagen memory list
oxagen memory list --harness claude-code --type feedback
oxagen memory list --state promoted,retired --repository github.com/acme/apiThe list ranks memories by uses, then by the newest use, then by the newest capture. Memories that say the same thing share one row, marked (+N same). Without --state, it lists waiting memories and memories a memory PR cites.
| Flag | Purpose |
|---|---|
--state <states> | Comma-separated: waiting, in_pr, promoted, dismissed, retired. |
--harness <harness> | claude-code, codex, cursor, stella, or claude-desktop. |
--agent <record-id> | Memories one agent wrote. |
--repository <repo> | Memories scoped to a repository, such as github.com/acme/api. |
--type <type> | A Claude Code memory type: user, feedback, project, or reference. |
--limit <n>, --offset <n> | Page through the rows, 50 at a time by default. |
--json | Machine-readable output. |
Uses count distinct runs. A run that only loaded the memory's line from MEMORY.md is left out of the count, and oxagen memory show lists those loads. A harness that reports no use shows No signal, so a zero never reads as unused.
Show one memory
oxagen memory show mem_01J8…It prints the memory's text, its source file, its harness and agent, each run that used it and how, and the memory PR that last cited it. A use is a file read, a harness's own count, a citation, an index load, or a later run's lesson that repeats it. It names the person who imported a memory, and says who dismissed a dismissed memory, when, and why.
Promote memories
oxagen memory promote mem_01J8…
oxagen memory promote mem_01J8… mem_01J9… --one-record --kind code-rule --force must
oxagen memory promote mem_01J8… --kind constraint --effect forbid --repo github.com/acme/api
oxagen memory promote mem_01J8… --workspaceEach id becomes one draft steering record, or --one-record cites every id in one record. Each record also cites the waiting memories that say the same thing, unless you pass --no-same-text. The drafts join the open memory PR, or the command opens one on memory/<date>. Nothing steers until a person merges the PR.
Unless you name a kind, force, or effect, Oxagen suggests each record's kind and force first. It uses the same classifier as oxagen memory import, and the command prints each suggestion with its reason and the words behind the force. With --statement, Oxagen classifies that text, the record's body, in place of the memory's own statement. The call is billed like the import's. If it fails, each record takes the default kind and force.
| Flag | Purpose |
|---|---|
--one-record | Cite every id in one record. |
--statement <text> | The record's body. Defaults to the first memory's statement. The suggestion reads this text. |
--kind <kind> | business-rule, code-rule, constraint, procedure, fact, preference, or memory. Defaults to the kind Oxagen suggests. |
--force <force> | must, should, may, or info, within what the kind allows. Defaults to the force Oxagen suggests. |
--effect <effect> | require or forbid. A constraint needs one. |
--repo <repo> | Scope the record to a repository. Repeat it for more. Defaults to the first memory's repositories. |
--workspace | Scope the record to the whole workspace, even when its memory names a repository. |
--no-suggest | Skip the suggestion. Each record takes the default kind and force: should for a rule kind, may for a preference, and info for a fact or a memory. |
--no-same-text | Cite only the ids you name. |
--json | Machine-readable output. |
Only a waiting memory is promoted. The command names each memory it left out and why.
Dismiss memories
oxagen memory dismiss mem_01J8… --reason covered
oxagen memory dismiss mem_01J8… --restore--reason says why: covered (a record already covers it), wrong (it is wrong for this workspace), one_off (it was a one-off in that run), or other. Each memory keeps the reason with the person who dismissed it and the time. A dismissed memory leaves the default list. The curator proposes its statement again only after memories from 2 more runs repeat it. --restore brings a dismissed memory back.
Drop a record from a memory PR
oxagen memory drop 12 steering/memory/workspace/general/use-pnpm.mdPass the memory PR's number and the path of the record file. The command pushes a commit to the PR's branch that deletes the file, and the other records stay. When the PR merges, the dropped record's statements are rejected and the memories it cited wait again. Running it again on a dropped record names the commit that dropped it.
The command refuses a merged or closed memory PR, a path the PR does not propose, and the PR's last record. To reject every record, close the PR instead. The command calls drop_memory_record.
Import existing docs
Turn Markdown rule docs, such as CLAUDE.md, AGENTS.md, or a conventions folder, into steering records in bulk:
oxagen memory import CLAUDE.md docs/conventions/*.md # preview
oxagen memory import CLAUDE.md docs/conventions/*.md --yes # open the steering PRThe preview lists one row per statement: its kind, its force with the words that justify it, the file and line it came from, and any duplicate or conflict with a published record. A duplicate is marked skip.
The command sends files in calls of 25 and then compares the rows of every call, so a statement two calls both hold is marked a duplicate. --yes opens one steering PR on steering/import-<date> with every row marked add. A row that conflicts with a published record is left out, and the command names it. One steering PR holds at most 299 records, so --yes refuses an import that marks more add. Nothing steers an agent until the PR merges. The command calls parse_markdown_import and commit_markdown_import.
Related
- Agent memory: the memory model and its capabilities.
- Knowledge graph from the CLI: the structural context memory sits beside.