Generated banner for Memoir
Generated logo for Memoir

Memoir

Memory server

First committed by zhangfengcdt

Published in zhangfengcdt/memoir. Publisher page

629 GitHub stars

What it is

Hierarchical Agent Memory with Git-Like Version Control
— the description by zhangfengcdt

AutoGineer overview, from the brain’s own files

Memoir is a memory system designed to replace opaque vector databases with a transparent, versioned, and cryptographically secure storage layer. By utilizing ProllyTrees, it enables hierarchical semantic paths instead of UUIDs, allowing for efficient O(log n) lookups. It addresses common AI memory issues like context contamination and token waste by providing branch, commit, merge, and rollback capabilities. Memoir integrates with various agents through plugins and an MCP server, supporting both keyword-based and LLM-powered semantic search.

How it works

Memory model: Not stated

AutoGineer overview, from the brain’s own files

Memoir organizes memory into a hierarchical structure using semantic paths, such as profile.professional.skills.python. It uses a ProllyTree-based store to manage data, allowing for Git-like operations such as branching and versioning. The system includes a classifier to categorize memories and a search engine for retrieval. It provides a CLI for manual interaction, hooks for automatic memory capture in supported agents, and an MCP server for integration with various AI development tools.

Folders
FolderRoleFiles
.githubagent-config10
docsdocs41
scriptsscripts9
srcsource-code216
teststests53
.agentsfolder1
.claude-pluginfolder1
benchmarksfolder10
packagingfolder3
pluginsfolder187
staticfolder2

The agent writes

Requirements

Runtimes: Python >=3.10

API keys (by name): ANTHROPIC_API_KEY, OPENAI_API_KEY

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)

Set it up

  1. This brain runs code automatically: 7 hooks (claude-code, codex), 2 scripts. Review Makefile, README.md, plugins/claude-code/hooks/hooks.json, plugins/codex/hooks/hooks.json before opening the folder in Claude Code. No step below turns a hook on for you.

    • Makefile: pip install -e .
    • README.md: curl -LsSf https://astral.sh/uv/install.sh | sh
    • plugins/claude-code/hooks/hooks.json: bash ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh
    • plugins/claude-code/hooks/hooks.json: bash ${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit.sh
    • plugins/claude-code/hooks/hooks.json: bash ${CLAUDE_PLUGIN_ROOT}/hooks/stop.sh
    • plugins/claude-code/hooks/hooks.json: bash ${CLAUDE_PLUGIN_ROOT}/hooks/session-end.sh
    • plugins/codex/hooks/hooks.json: bash "${PLUGIN_ROOT}/hooks/session-start.sh"
    • plugins/codex/hooks/hooks.json: bash "${PLUGIN_ROOT}/hooks/user-prompt-submit.sh"
    • plugins/codex/hooks/hooks.json: bash "${PLUGIN_ROOT}/hooks/stop.sh"
  2. Not scanned by AutoGineerThe author’s README also describes installing it as a Claude Code plugin marketplace. Read its install section: AutoGineer did not scan that path. https://github.com/zhangfengcdt/memoir/blob/7fd1b3ef704fc554596571d5b9c8b73d7f2b0c5d/README.md#install-a-plugin-for-your-agent
  3. Not scanned by AutoGineerIts dependencies are installed by pip or uv when you run it and were not scanned by AutoGineer (7 declared). https://pypi.org/project/memoir-ai/
  4. First committed by zhangfengcdt. Published in zhangfengcdt/memoir. Licence: Apache License 2.0.

Usage

AutoGineer overview, from the brain’s own files

  • CLI-based memory management
  • Automatic context injection for coding agents
  • Version-controlled memory branching
  • Semantic search across stored facts
  • Cross-machine memory synchronization
“memoir remember "I prefer using Python for data analysis" -p preferences.coding.languages”
Stores the fact under the specified semantic path for later retrieval.
“memoir recall "what are my coding preferences?"”
Performs a semantic search to retrieve the relevant stored memory.

Documentation by zhangfengcdt

Memoir

<div align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://www.memoir-ai.dev/images/memoir.png"> <source media="(prefers-color-scheme: light)" srcset="https://www.memoir-ai.dev/images/memoir-light.png"> <img src="https://www.memoir-ai.dev/images/memoir.png" alt="Memoir Logo" width="200" height="200"> </picture>

Git for AI Memory

Hierarchical Memory with Git-Like Version Control

</div>

Image: Python Image: License Image: Status Image: Website Image: Docs

<p align="center"> <img src="docs/_static/memoir-demo.gif" alt="Memoir demo" width="900"> </p>

Memoir is a high-performance semantic memory system for AI agents that brings Git-like version control to AI memory management. It replaces opaque vector databases with transparent, versioned, cryptographically secure memory storage using hierarchical semantic paths.

Project page: memoir-ai.dev — full overview, demos, and roadmap.

Why agents need versioned memory

AI memory is a Global Variable anti-pattern. Every production agent hits the same three walls: context contamination, token rent, and memory drift. Memoir brings version control to your agent's mind.

Your agent doesn't respect your git state. Context contamination happens every time you git checkout. Without branch-aware memory, your agent tries to apply experimental refactor patterns to stable production hotfixes.

You're paying "token rent" on a flat file. Using CLAUDE.md or MEMORY.md as a global store is a cache-killer. Every minor memory update invalidates your entire prefix cache, forcing you to pay full price to re-process your entire conversation.

Your agent's memory is code without version control. Today's AI memory — CLAUDE.md, vector stores, scratchpads — is treated like an append-only blob. One bad session poisons every future retrieval. Without memoir blame or memoir checkout, there's no way to audit who taught the agent a rule or revert a hallucination without wiping the whole store.

Key Features

  • Git-like Versioning — Branch, commit, merge, and rollback memories with cryptographic integrity.

  • Semantic Paths — Replace UUID keys with meaningful paths like profile.professional.skills.python.

  • O(log n) Lookups — Fast hierarchical search instead of expensive vector operations.

  • Memory Aggregation — Automatic consolidation of related memories at semantic locations.

  • Clean Architecture — Proper separation of storage, classification, and search layers.

  • Multiple Search Engines — Choose between fast keyword-based or intelligent LLM-powered search.

<!-- ## Multi-agent sessions <p align="center"> <img src="docs/_static/memoir-multi-agent.gif" alt="Multiple agent sessions working with Memoir" width="900"> <br> <em>Multiple agent sessions working with Memoir.</em> </p> -->

Install from PyPI

pip install memoir-ai

The distribution name on PyPI is memoir-ai. The Python import is import memoir and the CLI is memoir.

Install a plugin for your agent

Memoir ships as a plugin for several coding and personal-assistant agents. Expand the one you use:

<details> <summary><b>Claude Code</b></summary>

Inside a Claude Code session, run:

/plugin marketplace add zhangfengcdt/memoir
/plugin install memoir@memoir

No manual pip install needed if you have uv on PATH — the plugin auto-resolves to uvx --from memoir-ai memoir when the bare memoir binary isn't installed. Don't have uv? Install it once with the standard one-liner:

curl -LsSf https://astral.sh/uv/install.sh | sh

That's enough — the plugin handles the rest. It registers hooks for session start, user-prompt-submit, and stop, so your project gets automatic context injection and auto-captured memories. See the Claude Code plugin guide for the full slash-command and hook reference.

</details>

<details> <summary><b>Codex</b></summary>

Memoir's Codex plugin is distributed from this repository's Codex marketplace. In Codex, run /plugins, add the memoir marketplace from zhangfengcdt/memoir, restart Codex if prompted, then choose Memoir Plugins and install memoir.

You can also register the marketplace from the CLI:

codex plugin marketplace add zhangfengcdt/memoir

While developing from a local checkout, use codex plugin marketplace add /absolute/path/to/memoir instead. The repo marketplace lives at .agents/plugins/marketplace.json and points Codex at ./plugins/codex, relative to the repository root.

No manual pip install needed if you have uv on PATH — the Codex plugin resolves the Memoir CLI the same way the Claude Code plugin does: memoir on PATH first, then uvx --from memoir-ai==<pinned> memoir, then uv tool run --from memoir-ai==<pinned> memoir.

Enable Codex hooks with [features].hooks = true in ~/.codex/config.toml or pass --enable hooks for a smoke run. The Codex plugin ships lifecycle hooks; memory-recall, memoir-onboard, memoir-remember, memoir-status, and memoir-ui skills; Codex-specific transcript parsing; and local marketplace metadata. See the Codex plugin guide for setup, limitations, and the real Codex smoke-test flow.

</details>

<details> <summary><b>Hermes</b></summary>

Memoir is a memory provider for Hermes, the Nous Research personal-assistant agent. Install the plugin into your Hermes home and activate it:

hermes plugins install zhangfengcdt/memoir/plugins/hermes   # or: cp -r plugins/hermes ~/.hermes/plugins/memoir
hermes memory setup                                         # choose "memoir"

Hermes then auto-captures durable facts (people, schedule, preferences, standing instructions) each turn and exposes memoir_recall / memoir_remember / memoir_forget / memoir_sync / memoir_status tools. Capture/classification run on your host-selected model via direct provider APIs (never the claude CLI). See the Hermes plugin guide for install, configuration, model selection, and proxy routing.

</details>

<details> <summary><b>OpenClaw</b> (community)</summary>

Memoir is a memory plugin for OpenClaw, the personal-assistant gateway. It lives in its own repo, zhangfengcdt/openclaw-memoir. Install it into the memory slot, allow conversation access, and restart the gateway:

openclaw plugins install https://github.com/zhangfengcdt/openclaw-memoir   # or: --link /path/to/openclaw-memoir
openclaw config set plugins.entries.memory-memoir.hooks.allowConversationAccess true
systemctl --user restart openclaw-gateway

OpenClaw then auto-captures durable facts each turn (remembered across your sessions by default) and exposes memoir_recall / memoir_remember / memoir_forget / memoir_status tools plus an in-chat /memoir command. Set a capture model + provider key in config — plugins.entries.memory-memoir.config.{model,apiKey} (OpenClaw keeps its own keys in a secret store; use a temperature=0-capable model like anthropic/claude-haiku-4-5). See the OpenClaw plugin guide for configuration, scoping, model selection, and tool-profile notes.

</details>

<details> <summary><b>OpenCode</b> (community)</summary>

opencode-memoir is a community-maintained plugin that brings Memoir's long-term memory workflows to OpenCode through its native plugin system. Follow the install instructions in that repository.

</details>

<details> <summary><b>Any MCP host</b> (Claude Desktop, Cursor, Cline, Windsurf, VS Code, Zed, …)</summary>

Memoir ships an MCP server (memoir-mcp) on the official Model Context Protocol SDK, so any MCP-compatible host gets git-versioned memory — including the memoir_branches / memoir_checkout / memoir_commits versioning tools no other memory server has. No install needed if you have uv; add to your host's mcpServers config:

{
  "mcpServers": {
    "memoir": {
      "command": "uvx",
      "args": ["--from", "memoir-ai[mcp]", "memoir-mcp"],
      "env": { "MEMOIR_STORE": "~/.memoir/mcp" }
    }
  }
}

Recall is LLM-free by default (keyless), with opt-in single-call or multi-level tiered LLM modes; the store auto-creates on first use. See the MCP server guide for per-host config (VS Code/Zed/Continue/LibreChat differ slightly), recall modes + LLM setup, remote HTTP for ChatGPT/Claude.ai connectors, and the one-click Claude Desktop .mcpb.

</details>

Quick look

Memoir's CLI defaults to Anthropic claude-haiku-4-5 as of v0.1.6 — set your key first:

export ANTHROPIC_API_KEY="sk-..."

Note that if you do not set any model api keys, it will try to use the claude -p command to authenticate via claude code's subscription.

Then create a store and round-trip a memory:

# 1. Create a memoir store
memoir new my-memoir-store
cd my-memoir-store

# 2. Store with an explicit path (offline, no LLM call)
memoir remember "Sarah prefers tabs and 2-space indents" -p preferences.coding.style

# 3. Store with auto-classification (LLM picks the path; needs API key)
memoir remember "I work in Pacific time"

# 4. Read back by path (offline)
memoir get preferences.coding.style

# 5. Semantic search (LLM-backed)
memoir recall "what does Sarah prefer?"

# 6. Watch a file by indexing it on the fly
memoir watch add ~/papers/transformer.pdf -n research

# 7. Search the indexed content
memoir search "transformer attention mechanism"

# 8. Open the visual explorer (auto-opens in your browser)
memoir ui

Curious what the UI looks like before installing? Browse the UI Gallery.

Prefer a different model? memoir recall "..." --model gpt-4o-mini (needs OPENAI_API_KEY), or set MEMOIR_LLM_MODEL in your shell. Resolution order: --model flag → MEMOIR_LLM_MODEL → claude-haiku-4-5.

See the full Quickstart for the Python API and version-control workflow.

Documentation

Full docs live at zhangfengcdt.github.io/memoir:

  • Quickstart — five-minute tour of the core loop.

  • CLI Reference — every command, flag, and exit code.

  • UI — the visual explorer (Tree / Graph / Timeline / Places + /stats).

  • Claude Code — plugin install, slash commands, hooks, lifecycle.

  • Codex — plugin install, hooks, skills, transcript parsing, smoke-test evidence.

  • Architecture — taxonomy, classifier, store, search.

  • API Reference — Python SDK.

  • Examples — context branching, memory debugging, reproducible testing.

Contributing

Memoir is alpha and contributions are very welcome — especially from people building coding agents, since that's the audience we're optimizing for. Good first paths in:

  • Pick an issue from the issue tracker or open one describing a gap.

  • Fork the repo, branch off main, and run make ci before opening a PR (lint, tests, docs build must be green).

  • Bug reports with a minimal reproducer and benchmark / taxonomy proposals for coding-agent use cases are particularly appreciated.

License

Apache License 2.0 — see LICENSE.

docs/cli.md

CLI Reference

The memoir command is the primary shell interface to a memory store. It exposes every retrieval and mutation pipeline the Python SDK supports, plus taxonomy-inspection primitives designed for agentic callers.

This page documents the search-adjacent commands — recall, get, and summarize — and the cloud sync commands in depth. For mutation (remember, forget), versioning (branch, checkout, merge, time-travel, branch-match), and crypto (proof, verify, blame) commands, use memoir <command> --help or see the API reference.

Setup

Set MEMOIR_STORE once so you can skip -s <path> on every call. Most usage assumes this is exported:

export MEMOIR_STORE=/path/to/store

Add --json at the group level for machine-readable output (recommended when scripting or piping into jq). MEMOIR_JSON=1 in the environment has the same effect globally.

Environment variables
VariableEffect
MEMOIR_STOREDefault store path. Avoids -s <path> on every call.
MEMOIR_JSONIf 1, all commands output JSON (same as passing --json).
MEMOIR_QUIETIf 1, suppresses non-essential output.
MEMOIR_BRANCHDefault target branch for remember, recall, get, forget, and search — per-call routing without changing the store's checked-out branch. Each command also accepts an explicit --branch <name> flag which overrides this variable. See Per-call branch routing below.
MEMOIR_MERGE_POLICYGlobal conflict-resolution strategy for remember when a key already exists, overriding the per-type default but below an explicit --merge-policy. =replace restores the old overwrite-everywhere behaviour. See Conflict resolution.
MEMOIR_FACET_MAX_ENTRIESCap on facet entries per key for append-style writes (oldest pruned). Default 50; 0/none disables capping.
MEMOIR_RECALL_MERGEIf llm, enables merge-on-read: a multi-entry key's content is LLM-consolidated at read time. Off by default (the deterministic projection is used).
MEMOIR_API_KEYmemoir-cloud API key; overrides the one saved by memoir login. Unlocks the cloud sync commands (remote, push, pull, fetch). Unset = COMMUNITY tier, no behaviour change. Never written to disk. See Cloud Sync.
MEMOIR_CLOUD_URLmemoir-cloud gateway URL for remote add / push --create when --url is not passed. Default: the production gateway.
Global flags

Flags accepted before the subcommand, on the memoir group itself:

FlagEffect
-s, --store <path>Override the store path (takes precedence over MEMOIR_STORE).
--jsonMachine-readable output for every subcommand.
-q, --quietSuppress non-essential output.
-v, --verboseEnable verbose logging.
Per-call branch routing (multi-agent)

remember, recall, get, forget, and search accept --branch <name> (env: MEMOIR_BRANCH). When set, the call operates against that branch instead of the store's checked-out one.

Reads (recall, get, search) never touch the checkout. The branch is opened as a snapshot straight from its committed root, so .git/HEAD and every other process sharing the store are unaffected, and the view is read-only.

Writes (remember, forget, capture) check the branch out for the duration of the write, under the store's write lock. The previous branch is restored on exit. Every memoir writer takes the same lock (<store>/.git/memoir-write.lock), so a concurrent remember from another process, such as the Claude Code plugin's Stop hook, waits for the restore instead of committing onto the routed branch. Anything that only reads .git/HEAD meanwhile, like a status line, sees the routed branch for that moment.

Set MEMOIR_BRANCH once at the runtime boundary (LangGraph node, MCP client, agent shell). Each agent process injects its own identity once instead of threading a flag through every call site:

# In agent A's process
export MEMOIR_BRANCH=agents/reviewer
memoir remember "found N+1 query in /users migration"

# In agent B's process
export MEMOIR_BRANCH=agents/builder
memoir remember "shipped pagination on /users"

Or pass --branch per call. Explicit flag wins over the env var:

memoir remember "API contract change" --branch=agents/reviewer
memoir recall   "N+1"                 --branch=agents/reviewer
memoir get      lessons.builder.api   --branch=agents/builder
memoir forget   stale.note            --branch=agents/builder --force

Reads are isolated. Other branches and main don't see an agent's working memory until it's merged:

$ memoir get lessons.reviewer.sql --branch=agents/builder
✗ default:lessons.reviewer.sql (not found)

$ memoir get lessons.reviewer.sql --branch=typo-here
✗ Failed to get: Branch 'typo-here' does not exist.
  Create it explicitly with `memoir branch typo-here`, or use a write
  command (e.g. `memoir remember --branch=typo-here ...`) to bootstrap it.

That last error matters — read commands refuse to silently return empty on a misspelled branch, so typos surface immediately instead of looking like "no results".

Auto-create on first write. No separate memoir branch <name> is needed for a new agent:

memoir remember "first note" --branch=agents/new-bot   # branch is bootstrapped
memoir branch                                          # → main, agents/new-bot

Cross-agent synthesis stays explicit — promote findings to the shared trunk with memoir merge:

memoir merge agents/reviewer --into main
memoir recall "N+1"   # now visible on main

After every --branch call the store's checked-out branch is unchanged.

Concurrency note. Writers serialize on the store's write lock, across processes and threads; a writer that cannot get it within two minutes fails with "Another memoir process has been writing…" rather than waiting forever. Reads are lock-free.

Search commands

The three pipelines described in Search Theory are all reachable here. Pick the one that matches how narrow or open-ended your query is.

memoir recall — semantic search (in-engine)

Primary search entry point. Accepts a natural-language query and returns ranked IntelligentSearchResult memories. Mode is selected per call via --mode.

# Single-stage (default) — one LLM call, 500-800ms typical
memoir recall "what's my testing setup?"

# Tiered drill-down — 2-3 LLM calls, narrower prompts, ~1-2s typical
memoir recall "what's my testing setup?" --mode tiered

# Scope to a namespace and cap the result count
memoir recall "meeting notes" -n calendar -l 5

# Drop results below a relevance threshold (0.0-1.0)
memoir recall "programming languages" --threshold 0.5

# Machine-readable — best shape for agents / scripts / benchmarks
memoir --json recall "testing setup" --mode tiered

The --json form exposes per-stage observability. For --mode tiered the step_timings block contains l1_survey, l1_pick_llm, descend, key_pick_llm, memory_retrieval, total_search (plus l2_pick_llm when an L1 exceeded the 40-key escalation threshold). Every result carries metadata.mode so a consumer never has to guess which pipeline produced it:

memoir --json recall "testing setup" --mode tiered \
  | jq '.memories[0].metadata | {mode, step_timings}'
{
  "mode": "tiered",
  "step_timings": {
    "step1_path_discovery": 0.012,
    "l1_survey": 0.001,
    "l1_pick_llm": 0.412,
    "descend": 0.001,
    "key_pick_llm": 0.587,
    "memory_retrieval": 0.008,
    "total_search": 1.021
  }
}

A/B the two modes on the same store:

memoir --json recall "testing setup" --mode single  | jq '.timing_ms'
memoir --json recall "testing setup" --mode tiered  | jq '.timing_ms'
Picking the LLM

Both recall and remember accept a --model flag. Resolution order:

  1. --model <name> flag (highest priority)

  2. MEMOIR_LLM_MODEL env var

  3. claude-haiku-4-5 default

# Default — Anthropic Haiku, requires ANTHROPIC_API_KEY
memoir recall "what's my testing setup?"

# Per-call override
memoir recall "..."   --model gpt-4o-mini      # needs OPENAI_API_KEY
memoir remember "..." --model claude-sonnet-4-5

# Shell-wide override
export MEMOIR_LLM_MODEL=gpt-4o-mini

As of v0.1.7, litellm is a default dependency, so pip install memoir-ai enables both LLM-backed and direct-path commands. (Prior to v0.1.7 you had to add the [litellm] extra explicitly.)

memoir remember — conflict resolution

When a write lands on a key that already exists, remember resolves the conflict with a merge policy. By default the policy is derived from the key's memory type; --merge-policy overrides it per call. See Conflict & Merge theory for the full model.

FlagEffect
--merge-policy <strategy>Force a strategy for this write: append, replace, confidence_gated, llm_merge, merge_on_read, or reject.
-i, --interactiveOn a conflict, show existing vs. incoming and prompt (replace / append / merge / skip) per key. Not valid with --json.
--replaceBack-compat alias for --merge-policy replace.

Resolution order (first one set wins): --merge-policy flag → MEMOIR_MERGE_POLICY env → per-type default:

Memory typeExample keysDefault strategy
Episodicexperience.*, metrics.code.*append
Semanticknowledge.*, preferences.*, profile.*, context.project.*confidence_gated
Proceduralworkflow.*, behavior.*llm_merge
Workingcontext.current.*, metrics.turn.*replace
# No flag → the key's memory type decides.
memoir remember "use spaces" -p knowledge.coding.style     # semantic → confidence_gated
memoir remember "deployed v2 at 14:00" -p experience.releases.log  # episodic → append

# Override the type default for this call only.
memoir remember "use spaces" -p knowledge.coding.style --merge-policy append
memoir remember "draft note"  -p experience.releases.log --merge-policy replace

# Resolve interactively, or refuse to clobber and inspect the conflict (JSON).
memoir remember "new value" -p knowledge.coding.style --interactive
memoir --json remember "new value" -p knowledge.coding.style --merge-policy reject

!!! note confidence_gated only changes behaviour for sub-1.0 confidence (LLM classifications). Caller-supplied -p writes are confidence 1.0, so on a semantic key they pass the gate and effectively replace — pass --merge-policy append/llm_merge to accumulate or consolidate instead.

memoir get — direct lookup by taxonomy path

No LLM, no search. Pass one or more exact keys; missing keys come back as found: false so you can batch speculative candidates without branching. Latency is typically <10ms.

# Single lookup
memoir get preferences.coding.style

# Batched lookup in one call
memoir get preferences.coding.style profile.professional.skills

# Scope to a namespace, JSON output
memoir --json get preferences.coding.style -n default

This is the primitive an outer-LLM caller-driven flow uses once it has narrowed to exact keys. From the CLI it's also the fastest way to read a known memory.

memoir summarize — taxonomy surveys

Pure-compute taxonomy inspection. The building blocks behind the caller-driven [mode=drill] / [mode=flat] / [mode=get] patterns are directly usable from the shell when you want to understand the layout of a store without invoking any LLM.

# Full store breakdown
memoir summarize

# Taxonomy-only view, scoped to one namespace
memoir summarize taxonomy -n default

# Keys matching a glob
memoir summarize --keys "preferences.*"

# Top-level prefix histogram (L1 survey)
memoir summarize --depth 1

# Glob + depth: L2 breakdown under preferences.*
memoir summarize --keys "preferences.*" --depth 2

# JSON for scripting
memoir --json summarize --depth 1 -n default

A shell-only drill-down — mirror of the skill's [mode=drill] — is just three calls:

memoir --json summarize --depth 1 -n default
# → pick L1 prefixes from prefix_counts

memoir --json summarize --keys "preferences.*" -n default
# → pick 3-7 exact keys from matching_keys

memoir --json get preferences.coding.style preferences.tools.editor
# → stored values, <10ms
When to reach for which CLI command
  • You want semantic search over a natural-language query → memoir recall (add --mode tiered if the single-stage picker is dropping signal on your store size).

  • You already know the exact taxonomy path → memoir get — skip the classifier entirely.

  • You want to inspect the taxonomy layout (what prefixes exist, how dense each branch is) → memoir summarize --depth N with or without --keys <glob>.

  • You're scripting an agent / LLM caller and want to avoid a nested LLM call on memoir's side → compose summarize + get yourself; this is exactly what the memory-recall skill does.

Cloud sync commands

memoir remote, push, pull, and fetch round-trip a local store with memoir-cloud, so the same memories follow your agent across machines. They need a login: without one every cloud command exits 1 asking you to run memoir login, and nothing else in memoir changes. The rules behind the commands (addresses, what syncs, fast-forward only, key handling) are in the Cloud Sync reference; this section is a hands-on guide.

From the root of a clone of your code repo, the whole setup is:

memoir login                 # once per machine: approve in the browser
memoir push --create         # New: create <handle>/<repo name> from this repo's memories
# or
memoir pull <owner>/<store>  # Open: link an existing cloud store and pull it

Inside a code repo memoir uses that repo's store, the one Claude Code uses (~/.memoir/<slug>), so neither MEMOIR_STORE nor -s is needed; memoir login remembers the gateway, so --url isn't either. On a headless machine use echo "$KEY" | memoir login --with-key; MEMOIR_API_KEY still works and overrides the saved login. The walkthrough below uses explicit names and addresses so each step is visible.

Cloud stores are addressed GitHub-style as <owner>/<store>, where owner is your handle and store is the store name, for example feng-zhang/demo. That address is what you type, what memoir prints, and (prefixed with the gateway) the git remote origin.

CommandWhat it does
memoir login [--url <gateway>] [--with-key] [--default] [--status] / memoir logout [--url <gateway>] [--all]Save a key per gateway after approving in the browser (or from stdin); list them; remove one (or all) and revoke it on the cloud.
memoir login --agent [--name <store>]No account on this machine: provision an agent account that owns one cloud store for this repo and keep its token with the store (.git/memoir-cloud/token), then link origin. Capped (5 branches, 2,000 memories per branch) and deleted after 30 idle days until claimed.
memoir claim [--name <store>]Move that agent store into your own account (logs you in first when needed); origin follows, the token keeps working, the caps are lifted. --name when you already own a store of the repo's name.
memoir cloud openA single-use link (5 minutes) that opens the agent store in the web UI, the account's only way in.
memoir push --create [<store>]Create <your handle>/<store> in the cloud (default name: the code repo's), link it as origin, and push. The usual first step.
memoir remote add [<owner>/<store>] [--url <gateway>] [--force]Link an existing cloud store. With no argument, proposes <your handle>/<directory name> and asks first.
memoir remote add … --name <remote> / memoir remote listLink another cloud store under its own name (e.g. staging); list every remote with its gateway and login state.
memoir remote show [<remote>] / memoir remote remove [<remote>]Show the address, gateway, branch and cloud summary; or unlink. Default remote: origin.
memoir push [--branch <b>] [--remote <name>] [--to <cloud branch>] [--force]Upload the chunks the cloud is missing, then git push. Default: current branch. --to writes the cloud branch under another name (to park a conflicting branch for a manual merge); --force overwrites a cloud branch that is ahead, keeping its previous tip under refs/memoir/backup/<branch> first. Only node files some commit reaches are uploaded; dead ones stay home (memoir gc removes them).
memoir fetch [--remote <name>]Download new refs and chunks. Moves no local branch.
memoir pull [<owner>/<store>] [--remote <name>] [--url <gateway>] [--branch <b>] [--force]With an address, links the remote first when it's missing (never relinks one that points elsewhere). Then fetch, then fast-forward the branch. Creates it from the cloud if missing locally; a never-used local store adopts the cloud history. --force replaces the local branch with the cloud copy.
memoir statusAdds origin: <owner>/<store> when a cloud remote is configured.

All of them accept --json.

First push from your laptop

Start from an existing store, or create one:

memoir new ~/memories
export MEMOIR_STORE=~/memories
memoir remember "Always run make lint before opening a PR"

Create the cloud store, link it, and push in one step. The name is yours to pick; the owner is your handle:

memoir push --create memories
✓ pushed main to feng-zhang/memories: 3 chunks (3 new) in 1.4 s, git in 2.6 s

Behind the scenes this validated the name locally, created the cloud store, set the git remote origin to https://<gateway>/feng-zhang/memories, uploaded the chunks the cloud lacked in multipart batches, and only then pushed the git history. The chunks are the ProllyTree node files that hold the actual memories. If a chunk upload fails, the git push is never attempted, so the cloud never points at data it does not have. Memoir also records which hashes the server confirmed under .git/memoir-cloud/pushed-origin, so a second push right away needs no round trip to find out that nothing is new:

✓ pushed main to feng-zhang/memories: 3 chunks (0 new) in 0.0 s, git in 0.9 s

memoir status and memoir remote show both tell you the address:

origin:   feng-zhang/memories
Gateway:  https://api-gateway-production-ab56.up.railway.app
Branch:   main
Created:  2026-10-03T14:02:11Z

If the name is taken you get store name already exists; pick another or run memoir remote add feng-zhang/memories. If the name is invalid (spaces, a leading dot, a .git suffix) memoir says so before contacting the server.

Pick it up on your desktop

You never create the local store by hand. The Claude Code plugin creates one per project on session start, and memoir creates one on first use. So on the second machine, open the same project, log in, and pull the cloud store by its address. With an address, pull links the remote first when it doesn't exist yet:

memoir login
memoir pull feng-zhang/memories
→ linked origin to feng-zhang/memories
✓ created main to 7d3f1a9 (3 new chunks)

Running the same command again just pulls what's new. If origin already points at a different cloud store, pull changes nothing and exits 1 with a hint: use --remote <other name> to add a second store, or memoir remote add <address> --force to switch. memoir remote add <address> followed by memoir pull still works if you prefer two steps.

Because the local store had never been used, pull adopted the cloud history outright. From here status, recall, and get see the laptop's memories:

memoir status
memoir recall "lint"

Linking resolves the address first. An unknown store, or one you do not own, fails with store feng-zhang/typo not found (or you don't own it) and nothing is written. After pull, memoir also checks that the chunk named by the store's root hash was downloaded.

If the local store already holds memories of its own, pull refuses rather than guess:

✗ local and cloud histories have diverged; cloud merge is not available yet. To discard the local memories on this branch and adopt the cloud copy: memoir pull --force --branch main

Either push those memories to their own cloud store (memoir remote remove, then memoir push --create <other-name>), or adopt the cloud copy with memoir pull --force, which replaces the local branch and keeps the tip it had before under refs/memoir/backup/<branch> (recover with git branch <name> refs/memoir/backup/<branch>).

Linking without typing the address

Run memoir remote add with no argument and it proposes <your handle>/<current directory name> and asks before resolving. In a project folder called memories that is feng-zhang/memories. A full https://<gateway>/<owner>/<store> URL is accepted in place of the address.

The daily loop

Treat it like git. Pull before you start, push when you finish:

memoir pull          # bring down anything the other machine pushed
# ... work; the agent captures memories ...
memoir push
✓ fast-forwarded main to 9c1e2f0 (2 new chunks)

fetch downloads refs and chunks without moving any local branch, for when you want to look before you merge:

✓ fetched 1 remote refs, 2 new chunks from feng-zhang/memories
When the cloud is ahead

You pushed from the desktop, forgot to pull on the laptop, and kept working there. Pushing from the laptop is refused with exit code 6:

✗ remote has commits you don't have; run `memoir pull` first

User branches on the cloud are fast-forward only, so one machine can never overwrite another's history. If the laptop has no new commits of its own, memoir pull then memoir push resolves it.

If both machines committed since the last sync, the histories have diverged and pull is refused too:

✗ local and cloud histories have diverged; cloud merge is not available yet

Cloud-side merge is planned but not available yet. Until then, pick a side. To keep the cloud version, force-pull. Look at what you are giving up first; afterwards the old tip is kept under refs/memoir/backup/main in case you need it:

memoir fetch                                  # cloud refs + chunks are now local
memoir diff main origin/main                  # see what differs before deciding
memoir pull --force                           # main := origin/main
memoir remember "..."                         # re-add anything that mattered
memoir push
✓ replaced main (was 3f9c2b1, kept at refs/memoir/backup/main) with origin/main at 9c1e2f0 (2 new chunks)

To keep the local version instead, unlink with memoir remote remove and start a new cloud store with memoir push --create <new-name>.

More than one branch

Every verb takes --branch. Push an experiment branch without touching main:

memoir branch experiments
memoir checkout experiments
memoir remember "Trying Ruff instead of flake8 on the side project"
memoir push --branch experiments

On the other machine, pull --branch creates the branch if it does not exist locally yet:

memoir pull --branch experiments
✓ created experiments to 4b7d0a1 (1 new chunks)

Branches named cloud/... belong to the cloud. They carry proposals the cloud generates for you, appear after fetch as origin/cloud/..., and cannot be pushed:

✗ 'cloud/dedupe/42' is a cloud-owned proposal branch and cannot be pushed
Scripting and agents

Every command honours --json (or MEMOIR_JSON=1). A sync step in a hook or CI job can branch on the exit code and read the counts:

if out=$(memoir --json push); then
  echo "$out" | jq '{origin, branch, chunks_uploaded, chunks_present}'
else
  case $? in
    6) memoir pull && memoir push ;;   # cloud was ahead, retry once
    1) echo "auth or network problem: $out" >&2 ;;
  esac
fi
{
  "success": true,
  "message": "pushed main to feng-zhang/memories: 4 chunks (1 new) in 1.1 s, git in 2.4 s",
  "branch": "main",
  "origin": "feng-zhang/memories",
  "chunks_uploaded": 1,
  "chunks_present": 3,
  "pushed": true,
  "seconds": 3.6,
  "chunk_seconds": 1.1,
  "git_seconds": 2.4
}

Every JSON result carries the address as origin. fetch adds chunks_downloaded and remote_refs; pull adds branch, created, tip, chunks_downloaded, forced, previous_tip, and backup_ref.

To use a different gateway, such as a staging deployment, pass --url to remote add or push --create, or set MEMOIR_CLOUD_URL once. After linking, the gateway lives on the origin URL, so the other verbs need neither.

Unlinking

memoir remote remove drops the git remote and nothing else. Local memories, history, and the cloud store are untouched.

Troubleshooting
MessageCauseWhat to do
Cloud sync requires a loginNo saved login and no MEMOIR_API_KEY.memoir login (or export MEMOIR_API_KEY=...)
not signed in: run memoir loginThe gateway returned 401.The key is wrong, expired or revoked: memoir login again.
not logged in to <gateway>No saved login for the gateway this remote (or --url) points at.memoir login --url <gateway>; memoir login --status shows what's saved. In a repo with no account at all, memoir login --agent.
<address> refused <branch>: branch limit (5) reached / memory limit (2000) exceeded on this branchThe store belongs to an agent account, which the cloud caps.memoir claim moves it to your account and lifts the caps.
your account has no handle yetYou have not chosen a handle.Open <gateway>/app in a browser and pick one.
store <owner>/<store> not found (or you don't own it)Unknown address, or a store belonging to someone else.Check the address with memoir remote show on the machine that created it.
"str_..." is a store idYou pasted an internal id.Use the <owner>/<store> address instead.
store name already exists--create with a name you already use.Pick another name, or memoir remote add <handle>/<name>.
remote 'origin' already exists (...); pass --force to replace itThe store is linked already.Use remote show, or remote add ... --force to relink.
remote has commits you don't have; run memoir pull first (exit 6)The cloud is ahead.memoir pull, then push again.
local and cloud histories have diverged (exit 6)Both sides have commits the other lacks: both machines captured since the last sync, or the local store grew memories before it was linked.See "When the cloud is ahead" above, or adopt the cloud copy with memoir pull --force.
root chunk ... is missing locally after syncA chunk download did not complete.Run memoir fetch again.
object store unavailable, retry laterThe cloud's object store answered 502 three times in a row.Wait a little and run memoir push again; chunks already written are not re-sent.
server rejected N chunk(s)The server refused some chunk parts (reason listed per chunk).Nothing was pushed to git. Fix or report the listed chunks, then push again.

Memoir never writes the key to disk and never prints the cloud's internal store ids. If either ever appears in output, that is a bug: please report it.

Other command groups

The rest of the CLI surface is documented inline via --help. Command groups at a glance:

GroupCommands--help
Storenew, connect, status, refresh, gc — gc reports the prolly node files no commit refers to any more (every write leaves the previous nodes behind) and deletes them with --apply; it walks every ref's commits, so branches, remotes, tags and backups all keep their nodesmemoir gc --help
Memoryremember, recall, get, forgetmemoir remember --help
Branchbranch, checkout, merge, time-travel, diff, branch-match — diff <a> <b> lists the memories that differ between two refs (+ added, ~ modified, - removed; --json adds changes with both values), read from the tree without checking either outmemoir branch --help
Cryptoproof, verify, blamememoir proof --help
Analysissummarizememoir summarize --help
Cloud syncremote, push, pull, fetch — stores addressed as <owner>/<store> (requires MEMOIR_API_KEY; see Cloud Sync)memoir push --help

For the underlying Python APIs these commands call into, see the API Reference.

512 files · 489 not served here

Advantages

  • Provides Git-like version control for AI memory, allowing for branching, merging, and rolling back. evidence: README.md
  • Uses hierarchical semantic paths for O(log n) lookups, offering better performance than traditional vector databases. evidence: README.md

Limitations

  • Requires an API key for LLM-powered features like intelligent classification and semantic search. evidence: README.md
  • Some advanced features like document watching require additional dependencies or manual configuration. evidence: pyproject.toml

Security

Risk level: Medium risk

This brain runs

Git hooks (5)

  • .pre-commit-config.yaml: pre-commit hooks from https://github.com/pre-commit/pre-commit-hooks at v6.0.0 (contributor tooling: runs only after pre-commit install) · uses the network
  • .pre-commit-config.yaml: pre-commit hooks from https://github.com/pycqa/isort at 6.0.1 (contributor tooling: runs only after pre-commit install) · uses the network
  • .pre-commit-config.yaml: pre-commit hooks from https://github.com/astral-sh/ruff-pre-commit at v0.12.9 (contributor tooling: runs only after pre-commit install) · uses the network
  • .pre-commit-config.yaml: pre-commit hooks from https://github.com/PyCQA/bandit at 1.8.6 (contributor tooling: runs only after pre-commit install) · uses the network
  • .pre-commit-config.yaml: pytest

Agent instructions that run or fetch something (73)

  • CLAUDE.md: `make ci` runs the full pipeline (lint, test, security, docs).
  • CLAUDE.md: tests use the fake gateway in `tests/fake_cloud.py` (real `git http-backend`, no network).
  • CLAUDE.md: When touching the mod run `claude plugin validate plugins/claude-code` and `claude plugin test plugins/claude-code`;
  • CLAUDE.md: Run with `pytest`.
  • CLAUDE.md: Deep structural details (layouts, refactor history, per-file line counts) intentionally omitted — use `rg` / `git log` when you need them.
  • CLAUDE.md: flipping it later (`git init`, or `rm -rf .git`) surfaces a warning at SessionStart but does not block writes.
  • CLAUDE.md: When changing a prompt, **run the harness against haiku before merging**.
  • CLAUDE.md: The harness has two modes: **gate** (deterministic shell-hook tests, no LLM, sub-second per case — pins the recall-trigger gate in `hooks/user-prompt-submit.sh`) and **LLM mode** (`run` / `case` / `adhoc` against `claude -p` for prompt templates).
  • CLAUDE.md: # Gate mode — no LLM cost, run on every commit.
  • CLAUDE.md: plugins/claude-code/tests/prompt-harness/runner.py run --prompt stop_capture --model haiku
  • CLAUDE.md: plugins/claude-code/tests/prompt-harness/runner.py run --prompt stop_capture --model sonnet
  • CLAUDE.md: Every run drops `system.txt` (the assembled prompt actually sent), `input.txt`, `output.txt`, `command.sh` (replayable), and `result.json` per case under `/tmp/memoir-prompt-tests/<UTC-timestamp>/`.
  • CLAUDE.md: Skill prompts (`skills/<name>/SKILL.md`) are evaluated by the orchestrating Claude rather than dispatched as system prompts to a model, so they are *not* covered by this harness — to test those, run the slash command in a real session and inspect behavior.
  • CLAUDE.md: **Build the docs locally:** `make docs` (mkdocs) → `site/index.html`, or `make docs-live` for auto-reload.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: bash -c 'source "${CLAUDE_PLUGIN_ROOT}/hooks/common.sh" >/dev/null 2>&1; in_git_repo && echo codebase:onboard || echo project:onboard'
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: Store: !`bash -c 'if [ -n "${MEMOIR_STORE:-}" ];
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `$MEMOIR` is a wrapper that resolves the right invocation for this machine — `memoir` on PATH if installed, otherwise `uvx --from memoir-ai==<pin> memoir`, otherwise `uv tool run --from memoir-ai==<pin> memoir` (pin lives in `scripts/resolve-memoir-cli.sh`).
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: Wrap **every** memoir call — both branches A and B, both reads and writes — in a subshell that cd's into the store first, and use `"$MEMOIR"` (NOT bare `memoir`) so the call works on machines without a global memoir install:
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `test.strategy` — test layout, how to run tests, what coverage emphasizes.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: bash -c 'source "${CLAUDE_PLUGIN_ROOT}/hooks/common.sh" >/dev/null 2>&1; concurrent_session_warning'
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: If the command prints anything, stop and report: "Concurrent session detected — run /memoir:onboard after the other session finishes, or set a distinct MEMOIR_STORE."
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `git log --oneline -20` and `git log --stat -5` for recent change patterns (informs lessons / rules).
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: Run `git log --stat <last_sha>..HEAD` to enumerate changed paths since the last onboarding pass.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: Run the confirmation check (`memoir status` → path == `$STORE_PATH`) before doing any writes.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `python3 ${CLAUDE_PLUGIN_ROOT}/skills/memoir-onboard/extractors.py walk <root>` — JSON list of `{path, size, mtime_ns, kind}` plus `snapshot_hash`.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `python3 ${CLAUDE_PLUGIN_ROOT}/skills/memoir-onboard/extractors.py extract <path>` — `key=value` blob for one file (with `kind=` first, `extractor.stdlib.fields=[…]` for provenance).
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `python3 ${CLAUDE_PLUGIN_ROOT}/skills/memoir-onboard/extractors.py snapshot-hash <root>` — just the hash.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `python3 ${CLAUDE_PLUGIN_ROOT}/skills/memoir-onboard/extractors.py tree <root>` — pruned tree.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: `python3 ${CLAUDE_PLUGIN_ROOT}/skills/memoir-onboard/extractors.py shape <root>` — `{shape, overview}` JSON.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: bash -c 'source "${CLAUDE_PLUGIN_ROOT}/hooks/common.sh" >/dev/null 2>&1; concurrent_session_warning'
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: For each file in the walk result, run `extractors.py extract <path>` and capture the structured blob.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: python3 -c "import json,sys; print('\n'.join(e['path'] for e in json.loads(sys.argv[1])['files']))" "$WALK_JSON" \
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: **added** (in walk, not in store) → run `extract <path>`, write `files.<san>.meta` and `files.<san>.summary`.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: **modified** (same path, different `(size, mtime_ns)`) → re-run `extract <path>`, write both keys.
  • plugins/claude-code/skills/memoir-onboard/SKILL.md: If a cold run fails partway through, the `_meta.*` keys act as commit markers.
  • plugins/claude-code/skills/memory-recall/SKILL.md: Run this preamble first and reuse `$STORE` and `$MEMOIR` for every memoir invocation below:
  • plugins/claude-code/skills/memory-recall/SKILL.md: `$MEMOIR` is a wrapper that resolves the right invocation for this machine — `memoir` on PATH if installed, otherwise `uvx --from memoir-ai==<pin> memoir`, otherwise `uv tool run --from memoir-ai==<pin> memoir` (pin lives in `scripts/resolve-memoir-cli.sh`).
  • plugins/claude-code/skills/memory-recall/SKILL.md: that way recall works on machines where memoir isn't `pip install`ed but `uv` is.
  • plugins/codex/skills/memoir-onboard/SKILL.md: bash -c 'source "${PLUGIN_ROOT}/hooks/common.sh" >/dev/null 2>&1; in_git_repo && echo codebase:onboard || echo project:onboard'
  • plugins/codex/skills/memoir-onboard/SKILL.md: Store: !`bash -c 'if [ -n "${MEMOIR_STORE:-}" ];
  • plugins/codex/skills/memoir-onboard/SKILL.md: python3 - "$manifest" <<'PY'
  • plugins/codex/skills/memoir-onboard/SKILL.md: `$MEMOIR` is a wrapper that resolves the right invocation for this machine — `memoir` on PATH if installed, otherwise `uvx --from memoir-ai==<pin> memoir`, otherwise `uv tool run --from memoir-ai==<pin> memoir` (pin lives in `scripts/resolve-memoir-cli.sh`).
  • plugins/codex/skills/memoir-onboard/SKILL.md: Wrap **every** memoir call — both branches A and B, both reads and writes — in a subshell that cd's into the store first, and use `"$MEMOIR"` (NOT bare `memoir`) so the call works on machines without a global memoir install:
  • plugins/codex/skills/memoir-onboard/SKILL.md: `test.strategy` — test layout, how to run tests, what coverage emphasizes.
  • plugins/codex/skills/memoir-onboard/SKILL.md: bash -c 'source "${PLUGIN_ROOT}/hooks/common.sh" >/dev/null 2>&1; concurrent_session_warning'
  • plugins/codex/skills/memoir-onboard/SKILL.md: If the command prints anything, stop and report: "Concurrent session detected - run memoir-onboard after the other session finishes, or set a distinct MEMOIR_STORE."
  • plugins/codex/skills/memoir-onboard/SKILL.md: `git log --oneline -20` and `git log --stat -5` for recent change patterns (informs lessons / rules).
  • plugins/codex/skills/memoir-onboard/SKILL.md: Run `git log --stat <last_sha>..HEAD` to enumerate changed paths since the last onboarding pass.
  • plugins/codex/skills/memoir-onboard/SKILL.md: Run the confirmation check (`memoir status` → path == `$STORE_PATH`) before doing any writes.
  • plugins/codex/skills/memoir-onboard/SKILL.md: `python3 ${PLUGIN_ROOT}/skills/memoir-onboard/extractors.py walk <root>` — JSON list of `{path, size, mtime_ns, kind}` plus `snapshot_hash`.
  • plugins/codex/skills/memoir-onboard/SKILL.md: `python3 ${PLUGIN_ROOT}/skills/memoir-onboard/extractors.py extract <path>` — `key=value` blob for one file (with `kind=` first, `extractor.stdlib.fields=[…]` for provenance).
  • plugins/codex/skills/memoir-onboard/SKILL.md: `python3 ${PLUGIN_ROOT}/skills/memoir-onboard/extractors.py snapshot-hash <root>` — just the hash.
  • plugins/codex/skills/memoir-onboard/SKILL.md: `python3 ${PLUGIN_ROOT}/skills/memoir-onboard/extractors.py tree <root>` — pruned tree.
  • plugins/codex/skills/memoir-onboard/SKILL.md: `python3 ${PLUGIN_ROOT}/skills/memoir-onboard/extractors.py shape <root>` — `{shape, overview}` JSON.
  • plugins/codex/skills/memoir-onboard/SKILL.md: bash -c 'source "${PLUGIN_ROOT}/hooks/common.sh" >/dev/null 2>&1; concurrent_session_warning'
  • plugins/codex/skills/memoir-onboard/SKILL.md: For each file in the walk result, run `extractors.py extract <path>` and capture the structured blob.
  • plugins/codex/skills/memoir-onboard/SKILL.md: python3 -c "import json,sys; print('\n'.join(e['path'] for e in json.loads(sys.argv[1])['files']))" "$WALK_JSON" \
  • plugins/codex/skills/memoir-onboard/SKILL.md: **added** (in walk, not in store) → run `extract <path>`, write `files.<san>.meta` and `files.<san>.summary`.
  • plugins/codex/skills/memoir-onboard/SKILL.md: **modified** (same path, different `(size, mtime_ns)`) → re-run `extract <path>`, write both keys.
  • plugins/codex/skills/memoir-onboard/SKILL.md: If a cold run fails partway through, the `_meta.*` keys act as commit markers.
  • plugins/codex/skills/memoir-onboard/SKILL.md: A subsequent forced memoir-onboard run will rewrite cleanly.
  • plugins/codex/skills/memoir-remember/SKILL.md: python3 - "$manifest" <<'PY'
  • plugins/codex/skills/memoir-remember/SKILL.md: bash "$PLUGIN_ROOT/scripts/ensure-store.sh" "$STORE" >/dev/null
  • plugins/codex/skills/memoir-status/SKILL.md: Run:
  • plugins/codex/skills/memoir-status/SKILL.md: python3 - "$manifest" <<'PY'
  • plugins/codex/skills/memoir-status/SKILL.md: bash "$PLUGIN_ROOT/scripts/status-cmd.sh"
  • plugins/codex/skills/memoir-ui/SKILL.md: Run:
  • plugins/codex/skills/memoir-ui/SKILL.md: python3 - "$manifest" <<'PY'
  • plugins/codex/skills/memoir-ui/SKILL.md: bash "$PLUGIN_ROOT/scripts/memoir-ui-ctl.sh" start "$STORE"
  • plugins/codex/skills/memory-recall/SKILL.md: Run this preamble first and reuse `$STORE` and `$MEMOIR` for every memoir invocation below:
  • plugins/codex/skills/memory-recall/SKILL.md: python3 - "$manifest" <<'PY'
  • plugins/codex/skills/memory-recall/SKILL.md: `$MEMOIR` is a wrapper that resolves the right invocation for this machine — `memoir` on PATH if installed, otherwise `uvx --from memoir-ai==<pin> memoir`, otherwise `uv tool run --from memoir-ai==<pin> memoir` (pin lives in `scripts/resolve-memoir-cli.sh`).
  • plugins/codex/skills/memory-recall/SKILL.md: that way recall works on machines where memoir isn't `pip install`ed but `uv` is.

Install scripts (2)

  • Makefile (make install): pip install -e .
  • README.md: curl -LsSf https://astral.sh/uv/install.sh | sh · uses the network

MCP servers (1)

  • README.md (memoir): uvx --from memoir-ai[mcp] memoir-mcp

Hooks (7)

  • plugins/claude-code/hooks/hooks.json (SessionStart): bash ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh
  • plugins/claude-code/hooks/hooks.json (UserPromptSubmit): bash ${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit.sh
  • plugins/claude-code/hooks/hooks.json (Stop): bash ${CLAUDE_PLUGIN_ROOT}/hooks/stop.sh
  • plugins/claude-code/hooks/hooks.json (SessionEnd): bash ${CLAUDE_PLUGIN_ROOT}/hooks/session-end.sh
  • plugins/codex/hooks/hooks.json (SessionStart): bash "${PLUGIN_ROOT}/hooks/session-start.sh"
  • plugins/codex/hooks/hooks.json (UserPromptSubmit): bash "${PLUGIN_ROOT}/hooks/user-prompt-submit.sh"
  • plugins/codex/hooks/hooks.json (Stop): bash "${PLUGIN_ROOT}/hooks/stop.sh"
  • Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:2)
  • Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:23)
  • Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:30)
  • Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:40)
  • Medium risk: runs-install-script-remote-exec (README.md:86)
  • Medium risk: runs-mcp-server-unpinned-runner (README.md:153)
  • Low risk: network-instructions (Makefile:37)
  • Low risk: scripts-present (benchmarks/classifier.py)
  • Low risk: scripts-present (benchmarks/locomo/run.py)
  • Low risk: scripts-present (plugins/claude-code/hooks/session-end.sh)
  • Low risk: scripts-present (plugins/claude-code/hooks/session-start.sh)
  • Low risk: scripts-present (plugins/claude-code/hooks/stop.sh)
  • Low risk: scripts-present (plugins/claude-code/hooks/user-prompt-submit.sh)
  • Low risk: network-instructions (plugins/claude-code/skills/memory-recall/SKILL.md:20)
  • Low risk: scripts-present (plugins/codex/hooks/session-start.sh)
  • Low risk: scripts-present (plugins/codex/hooks/stop.sh)
  • Low risk: scripts-present (plugins/codex/hooks/user-prompt-submit.sh)
  • Low risk: network-instructions (plugins/codex/skills/memory-recall/SKILL.md:36)
  • Low risk: network-instructions (pyproject.toml:57)
  • Low risk: scripts-present (scripts/cc-smoke/run.sh)
  • Low risk: scripts-present (scripts/check_version_consistency.py)

Attribution and licence

First committed by
GitHub avatar of zhangfengcdtzhangfengcdt
Declared authors
  • zhangfengcdt (declared in pyproject.toml)
Publisher
Feng Zhang (Community)
Source
zhangfengcdt/memoir · commit 7fd1b3e
Licence
Apache License 2.0 (files served here)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Contributors
zhangfengcdt, rapidSpace, disafronov, KevFoxCodeCraft, Ottohere-Mourn

AutoGineer is not affiliated with or endorsed by zhangfengcdt.

Install from source

489 of its files are not served here, so there is no ZIP. zhangfengcdt/memoir at 7fd1b3e