Mai Setup — Initialization and Sync
First-time setup
mai init # local only — no remote, no push
mai init --remote forgejo # enable auto-push to a remote
mai init --remote forgejo --block github.com # push to forgejo, block github
This creates:
.maitake/hooks/pre-write— scans for secrets before every note write.maitake/config.toml— sync remote + blocked hosts.gitignoreentry — keeps.maitake/out of the repo
Tip: Long notes use the pipe pattern — write to
/tmp, pipe intomai add-note. (See mai-agent skill.)
What each flag does
| Flag | What | Example |
|---|---|---|
--remote <name> |
Push notes to this git remote after every write | --remote forgejo |
--block <host> |
Never push notes to this host (repeatable) | --block github.com |
Default behavior
- No
--remote→ notes are local only, nothing pushes anywhere - Default blocked →
github.com(even when a remote is configured) - No flags at all → fully local, private, zero network activity
Config file
.maitake/config.toml:
[sync]
remote = "forgejo"
blocked-hosts = ["github.com", "gitlab.com"]
[docs]
sync = "auto" # "auto" | "manual" | "off"
dir = ".mai-docs"
[hooks]
pre-write = true
post-push = true
Edit directly or re-run mai init. Legacy flat-format config files are still read for backwards compatibility.
How sync works
Auto-push (after every write)
When a remote is configured, every mai create, mai close, mai add-note, etc. auto-pushes refs/notes/maitake to the remote.
If the push is rejected (remote diverged):
- Fetch + merge using
cat_sort_uniq(set-union on note lines) - Retry push
- If still fails, warn to stderr — the write still succeeds locally
Manual sync
mai sync
Fetch + merge + push in one command. Use after cloning a repo that already has notes on the remote.
Privacy
Git notes don't push with git push — git ignores refs/notes/* by default.
maitake only pushes to the remote you configure in .maitake/config.toml.
Blocked hosts are checked before every push. No remote configured = nothing
leaves your machine.
After cloning a repo with existing notes
git clone <url>
cd repo
mai init --remote origin
mai sync # pulls existing notes from remote
mai ls # see the work queue
mai search "topic" # search across all notes
Guard hooks
.maitake/hooks/pre-write runs before every note write. It receives the JSON note content on stdin. Exit non-zero to reject.
Default hook: tries gitleaks, falls back to regex patterns for common secrets (AWS keys, GitHub tokens, private keys, JWTs).
Replace with your own:
# Custom pre-write hook
cat > .maitake/hooks/pre-write << 'EOF'
#!/bin/bash
set -euo pipefail
# Your custom scanning here
my-scanner --stdin
EOF
chmod +x .maitake/hooks/pre-write
Troubleshooting
mai doctor # graph health, note counts, broken edges
mai ls --status=all # everything including closed
mai kinds # what kinds of notes exist
git notes --ref=refs/notes/maitake list # raw git notes list