git-as-memory is a small TypeScript library for storing agent memory directly in a Git object database.
It follows the same core idea as checkpoint systems that write agent state into Git refs:
- no branch checkout
- no working tree changes
- no mutation of the repository's normal index
- append-only history through commits
- versioned storage namespace under a dedicated ref
Default storage ref:
refs/git-as-memory/memory/v1
Default tree layout:
.git-as-memory/schema.json
memories/<type>/<id>/memory.json
memories/<type>/<id>/source.md
memories/<type>/<id>/events.jsonl
TypeScript is the best default for this project because it fits the Minion Mind/Electron/Node ecosystem and can be used as both a CLI and an embeddable SDK. The current backend calls canonical git plumbing commands for correctness and speed of iteration. A later backend can use isomorphic-git when browser support or a no-native-git runtime matters.
isomorphic-git is useful reference material for Git internals: object storage, refs, index handling, packfiles, and API layering. For this PoC, the system Git binary keeps the implementation small while preserving real Git semantics.
npx skills add https://github.com/femto/skills --skill git-as-memoryOr via OpenClaw:
openclaw skills install git-as-memorynpm install
npm run buildLocal CLI:
node dist/cli.js --helpOr through package bins after linking/installing:
gam --help
git-as-memory --helpInside any Git repo:
gam init
gam write "User prefers concise technical answers." \
--type entity \
--id user-preference-concise \
--tag preference \
--source "Learned from a conversation where the user corrected over-explanation."
gam list
gam glob "entity/*"
gam read entity/user-preference-concise
gam show user-preference-concise
gam search concise
gam history user-preference-conciseEquivalent without linking:
node /path/to/git-as-memory/dist/cli.js write "A memory" --repo /path/to/repogam init [--repo .] [--ref refs/git-as-memory/memory/v1]
gam write <content> [--repo .] [--type semantic] [--id id] [--tag tag] [--source text]
gam write --stdin [--source-file context.md] [--events-file events.jsonl]
gam list [--repo .] [--all] [--json]
gam glob [pattern] [--repo .] [--files] [--json]
gam read <id|type/id> [--repo .] [--json]
gam show <id> [--repo .] [--type semantic] [--json]
gam search <query> [--repo .] [--json]
gam history <id> [--repo .] [--type semantic] [--json]
gam delete <id> [--repo .] [--type semantic]
gam purge <id> [--repo .] [--type semantic]
delete writes a tombstone into memory.json so history and provenance remain available. purge removes the current files from the memory ref while Git history still retains old commits.
glob is memory-native. It matches memory keys in the form <type>/<id>, and also matches bare ids:
gam glob "entity/*"
gam glob "user-*"
gam glob "*preference*"Use --files only when you want the underlying Git tree paths:
gam glob "entity/*" --filesmemory.json:
{
"schema_version": 1,
"id": "user-preference-concise",
"type": "entity",
"content": "User prefers concise technical answers.",
"tags": ["preference"],
"metadata": {},
"created_at": "2026-05-18T13:40:00.000Z",
"updated_at": "2026-05-18T13:40:00.000Z"
}source.md is for human/model readable provenance. events.jsonl is for a complete event stream when an agent runtime wants replay or audit support.
The memory store is ordinary Git data:
git log --oneline refs/git-as-memory/memory/v1
git ls-tree -r --name-only refs/git-as-memory/memory/v1
git show refs/git-as-memory/memory/v1:memories/entity/user-preference-concise/memory.jsonThe current working branch and files are not touched.