git-memento is a Git extension that records the AI coding session used to produce a commit.
It runs a commit and then stores a cleaned markdown conversation as a git note on the new commit.
- Create commits with normal Git flow (
-mor editor). - Attach the AI session trace to the commit (
git notes). - Keep provider support extensible (Codex first, others later).
- Produce human-readable markdown notes.
Initialize per-repository memento settings:
git memento init
git memento init codex
git memento init claudeinit stores configuration in local git metadata (.git/config) under memento.*.
git memento commit <session-id> -m "Normal commit message"
git memento commit <session-id> -m "Subject line" -m "Body paragraph"
git memento amend -m "Amended subject"
git memento amend <new-session-id> -m "Amended subject" -m "Amended body"
git memento audit --range main..HEAD --strict
git memento doctorOr:
git memento commit <session-id>You can pass -m multiple times, and each value is forwarded to git commit in order.
When -m is omitted, git commit opens your default editor.
amend runs git commit --amend.
- Without a session id, it copies the note(s) from the previous HEAD onto the amended commit.
- With a session id, it copies previous note(s) and appends the new fetched session as an additional session entry.
- A single commit note can contain sessions from different AI providers.
Share notes with the repository remote (default: origin):
git memento share-notes
git memento share-notes upstreamThis pushes refs/notes/* and configures local remote.<name>.fetch so notes can be fetched by teammates.
Push your branch and sync notes to the same remote in one command (default: origin):
git memento push
git memento push upstreamThis runs git push <remote> and then performs the same notes sync as share-notes.
Sync and merge notes from a remote safely (default remote: origin, default strategy: cat_sort_uniq):
git memento notes-sync
git memento notes-sync upstream
git memento notes-sync upstream --strategy unionThis command:
- Ensures notes fetch mapping is configured.
- Creates a backup ref under
refs/notes/memento-backups/<timestamp>. - Fetches remote notes into
refs/notes/remote/<remote>/*. - Merges remote notes into local notes and pushes synced notes back to the remote.
Configure automatic note carry-over for rewritten commits (rebase / commit --amend):
git memento notes-rewrite-setupThis sets local git config:
notes.rewriteRef=refs/notes/commitsnotes.rewriteMode=concatenatenotes.rewrite.rebase=truenotes.rewrite.amend=true
Carry notes from a rewritten range (for squash/rewrite flows) onto a new target commit:
git memento notes-carry --onto <new-commit> --from-range <base>..<head>This reads notes from commits in <base>..<head> and appends a provenance block to <new-commit>.
Audit note coverage and note metadata in a commit range:
git memento audit --range main..HEAD
git memento audit --range origin/main..HEAD --strict --format json- Reports commits with missing notes (
missing-note <sha>). - Validates note metadata markers (
- Provider:and- Session ID:). - In
--strictmode, invalid note structure fails the command.
Run repository diagnostics for provider config, notes refs, and remote sync posture:
git memento doctor
git memento doctor upstream --format jsonShow command help:
Show installed tool version (major.minor + commit metadata when available):
Provider defaults can come from env vars, and init persists the selected provider + values in local git config:
MEMENTO_AI_PROVIDER(default:codex)MEMENTO_CODEX_BIN(default:codex)MEMENTO_CODEX_GET_ARGS(default:sessions get {id} --json)MEMENTO_CODEX_LIST_ARGS(default:sessions list --json)MEMENTO_CLAUDE_BIN(default:claude)MEMENTO_CLAUDE_GET_ARGS(default:sessions get {id} --json)MEMENTO_CLAUDE_LIST_ARGS(default:sessions list --json)
Set MEMENTO_AI_PROVIDER=claude to use Claude Code.
Runtime behavior:
- If the repository is not configured yet,
commit,amend <session-id>,push,share-notes,notes-sync,notes-rewrite-setup, andnotes-carryfail with a message to rungit memento initfirst. - Stored git metadata keys include:
memento.providermemento.codex.bin,memento.codex.getArgs,memento.codex.listArgsmemento.claude.bin,memento.claude.getArgs,memento.claude.listArgs
If a session id is not found, git-memento asks Codex for available sessions and prints them.
Requires .NET SDK 10 and native toolchain dependencies for NativeAOT.
dotnet publish src/GitMemento.Cli/GitMemento.Cli.fsproj -c Release -r osx-arm64 -p:PublishAot=truedotnet publish src/GitMemento.Cli/GitMemento.Cli.fsproj -c Release -r linux-x64 -p:PublishAot=truedotnet publish src/GitMemento.Cli/GitMemento.Cli.fsproj -c Release -r win-x64 -p:PublishAot=trueGit discovers commands named git-<name> in PATH.
- Publish for your platform.
- Copy the produced executable to a directory in your
PATH. - Ensure the binary name is
git-memento(orgit-memento.exeon Windows).
Then run:
git memento commit <session-id> -m "message"Install from latest GitHub release:
curl -fsSL https://raw.githubusercontent.com/mandel-macaque/memento/main/install.sh | sh- Release assets are built with NativeAOT (
PublishAot=true) and packaged as a single executable per platform. - If the workflow runs from a tag push (for example
v1.2.3), that tag is used as the GitHub release tag/name. - If the workflow runs from
mainwithout a tag, the release tag becomes<Version>-<shortSha>(for example1.0.0-a1b2c3d4). install.shalways downloads fromreleases/latest, so the installer follows the latest published GitHub release.
CI runs install smoke tests on Linux, macOS, and Windows that verify:
install.shdownloads the latest release asset for the current OS/architecture.- The binary is installed for the current user into the configured install directory.
git memento --versionandgit memento helpboth execute after installation.
dotnet test GitMemento.slnx
npm run test:jsThis repository includes a reusable marketplace action with two modes:
mode: comment(default): readsgit notescreated bygit-mementoand posts a commit comment.mode: gate: runsgit memento auditas a CI gate and fails if note coverage checks fail.git-mementomust already be installed in the job.
Action definition:
action.ymlat repository root.install/action.ymlfor reusable git-memento installation.- Renderer source:
src/note-comment-renderer.ts - Runtime artifact committed for marketplace consumers:
dist/note-comment-renderer.js
Example workflow:
name: memento-note-comments
on:
push:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: write
pull-requests: read
jobs:
comment-memento-notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: mandel-macaque/memento@v1
with:
mode: comment
github-token: ${{ secrets.GITHUB_TOKEN }}Inputs:
github-token(default:${{ github.token }})mode(default:comment) -commentorgatenotes-fetch-refspec(default:refs/notes/*:refs/notes/*)max-comment-length(default:65000)audit-range(optional, gate mode)base-ref(optional, gate mode pull request inference)strict(default:true, gate mode)
Installer action inputs:
memento-repo(default:mandel-macaque/memento, release asset source)install-dir(default:${{ runner.temp }}/git-memento-bin)verify(default:true)
CI gate example:
name: memento-note-gate
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
jobs:
enforce-memento-notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: mandel-macaque/memento/install@v1
with:
memento-repo: mandel-macaque/memento
- uses: mandel-macaque/memento@v1
with:
mode: gate
strict: "true"Installer action example:
- uses: mandel-macaque/memento/install@v1
with:
memento-repo: mandel-macaque/mementoLocal workflow in this repository:
.github/workflows/memento-note-comments.yml.github/workflows/memento-note-gate.yml
- Build and commit the action renderer artifact:
npm ci
npm run build:action
git add src/note-comment-renderer.ts dist/note-comment-renderer.js- Ensure
action.ymlandinstall/action.ymlare in the default branch and README documents usage. - Create and push a semantic version tag:
git tag -a v1.0.0 -m "Release GitHub Action v1.0.0"
git push origin v1.0.0
git tag -f v1 v1.0.0
git push -f origin v1- In GitHub, open your repository page:
Releases->Draft a new release-> choosev1.0.0-> publish.
- Open the
Marketplace(GitHub Store) publishing flow from the repository and submit listing metadata. - Keep the major tag (
v1) updated to the latest compatible release.
- Notes are written with
git notes add -f -m "<markdown>" <commit-hash>. - Multi-session notes use explicit delimiters:
<!-- git-memento-sessions:v1 --><!-- git-memento-note-version:1 --><!-- git-memento-session:start --><!-- git-memento-session:end -->
- Legacy single-session notes remain supported and are upgraded to the versioned multi-session envelope when amend needs to append a new session.
- Conversation markdown labels user messages with your git alias (
git config user.name) and assistant messages with provider name. - Serilog debug logs are enabled in
DEBUGbuilds.