Skip to content

Instantly share code, notes, and snippets.

@jaredmdobson
Created May 20, 2026 16:09
Show Gist options
  • Select an option

  • Save jaredmdobson/7e599ec20b80beb2f4d95208ab773cc2 to your computer and use it in GitHub Desktop.

Select an option

Save jaredmdobson/7e599ec20b80beb2f4d95208ab773cc2 to your computer and use it in GitHub Desktop.
Tracking AI tool config (~/.claude, ~/.codex, ~/.aider, ...) with chezmoi

Tracking AI tool config (~/.claude, ~/.codex, ~/.aider, …) with chezmoi

A practical recipe for keeping the authored parts of your AI tools (instructions, skills, agents, commands, prompts, settings) in git while leaving the runtime junk (chat history, project caches, transcripts, telemetry, plugins) out of it.

This guide is written for both humans and agents handed the job "set up dotfile management for my AI tools." Follow it top-to-bottom on a fresh machine, or jump to Adding a new AI tool if chezmoi is already initialized.


Why chezmoi (and not git directly)

Every AI tool colonizes ~/.<tool>/ and writes a mix of:

Category Examples Action
Authored CLAUDE.md, settings.json, skills, agents, commands, MCP configs track
Runtime state chat history, project transcripts, session logs, telemetry, statsig caches ignore
Reinstallable plugins, downloaded skills from registries, vendored binaries ignore
Machine-specific API keys, absolute paths, hostnames template or encrypt

A bare git repo in $HOME works but forces you to maintain .gitignore carefully and shares the same secrets across every machine. chezmoi gives you (a) a dedicated source dir so $HOME stays clean, (b) .chezmoiignore evaluated against target paths, (c) Go templates for per-machine values, and (d) age/gpg encryption for secrets — all without leaving git.


One-time bootstrap

# 1. Create an empty private repo somewhere (GitHub, GitLab, self-hosted)
gh repo create <you>/dotfiles --private

# 2. Install chezmoi and clone the repo into the chezmoi source dir
brew install chezmoi                                              # macOS
# sh -c "$(curl -fsLS get.chezmoi.io)"                            # Linux
chezmoi init https://github.com/<you>/dotfiles.git                # clones into ~/.local/share/chezmoi

# 3. Verify
chezmoi cd                # drops you into the source dir
chezmoi managed           # lists target paths chezmoi will manage (empty on first run)

chezmoi init clones the repo and does nothing else. Use chezmoi init --apply <url> only when you trust the repo's contents not to clobber $HOME — on a fresh repo this is fine, on a populated one it's not.


Adding a new AI tool

Workflow is the same for every tool:

# 1. Add the authored paths (chezmoi copies them into the source dir with `dot_` prefix)
chezmoi add ~/.<tool>/<file-or-dir> [~/.<tool>/<more>...]

# 2. Add ignore patterns BEFORE re-running `chezmoi add` on a parent dir
$EDITOR ~/.local/share/chezmoi/.chezmoiignore

# 3. Verify
chezmoi managed | grep .<tool>     # should list only what you want tracked
chezmoi diff                       # empty = source matches $HOME

# 4. Commit + push
chezmoi cd
git add . && git commit -m "Track ~/.<tool>" && git push

Order matters: add ignore patterns before doing chezmoi add ~/.<tool> on a parent directory — chezmoi evaluates .chezmoiignore against target paths at add time. If you accidentally added runtime junk, remove it from the source dir with rm (not chezmoi forget, which only works on currently-managed paths).


Per-tool cheat sheet

What to track vs ignore for the common AI tools as of 2026. Paths assumed under ~/; adjust if a tool is XDG-relocated.

Claude Code (~/.claude/)

Track Ignore
CLAUDE.md projects/, jobs/, todos/, statsig/
settings.json shell-snapshots/, transcripts/, ide/
agents/, hooks/, commands/ plugins/ (reinstall via plugin marketplace)
skills/<authored>/ skills/<symlinked-from-outside>
keybindings.json mcp_logs/, run_history, scheduled_tasks.json

Codex (~/.codex/)

Track Ignore
config.toml, AGENTS.md history/, sessions/, cache/
skills/, prompts/ logs/
mcp_servers.json *.log, telemetry

Aider (~/ and ~/.aider.d/)

Track Ignore
.aider.conf.yml .aider.chat.history.md
.aider.model.metadata.json (if customized) .aider.input.history
.aider.d/<prompts>/ .aider.tags.cache.v3/

Cursor / Continue / Gemini CLI / Zed AI

Same pattern. Look under ~/.<tool>/ for:

  • config.{json,yaml,toml} → track
  • prompts/, rules/, agents/, commands/ → track
  • history/, sessions/, cache/, logs/, telemetry/, index* → ignore

If in doubt: read once, edit once, then re-check ls -la ~/.<tool>/ — anything that grew without you touching it is runtime state.


A solid starting .chezmoiignore

# repo meta (lives in the source dir but doesn't belong in $HOME)
README.md
LICENSE

# ----- Claude Code runtime -----
.claude/projects
.claude/jobs
.claude/todos
.claude/statsig
.claude/shell-snapshots
.claude/transcripts
.claude/plugins
.claude/ide
.claude/mcp_logs
.claude/run_history
.claude/scheduled_tasks.json
.claude/skills/*/.aider*
# symlinks pointing outside ~/.claude (target won't exist elsewhere)
.claude/skills/find-skills

# ----- Codex runtime -----
.codex/history
.codex/sessions
.codex/cache
.codex/logs
.codex/*.log

# ----- Aider runtime -----
.aider.chat.history.md
.aider.input.history
.aider.tags.cache.v3
.aider.llm.history

# ----- Generic AI runtime patterns -----
**/cache
**/sessions
**/transcripts
**/telemetry
**/*.log

Multi-machine sync

On every machine after the first:

brew install chezmoi
chezmoi init --apply https://github.com/<you>/dotfiles.git    # one command, restores all tracked AI config

After making edits on machine A:

chezmoi cd && git add . && git commit -m "<change>" && git push

On machine B:

chezmoi update    # pulls the repo and applies the diff to $HOME

chezmoi update = git pull + chezmoi apply. Run it after each remote change. If you've edited a managed file directly in $HOME without going through chezmoi, chezmoi diff will show the drift — re-sync with chezmoi re-add (source ← home) or chezmoi apply (source → home).


Templating (when you need it)

Use templates for values that differ per machine (e.g. an API endpoint, a path to a personal vault):

chezmoi add --template ~/.codex/config.toml
$EDITOR $(chezmoi source-path ~/.codex/config.toml)

Inside the template, reference {{ .chezmoi.hostname }}, {{ .chezmoi.os }}, {{ .email }}, or custom data from chezmoi edit-config.

For secrets (API keys), use chezmoi encrypt (age-backed by default) and reference the encrypted file from a template — never commit a plaintext key.


Common gotchas

  • Symlinks pointing outside ~/.<tool>/ — chezmoi by default tracks the symlink target. If the target lives in some other dir that isn't on the target machine, the symlink will dangle. Add it to .chezmoiignore or chezmoi add --follow to copy the target content instead.
  • Plugin / extension directories — these are usually reinstallable from a manifest. Track the manifest (plugins.json, extensions.json), ignore the unpacked dir.
  • Top-level files in the source dir become ~/<name> filesREADME.md in the source dir would land at ~/README.md on apply unless added to .chezmoiignore.
  • chezmoi add re-runs are not idempotent for changed files — if you edit ~/.claude/CLAUDE.md, re-run chezmoi add (or chezmoi re-add) to pull the change into the source dir. chezmoi diff tells you when they've drifted.

TL;DR for an agent picking this up

brew install chezmoi
chezmoi init https://github.com/<you>/dotfiles.git
# Edit ~/.local/share/chezmoi/.chezmoiignore with the patterns above
chezmoi add ~/.claude/CLAUDE.md ~/.claude/skills/<authored-dirs>
chezmoi add ~/.codex/config.toml ~/.codex/skills
# ...repeat per tool
chezmoi managed             # sanity check: only authored paths
chezmoi diff                # sanity check: empty
chezmoi cd && git add . && git commit -m "Initial AI dotfiles" && git push

That's the whole loop. Adding the next AI tool is chezmoi add + update .chezmoiignore + commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment