agentdiff
Audit and trace autonomous AI code contributions in git repositories.
What is agentdiff?
agentdiff tracks who (which AI agent) wrote what code in your repository. It captures the agent name, model, prompt, and line-level attribution for every AI-assisted edit — storing this metadata for audit trails, compliance, and accountability.
Installation
# Install latest release (recommended)
|
# Install a specific version
|
# Install from crate source
# Build release and copy manually
Quick Start
# Initialize tracking in a repository
# Start MCP server (stdio) for agent integrations
# Make some AI-assisted edits, then commit
# List all captured entries
# Show one commit's full ledger details
# See line-by-line blame for a file
# View statistics
# Generate CI report (stdout, or --out-md / --out-annotations for files)
# optional filters: --since RFC3339 --agent substring --model substring
Commands
| Command | Description |
|---|---|
agentdiff init |
Initialize tracking in current repository |
agentdiff list |
List all captured attribution entries |
agentdiff blame <file> |
Show line-level attribution (like git-blame) |
agentdiff stats |
Show aggregate statistics by agent/file/model |
agentdiff report |
CI report: markdown and/or GitHub-style annotations (--out-md, --out-annotations, --agent, --model, --since) |
agentdiff diff [<commit>] |
Show attribution changes in a commit |
agentdiff log |
Show chronological history |
agentdiff show <sha> |
Show one ledger entry by commit SHA |
agentdiff ledger repair |
Normalize and de-duplicate .agentdiff/ledger.jsonl |
agentdiff ledger import-notes |
Import legacy refs/notes/agentdiff into ledger |
agentdiff sync-notes |
Legacy: fetch refs/notes/agentdiff for migration |
agentdiff config |
Manage configuration |
How It Works
-
Hook Installation —
agentdiff initinstalls:- Git
pre-commithook to snapshot staged AI attribution context - Git
post-commithook to append one commit-scoped ledger line - Claude Code PostToolUse hook
- Cursor afterFileEdit hook
- Codex notify hook
- Gemini/Antigravity BeforeTool/AfterTool hooks
- Windsurf repo-level hooks
- OpenCode repo-level plugin
- VS Code Copilot extension (
~/.vscode/extensions/agentdiff-copilot-0.1.0/)
- Git
-
Capture — When you use AI tools:
- Claude Code → PostToolUse hook fires on Edit/Write/MultiEdit
- Cursor → afterFileEdit/afterTabFileEdit hooks fire
- Codex → notify hook fires on turn completion
- Gemini/Antigravity → BeforeTool/AfterTool hooks fire on write_file/replace
- Windsurf → post_write_code hook fires on code write
- OpenCode → plugin fires on tool.execute.after
- GitHub Copilot → VS Code extension captures inline completions and chat edits on save
- Each capture writes to
<repo>/.git/agentdiff/session.jsonl - Optional MCP writes context to
<repo>/.git/agentdiff/pending.json
-
Commit — On
git commit:- Pre-commit hook writes
<repo>/.git/agentdiff/pending-ledger.json - Post-commit hook finalizes one line into
<repo>/.agentdiff/ledger.jsonl - By default, post-commit auto-amends the commit to include ledger changes
- Pending files are cleared after finalize
- Pre-commit hook writes
-
View — Use CLI commands to inspect captured data
Configuration
Config stored at ~/.agentdiff/config.toml
= "1.0"
= "~/.agentdiff/spillover" # optional spillover for no-repo captures
= "~/.agentdiff/scripts"
= true
[[]]
= "/home/user/project"
= "-home-user-project"
Disable same-commit amend behavior:
Supported Agents
- Claude Code — via PostToolUse hook
- Cursor — via afterFileEdit/afterTabFileEdit hooks
- Codex CLI — via
notifyhook - Gemini/Antigravity — via
~/.gemini/settings.jsonhooks (write_file|replace) - Windsurf — via
post_write_codehook - OpenCode — via
.opencode/plugins/agentdiff.ts - GitHub Copilot (VS Code) — via VS Code extension installed to
~/.vscode/extensions/ - MCP context writer — via
record-context.py(writes.git/agentdiff/pending.json) - Manual batch fallback —
capture-antigravity.py --prompt "..." --model "..."
MCP Server
agentdiff-mcp is a real MCP stdio server.
Supported methods:
initializetools/listtools/callfor toolrecord_context
record_context writes context to <repo>/.git/agentdiff/pending.json, which is consumed by agentdiff pre/post commit hooks and attached to the next ledger line.
Example record_context arguments:
MCP Client Config
Minimal MCP stdio config is provided at:
examples/mcp/agentdiff-mcp.json
Generic server block:
Use this same command in Claude/Cursor/Codex/OpenCode MCP settings.
End-to-End Testing
1) Reinstall latest binaries and scripts
2) MCP flow test (commit should include prompt/model/session)
# In repo root
# In another terminal, send tools/call record_context via your MCP client
# then make a small edit + git add + git commit
3) Hook-only fallback test (no MCP)
# Make an AI edit from Cursor/Codex/Windsurf/Claude, then commit
4) Cursor diagnostics (if entry is missing)
# make one Cursor edit + commit
4b) Codex / Gemini diagnostics (if entry is missing)
# make one edit in Codex or Gemini, then commit
5) Edge cases to validate
- Empty or malformed hook payloads should not crash capture scripts.
afterTabFileEditevents should still attribute file/line/model without prompt.- Events with Windows-style backslash paths should resolve to repo-local paths.
- If hook
cwdis not repo (for example~/.cursor), file-path-based repo resolution should still write to<repo>/.git/agentdiff/session.jsonl. - Commits with no staged overlap against captured lines should fall back to
human. - Duplicate finalize on same SHA should not append duplicate ledger rows.
Release Process
Tagging v* triggers release workflow:
- Runs Rust + Python tests and MCP smoke test
- Builds
agentdiffandagentdiff-mcpartifacts for Linux/macOS/Windows - Publishes
SHA256SUMS - Creates GitHub Release with artifacts
- Optionally publishes crate to crates.io when
CARGO_REGISTRY_TOKENis set
Output Formats
List Output
# — COMMIT TIME AGENT MODEL TOOL FILE LINES PROMPT
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 a1b2c3d4 Mar 20 17:52 claude-code sonnet-4-6 Edit src/auth/tokens.py 17-24 "add auth middleware"
2 a1b2c3d4 Mar 20 17:55 cursor gpt-4o afterFileEdit src/main.rs 1 "add main entry"
* a1b2c3e5 Mar 20 18:02 claude-code sonnet-4-6 Write src/utils.rs 1-94 "refactor utils" (uncommitted)
Blame Output
agentdiff blame — src/main.rs
───────────────────────────────────────────────────────────────────────────────────────────────────
1 human fn main() {
2 human use anyhow::Result;
3 claude-code use std::process::Command; (Edit)
4 human
5 cursor fn run() -> Result<()> { (afterFileEdit)
Stats Output
agentdiff — Statistics
Total lines tracked: 2847
By Agent:
claude-code 1847 (65%) ████████████████████
cursor 647 (23%) ████████
human 353 (12%) ████
By File:
src/main.rs 340 lines (78% AI) — claude-code
src/auth/mod.rs 220 lines (65% AI) — cursor
Use Cases
- Security audits — Know which AI generated risky code
- Compliance — SOC2, ISO 27001 require knowing what generated production code
- Code review — Identify AI-authored code requiring extra scrutiny
- Attribution — Track prompts driving major changes
VS Code Copilot Extension
agentdiff init installs a plain-JavaScript VS Code extension directly into
~/.vscode/extensions/agentdiff-copilot-0.1.0/. No npm install or build step
is needed. Restart VS Code after running agentdiff init to activate it.
The extension:
- Detects GitHub Copilot inline completions (multi-character/multi-line insertions)
- Flushes captured lines to
session.jsonlon file save - Exposes command "agentdiff: Capture Copilot edits for current file" for manual capture
To skip Copilot setup: agentdiff init --no-copilot
To skip Gemini/Antigravity setup: agentdiff init --no-antigravity
Note: The extension uses a heuristic — insertions of ≥10 characters or multiple lines while Copilot is active are attributed to Copilot. Short single-character insertions are treated as manual typing.
Architecture
~/.agentdiff/
├── config.toml ← Global configuration
├── scripts/ ← Python capture scripts
│ ├── capture-claude.py
│ ├── capture-cursor.py
│ ├── capture-codex.py
│ ├── capture-windsurf.py
│ ├── capture-opencode.py
│ ├── capture-copilot.py
│ ├── prepare-ledger.py
│ ├── finalize-ledger.py
│ ├── record-context.py
│ ├── capture-antigravity.py
│ └── write-note.py ← legacy notes writer (migration only)
└── spillover/ ← Optional no-repo event spillover
~/.vscode/extensions/
└── agentdiff-copilot-0.1.0/
├── package.json ← VS Code extension manifest
└── extension.js ← Copilot capture logic (plain JS, no build needed)
<repo>/.agentdiff/
└── ledger.jsonl ← Canonical committed append-only attribution log
<repo>/.git/agentdiff/
├── session.jsonl ← Uncommitted per-repo buffer from hooks/agents
├── pending.json ← Ephemeral MCP context handoff
└── pending-ledger.json ← Pre-commit snapshot finalized in post-commit
<repo>/.windsurf/
└── hooks.json ← Windsurf repo-level hook config
<repo>/.opencode/plugins/
└── agentdiff.ts ← OpenCode repo-level plugin
git refs (legacy migration source):
└── refs/notes/agentdiff
Requirements
- Rust 1.85+
- Python 3.7+ (for capture scripts)
- Git repository
License
Dual-licensed under:
- MIT (LICENSE-MIT)
- Apache-2.0 (LICENSE-APACHE)