Guide6 min read

Dotfiles for AI coding assistants: what to commit

Which files in ~/.claude, ~/.codex and ~/.cursor are safe to commit, which hold secrets or session state, and how Stow and chezmoi handle them.

Dotfiles#claudecode#codex#cursor GUIDE Dotfiles for AIcoding assistants what to commit skillpouch.net/blog Guide: Dotfiles for AI coding assistants: what to commit

Your dotfiles repo already carries .zshrc and .gitconfig, so adding ~/.claude, ~/.codex and ~/.cursor looks like a five-minute job. It isn’t, because those folders mix the config you wrote with login tokens, transcripts and files the assistant rewrites on its own. This guide to dotfiles for AI coding assistants maps which files are safe to put in git and which aren’t, then shows where Stow, chezmoi and cloud folders hold up and where they break.

Why AI assistant config isn’t like .zshrc

A shell config is a file you write and nothing else touches. An assistant’s home folder is shared between you and the program, and three problems follow from that:

  • Secrets sit inside config files. An MCP server that needs a token usually gets it from an env block, in the same file as the rest of your setup: ~/.cursor/mcp.json for Cursor, ~/.codex/config.toml for Codex, ~/.claude.json for Claude Code.
  • State files never stop changing. Claude Code writes every prompt to history.jsonl and every session to a transcript under projects/. The Claude Code docs say these aren’t encrypted at rest, and that anything passing through a tool lands in a transcript, including a credential a command printed. Codex saves session transcripts to history.jsonl by default as well, per its history persistence docs.
  • Some files hold per-machine paths. Codex’s config reference has projects.<path>.trust_level entries keyed by a project’s absolute path, and a Mac and a Linux box disagree about where home is.

Codex’s own docs say it keeps its local state under CODEX_HOME, which defaults to ~/.codex, and list what lives there. Only the first line is config you’d want on another computer:

learn.chatgpt.com/docs/config-file/config-advanced
Codex documentation listing files Codex stores: config.toml (your local configuration), auth.json (if you use file-based credential storage) or your OS keychain/keyring, history.jsonl (if history persistence is enabled), other per-user state such as logs and caches
The Codex docs: one config file, then credentials, transcripts, logs and caches.

Dotfiles for AI coding assistants: the file map

Here is the split for the three folders most people start with. The left column is what you wrote; the right column stays on the computer that made it.

Assistant Commit it Keep it out of git
Claude Code (~/.claude) CLAUDE.md, skills/, agents/, commands/, settings.json (check its env block) .credentials.json, history.jsonl, projects/, caches, and ~/.claude.json as a whole
Codex (~/.codex) AGENTS.md, prompts/, config.toml (check MCP env values and projects entries) auth.json, history.jsonl, logs and caches
Cursor (~/.cursor) mcp.json with ${env:NAME} instead of keys, skills/, commands/, hooks.json, cli-config.json Keys typed straight into mcp.json; your User Rules aren’t a file here at all

A few details the table can’t hold:

  • ~/.claude.json sits next to ~/.claude, not inside it, and holds your OAuth session, per-project trust decisions, your personal MCP servers and UI toggles, per the Claude Code docs. Only the MCP servers are worth carrying.
  • Cursor resolves ${env:NAME} and ${userHome} inside mcp.json, and its MCP docs say to use environment variables for secrets and never hardcode them. Codex has the same idea in env_vars and bearer_token_env_var, so the file holds variable names, not values.
  • Cursor’s CLI configuration docs say some fields in cli-config.json are CLI-managed and may be overwritten, so expect diffs you didn’t make.
  • Gemini CLI’s oauth_creds.json belongs in the right column too.

Git and Stow: the simplest setup

GNU Stow is a symlink farm manager: each folder in your repo is a package, and Stow links its contents into the parent of the repo, which is your home folder if the repo is ~/dotfiles. Give each assistant a package that holds only the left column of the table, for example ~/dotfiles/claude/.claude/CLAUDE.md, and stow them:

~/dotfiles
❯ mkdir -p ~/.claude ~/.codex ~/.cursor# the real folders must exist before you stow (see the warning below)❯ stow claude codex cursor# links each file from claude/.claude/, codex/.codex/ and cursor/.cursor/ into your home folder

This works well for one assistant on two machines. It breaks in three places:

  • Secrets. Stow has no encryption. A key in an env block is plain text in every clone of the repo, private or not.
  • Per-machine values. A symlink points every computer at the same bytes, so an absolute path or a work-only MCP server can’t differ between machines.
  • Files the assistant rewrites. A program that saves by writing a new file and renaming it over the old one replaces your symlink with a plain file, and your repo stops seeing changes. After the assistant changes a setting, check with ls -l that the link is still a link.

Encrypted dotfiles sync with chezmoi and age

chezmoi adds the two things Stow lacks: templates and encryption. With age, a file you add with --encrypt sits encrypted in the repo and is decrypted when you apply it. With templates, one source file renders differently per machine:

~
❯ chezmoi age-keygen --output=$HOME/key.txt# prints your public key; set encryption = "age" and [age] identity + recipient in ~/.config/chezmoi/chezmoi.toml❯ chezmoi add --encrypt ~/.gemini/.env# stored encrypted in the source repo, decrypted by chezmoi apply❯ chezmoi add --template ~/.codex/config.toml# then replace your home path in the template with {{ .chezmoi.homeDir }}

The key file never goes in the repo. Copy it to each computer yourself and back it up somewhere other than the repo: without it, the encrypted files can’t be decrypted on a new machine.

chezmoi can also handle ~/.claude.json, the file you can’t commit whole. A modify_ script receives the file’s current contents and writes the new ones, and the setValueAtPath function changes one key in a JSON or TOML file, so you can manage the MCP servers and leave the session alone:

chezmoi.io/user-guide/manage-different-types-of-file/
chezmoi documentation example: a modify script marked chezmoi:modify-template that replaces old with new, and a second one using fromJson, setValueAtPath key.nestedKey value and toPrettyJson to set one value in a JSON file
chezmoi's modify templates change one key in a file the program also writes, such as the MCP servers in ~/.claude.json.

The docs note that on a new machine the file doesn’t exist yet, so the script must write a complete file. And the cost grows with every assistant: the same MCP server is JSON for Claude Code and Cursor and TOML for Codex. One MCP configuration with chezmoi solves that with one manifest and a template per format, which works and is yours to maintain.

Cloud folders: why live config files conflict

Moving ~/.claude into Dropbox, iCloud or a Syncthing folder skips all the setup above, and that’s the trap. A cloud folder syncs whole files whenever they change, and the folder holds files the assistant writes during every session. Two computers with the assistant open write the same history.jsonl, and you can end up with a conflicted copy next to it that nobody tells you about. The whole folder also travels, credentials and transcripts included. Our comparison of git, Syncthing, Dropbox and iCloud for Claude Code shows what each does with a clash.

✕The usual way

Symlink ~/.claude into a cloud folder: transcripts and .credentials.json upload with it, and history.jsonl can split into conflicted copies.

✓With SkillPouch

Sync only the left column of the file map, keep keys out of plain text, and decide what happens when two machines change the same file.

A purpose-built option: SkillPouch

SkillPouch is ours, so weigh this section with that in mind. It syncs items instead of folders: instructions, skills, agents, commands, MCP servers, hooks, plugins and settings. It never touches the right column of the file map:

docs.skillpouch.net/assistants/#settings-sync
SkillPouch docs: Windsurf settings are not supported; MCP servers, hooks and plugins are synced as their own item kinds; credential files such as auth.json, .credentials.json and oauth_creds.json are never synced
From the SkillPouch assistants page: credential files such as auth.json and .credentials.json are never synced.

How it answers the problems above:

  • Secrets are encrypted before upload. The CLI and the web app encrypt pouch content, file names and pouch names on your device, per the security page, and the server never sees your master password or Recovery Key. If you lose your master password, your Recovery Key and every computer or browser you already trust, nobody can recover your data, as the background sync docs state.
  • Each assistant gets its own format. An MCP server is stored once and written into ~/.claude.json, Cursor’s mcp.json or Codex’s config.toml, changing only the entries SkillPouch added (assistant file map).
  • Conflicts are marked, not guessed. When the same item changes on two computers, both versions are kept and you pick one in the web app (conflicts).
  • No habit to keep. The background sync starts again when you log in.
  • Self-hostable. It’s open source under AGPL-3.0, with self-hosting docs.

What it isn’t: a backup. A deleted skill is deleted everywhere, and there’s no version history. So keep the git repo if you want one; SkillPouch leaves it alone:

docs.skillpouch.net/assistants/#folders-in-a-git-checkout
SkillPouch docs, Folders in a git checkout: if an assistant's folder is part of a git checkout, such as a dotfiles repository, SkillPouch only reads it and never writes there, so the checkout stays clean.
An assistant folder inside a dotfiles checkout is read-only to SkillPouch, so git and SkillPouch can run side by side.

Which approach for which setup

Your setup Good fit
One assistant, two machines, no keys in config git and Stow, with the folders created before you stow
Keys in MCP env blocks, or paths that differ per machine chezmoi with age and templates
Several assistants sharing instructions and MCP servers SkillPouch, or chezmoi with a template per format
A team Project files in the project repo; personal setup stays personal
Everything on your own hardware Stow or chezmoi with a private remote, or self-hosted SkillPouch

For the team row, the Claude Code docs draw the same line: commit project files to share them, while ~/.claude is personal configuration for all your projects. If Claude Code is the only assistant you care about, the step-by-step guide to syncing Claude Code settings walks through the git and SkillPouch setups in full.

Whichever you pick, run git status before your first push and read every file name. If you see history.jsonl, projects/ or anything with auth or credentials in the name, stop there.

Try it on your own setup

Free to start, end-to-end encrypted, open source. Two commands and your setup follows you.

or sign in on the web

Read next