botrun-msync — Git-backed Memory Sync CLI for Agents
bms manages persistent memory for AI agents across ephemeral VMs. Memories are stored as files in Git repos (GitHub / GitLab), and bms handles the git plumbing — clone, sync, and scope management. Agents read/write memory files directly using their own tools.
Install
npx botrun-msync --help
Quick Start
npx botrun-msync config add-scope my-notes \
--repo github.com/your-org/agent-memory \
--token-env MY_GITHUB_TOKEN \
--description "My personal notes" \
--access readwrite
export MY_GITHUB_TOKEN=ghp_xxxxx
npx botrun-msync memory init
npx botrun-msync memory sync
Concepts
Scope
A scope is a logical name that maps to a git repo. Each agent can have multiple scopes pointing to different repos.
npx botrun-msync config add-scope my-notes \
--repo github.com/org/my-memory \
--token-env BMS_TOKEN_NOTES \
--description "Personal research notes" \
--access readwrite
Multi-Repo Architecture
Different scopes can point to different repos. Permissions are controlled by Git provider tokens — not by bms. Each scope binds to its own token via --token-env, enabling per-repo permission control.
npx botrun-msync config add-scope director \
--repo github.com/org/director-memory \
--token-env BMS_TOKEN_DIRECTOR \
--description "Director personal research" \
--access readwrite
npx botrun-msync config add-scope team1 \
--repo github.com/org/team1-memory \
--token-env BMS_TOKEN_TEAMS \
--description "Team 1 memory" \
--access readonly
npx botrun-msync config add-scope team2 \
--repo github.com/org/team2-memory \
--token-env BMS_TOKEN_TEAMS \
--description "Team 2 memory" \
--access readonly
Create separate GitHub Fine-grained PATs with different permissions:
BMS_TOKEN_DIRECTOR → Contents: Read and write (only director-memory repo)
BMS_TOKEN_TEAMS → Contents: Read-only (only team1-memory + team2-memory repos)
This way, even if a user modifies the config, they can't write to repos their token doesn't allow.
Config
Base Path
All bms data lives under a single base directory:
~/.botrun/bms/ ← default base path
├── config.json ← scope definitions
└── data/
├── my-notes/ ← git clone of my-notes scope
├── team1/ ← git clone of team1 scope
└── team2/ ← git clone of team2 scope
Override with CLI option or environment variable:
npx botrun-msync --bms-path /tmp/test-bms memory init
BMS_PATH=/custom/path npx botrun-msync memory init
Priority: --bms-path > BMS_PATH > ~/.botrun/bms/
Config File
Located at <BMS_PATH>/config.json (default: ~/.botrun/bms/config.json).
Override config path independently with: BMS_CONFIG=/path/to/config.json
{
"scopes": {
"my-notes": {
"repo": "github.com/org/member1-memory",
"token_env": "BMS_TOKEN_NOTES",
"description": "Personal research notes",
"access": "readwrite"
},
"team1": {
"repo": "github.com/org/team1-memory",
"branch": "dev",
"token_env": "BMS_TOKEN_TEAMS",
"description": "Team 1 memory",
"access": "readonly"
}
}
}
repo | yes | Git repo URL (without https://) |
branch | no | Git branch to use. Omit = repo default branch |
token_env | no | Env var name for this scope's token (for per-repo permission control) |
description | no | Description for agent context |
access | no | Access hint for agent: readwrite or readonly (default: readwrite) |
provider | no | github or gitlab. Auto-detected from URL |
Config Commands
npx botrun-msync config add-scope <name> --repo <url> [--branch <branch>] [--token-env <envVar>] [--description <text>] [--access <mode>]
npx botrun-msync config remove-scope <name>
npx botrun-msync config show
Environment Variables
BMS_PATH | Base directory for all bms data (default: ~/.botrun/bms) |
BMS_CONFIG | Config file path (overrides <BMS_PATH>/config.json) |
Each scope's token is configured via --token-env, which points to an environment variable name. There are no global token variables — every scope must declare its own.
Memory Commands
npx botrun-msync memory init
Clones all configured scope repos to <BMS_PATH>/data/<scope-name>/. If already cloned, pulls latest.
{
"scopes": {
"my-notes": { "local": "/root/.botrun/bms/data/my-notes" },
"team1": { "local": "/root/.botrun/bms/data/team1" }
}
}
npx botrun-msync memory scopes
Lists all scopes with their repo, description, access, and local filesystem path.
{
"scopes": {
"my-notes": {
"repo": "github.com/org/member1-memory",
"description": "Personal research notes",
"access": "readwrite",
"local": "/root/.botrun/bms/data/my-notes"
},
"team1": {
"repo": "github.com/org/team1-memory",
"description": "Team 1 memory",
"access": "readonly",
"local": "/root/.botrun/bms/data/team1"
}
}
}
npx botrun-msync memory sync
Commits and pushes all changed memory files back to remote repos.
{
"synced": ["my-notes"],
"skipped": ["team1"]
}
JSON Output
All commands output structured JSON, including --help:
npx botrun-msync --help
npx botrun-msync config --help
npx botrun-msync memory --help
Agent Lifecycle
VM starts
→ npx botrun-msync memory init # clone repos to <BMS_PATH>/data/
→ agent reads/writes files # using native tools (Read, Write, grep)
→ npx botrun-msync memory sync # push changes
VM destroyed
Development
npm install
npm test
License
MIT