acd watches a Git worktree and turns file edits into local commits while you
keep working. It is built for AI coding tools such as Claude Code, Codex,
Cursor, OpenCode, and Pi, but the daemon itself is just a static Go binary.
flowchart LR
Tool["AI tool hook"] --> CLI["acd start / wake / flush"]
CLI --> Daemon["acd daemon"]
Daemon --> Store[("state.db<br/>and git blobs")]
Store --> Replay["scratch index replay"]
Replay --> Commit["git commit<br/>update-ref"]
classDef hook fill:#243447,stroke:#7aa2f7,color:#e6edf3
classDef daemon fill:#203a31,stroke:#9ece6a,color:#eaffdf
classDef store fill:#3d2f1f,stroke:#f6c177,color:#fff4d6
class Tool,CLI hook
class Daemon,Replay daemon
class Store,Commit store
brew install KristjanPikhof/tap/acdOther options:
curl -fsSL https://raw.githubusercontent.com/KristjanPikhof/Auto-Commit-Daemon/main/scripts/install.sh | sh
go install github.com/KristjanPikhof/Auto-Commit-Daemon/cmd/acd@latestRun the setup command for the tool you use, then paste the printed snippet into
the target config file. Do not redirect with > when you already have custom
hooks, because that replaces the whole file.
acd setup claude-code
acd setup codex
acd setup cursor
acd setup opencode
acd setup pi
acd setup shell| Tool | Config file | Notes |
|---|---|---|
| Claude Code | ~/.claude/settings.json |
Native hook support. |
| Codex | ~/.codex/hooks.json |
Run /hooks after changing the file so Codex re-approves it. |
| Cursor | ~/.cursor/hooks.json |
User-global hooks only. Approve in Settings -> Hooks. |
| OpenCode | ~/.config/opencode/hook/hooks.yaml |
Uses the OpenCode-Hooks adapter. |
| Pi | ~/.pi/agent/hook/hooks.yaml |
Uses the Pi-YAML-Hooks adapter. |
| Shell | .envrc or shell rc |
Fallback when no native harness exists. |
Fresh Cursor install with no existing hooks:
mkdir -p ~/.cursor
acd setup cursor --raw > ~/.cursor/hooks.jsonIf ~/.codex/config.toml pins feature flags, keep hooks enabled:
[features]
hooks = trueAfter setup:
acd doctordoctor checks that the installed snippet still matches the current template.
| Strategy | What happens | Best for |
|---|---|---|
event |
One captured edit becomes one commit. This is the default. | Offline use, CI, shared branches, strict traceability. |
intent |
An AI planner groups related captures before replay writes a commit. | Local work where reviewable commits matter more than one-edit history. |
Offline default:
export ACD_AI_PROVIDER=deterministic
export ACD_COMMIT_STRATEGY=eventAI grouping:
export ACD_AI_PROVIDER=openai-compat
export ACD_AI_API_KEY=$YOUR_API_KEY
export ACD_AI_BASE_URL=https://your-endpoint/v1
export ACD_AI_MODEL=gpt-5.4-mini
export ACD_AI_DIFF_EGRESS=1
export ACD_COMMIT_STRATEGY=intent
export ACD_INTENT_WINDOW=10
export ACD_INTENT_MIN_PENDING=4
export ACD_INTENT_MAX_PENDING_AGE=5m
export ACD_INTENT_DEFER_LIMIT=1ACD_AI_DIFF_EGRESS=1 lets the planner see redacted captured diffs. Leave it
unset when the endpoint should receive metadata only.
| Need | Command |
|---|---|
| Start or refresh the current repo daemon | acd start |
| Watch all registered repos | acd list |
| Show this repo state | acd status |
| Follow capture, group, publish, and block decisions | acd events --watch |
| Ask why a path behaved a certain way | acd explain --path FILE |
| Ask what ACD did for a commit | acd explain --commit HEAD |
| Flush the current visible intent batch from an active harness session | acd flush --session-id "$ACD_SESSION_ID" --logical |
| Nudge capture and replay without bypassing intent batch gates | acd wake --session-id "$ACD_SESSION_ID" |
| Stop this repo daemon | acd stop |
| Stop every registered daemon | acd stop --all |
| Tail the daemon log | acd logs --follow |
| Create a support bundle | acd doctor --bundle |
acd start resolves your current directory to the canonical Git worktree root,
so calling it from a subdirectory refreshes the same daemon.
Use the same ladder every time:
acd status
acd events --watch
acd explain --path path/to/file
acd diagnose --json
acd fix --dry-run
acd fix --yes
acd statusOnly use the force path after the dry-run shows terminal barriers with pending
successors and you have checked that the blocked changes are already in HEAD
or should be discarded:
acd fix --force --dry-run
acd fix --force --yesacd fix backs up state.db before it mutates state and refuses to run while a
live daemon owns the database. If the problem is only a manual pause marker,
run:
acd resume --yesUse commit-all when files changed while no daemon was running:
acd commit-all --dry-run
acd commit-all --yes
acd commit-all --yes --jsonIt refuses on detached HEAD, in-progress Git operations, manual pause markers, or while the per-repo daemon is alive.
Most repos need no manual setup. Harness hooks call acd start, which creates
<gitDir>/acd/state.db and registers the repo.
Use explicit lifecycle commands when autodiscovery is disabled or when old rows need cleanup:
acd repo init
acd repo list
acd repo remove --dry-run
acd repo remove --yes
acd repo remove --yes --purge-stateDisable autodiscovery in ~/.config/acd/config.json:
{
"repo_lifecycle": {
"autodiscovery": false
}
}Override it for one process:
ACD_REPO_AUTODISCOVERY=disabled acd start
ACD_REPO_AUTODISCOVERY=enabled acd startThe daemon never rewrites history on its own. Use rewrite-commits only for an
explicit local cleanup before sharing a branch:
acd rewrite-commits --from 5 --plan-out rewrite.json --plan-only
acd rewrite-commits --show-plan rewrite.json
acd rewrite-commits --apply-plan rewrite.json --dry-run
acd rewrite-commits --apply-plan rewrite.json --yesIf apply prints a backup ref or SHA and review fails:
git reset --hard <backup-ref-or-sha>| Variable | Default | Use |
|---|---|---|
ACD_COMMIT_STRATEGY |
event |
event for one capture per commit, intent for AI grouping. |
ACD_AI_PROVIDER |
deterministic |
deterministic, openai-compat, or subprocess:<name>. |
ACD_AI_API_KEY |
unset | Required by openai-compat. |
ACD_AI_BASE_URL |
https://api.openai.com/v1 |
OpenAI-compatible endpoint. |
ACD_AI_MODEL |
gpt-5.4-mini |
Model passed to the provider. |
ACD_AI_DIFF_EGRESS |
off | Truthy sends redacted captured diffs to providers that ask for diffs. |
ACD_INTENT_WINDOW |
10 |
Max captures offered to one planner pass. |
ACD_INTENT_MIN_PENDING |
10 |
Preferred count before planning. Lower it for sparse repos. |
ACD_INTENT_MAX_PENDING_AGE |
5m |
Age escape hatch for sparse queues. |
ACD_INTENT_DEFER_LIMIT |
1 |
Deferrals before ACD forces a one-capture window. |
ACD_INTENT_RETRY_ON_INVALID |
2 |
Max correction retries after invalid planner output. |
ACD_SAFE_IGNORE |
enabled | Set false-like value to stop pruning generated trees. |
ACD_SAFE_IGNORE_EXTRA |
unset | Extra generated trees, such as dist/,build/. |
ACD_SENSITIVE_GLOBS |
built in | Extra sensitive path globs. Empty keeps defaults. |
ACD_TRACE |
off | Writes daemon decision summaries under <gitDir>/acd/trace/. |
ACD_AI_PROMPT_TRACE |
off | Writes local AI request diagnostics. Treat as sensitive. |
Restart a running daemon after changing daemon runtime environment.
| Doc | Use it for |
|---|---|
| docs/overview.md | A short system map. |
| docs/user-workflows.md | Daily status, recovery, support bundles, and commit-all. |
| docs/capture-replay.md | Storage, replay, branch safety, blockers, and trace classes. |
| docs/intent-commit-flow.md | Intent grouping behavior and planner observability. |
| docs/intent-commit-rewrite-flow.md | Safe history rewrite workflow. |
| docs/rewrite-commits.md | rewrite-commits command grammar. |
| docs/ai-providers.md | Provider setup, diff privacy, prompt tracing, and plugin protocol. |
| docs/multi-tool.md | Running ACD next to another auto-committer. |
MIT. See LICENSE.