Skip to content

How Do I Version Control My AI Coding Assistant Configuration and Skills?

I spent weeks perfecting my custom skills for Claude Code. I crafted elaborate prompts, built specialized workflows, and fine-tuned my opencode.jsonc configuration. Then my laptop died. All that work—gone.

After that disaster, I swore I’d never lose my AI assistant configuration again. The solution? Version control with chezmoi, a declarative dotfile manager that handles the complexity of syncing configs across machines.

The Problem: Your AI Assistant Config Is Valuable and Fragile

Modern AI coding assistants like Claude Code and OpenCode CLI store their configuration in multiple locations:

  • ~/.claude/settings.json — Global settings and preferences
  • ~/.config/opencode/opencode.jsonc — OpenCode CLI configuration
  • ~/.claude/skills/ — Custom skills you’ve developed
  • ~/.claude/commands/ — Custom slash commands
  • ~/.claude/CLAUDE.md — Project instructions

These files represent significant time investment. My custom skills directory alone contains 15 specialized tools I’ve built over months. Losing them means hours of reconstruction.

But version controlling these files isn’t straightforward:

  1. Multiple machines: I switch between my MacBook Pro (macOS) and my Linux workstation daily
  2. OS-specific differences: Some paths and settings differ between operating systems
  3. Sensitive data: API keys and tokens shouldn’t go into git
  4. Scattered locations: Config files live in different directories

Why Not Just Use Git Directly?

I tried a bare git repository approach first. It worked, but felt clunky:

bare-git-approach.sh
# Create a bare repository for dotfiles
git init --bare $HOME/.dotfiles
# Create an alias for convenience
alias config='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
# Add config files
config add ~/.claude/settings.json
config add ~/.config/opencode/opencode.jsonc
config commit -m "Add AI assistant configs"

This works for simple cases, but it has limitations:

  • No templating for OS-specific values
  • Manual encryption for secrets
  • Easy to accidentally commit sensitive data
  • No built-in conflict resolution for different machines

The Solution: chezmoi for Declarative Dotfile Management

chezmoi solves these problems with a declarative approach. You define what your config files should look like, and chezmoi handles the complexity.

Initialize chezmoi for AI Assistant Config

First, install chezmoi:

install-chezmoi.sh
# macOS
brew install chezmoi
# Linux
sudo pacman -S chezmoi # Arch
sudo apt install chezmoi # Debian/Ubuntu

Initialize it for your AI assistant configs:

init-chezmoi.sh
# Initialize chezmoi
chezmoi init
# Add your AI assistant configuration files
chezmoi add ~/.claude/settings.json
chezmoi add ~/.config/opencode/opencode.jsonc
chezmoi add ~/.claude/CLAUDE.md
# Add your skills directory (entire directory)
chezmoi add ~/.claude/skills
# Add commands directory
chezmoi add ~/.claude/commands

Track Changes and Sync

Now when you modify your AI assistant configuration, use chezmoi’s workflow:

chezmoi-workflow.sh
# Edit a file with chezmoi (edits the source, not the target)
chezmoi edit ~/.claude/settings.json
# After editing, apply changes
chezmoi apply
# View what changed
chezmoi diff
# Commit to git (chezmoi uses a git repo under the hood)
chezmoi cd
git add .
git commit -m "Update Claude Code skills for better code review"
git push
chezmoi cd

Handle Sensitive Data with Encryption

The real power of chezmoi is handling secrets. I store API keys and tokens in encrypted files:

encrypt-secrets.sh
# Add a file with encryption
chezmoi add --encrypt ~/.claude/api-keys.json
# chezmoi uses your default encryption tool (age or GPG)
# The encrypted version goes into your chezmoi source directory

When you sync to a new machine, chezmoi decrypts the file automatically (after you provide your encryption key).

I also use environment variables in templates:

settings.json.tmpl
{
"apiEndpoint": "{{ .Env.AI_API_ENDPOINT }}",
"modelPreferences": {
"defaultModel": "claude-3-5-sonnet-20241022"
}
}

This way, sensitive values never touch the repository.

Cross-Machine Setup

When setting up a new machine, the entire process takes seconds:

new-machine-setup.sh
# Install chezmoi
brew install chezmoi
# Initialize from your git repository
chezmoi init https://github.com/yourusername/dotfiles.git
# Apply all your AI assistant configs
chezmoi apply
# Your Claude Code, OpenCode CLI, and skills are ready

Handle OS Differences with Templates

My opencode.jsonc needs different settings on macOS vs Linux. chezmoi templates handle this:

opencode.jsonc.tmpl
{
"model": "claude-3-5-sonnet-20241022",
"contextPaths": [
{{ if eq .chezmoi.os "darwin" }}
"/Users/Shared/ai-context"
{{ else }}
"/opt/ai-context"
{{ end }}
],
"skillsDir": "{{ .chezmoi.homeDir }}/.claude/skills"
}

chezmoi automatically selects the right path based on the current OS.

Key Directories to Version Control

Based on my experience, these are the essential files and directories to track:

essential-config-paths.txt
~/.claude/
├── CLAUDE.md # Project instructions (critical!)
├── settings.json # Global settings
├── skills/ # Custom skills (months of work)
│ ├── code-reviewer/
│ ├── tdd-guide/
│ ├── security-reviewer/
│ └── ...
├── commands/ # Custom slash commands
│ ├── review-pr.md
│ └── commit.md
└── agents/ # Custom agent configurations
└── ...
~/.config/opencode/
└── opencode.jsonc # OpenCode CLI configuration

I also track learned patterns. After each productive session, I save insights to markdown files in my skills directory:

save-learned-patterns.sh
# After a session, save what I learned
echo "## Effective Patterns for React Testing
- Use data-testid attributes for stable selectors
- Mock fetch calls at the module level
- ..." > ~/.claude/skills/learned/react-testing-patterns.md
chezmoi add ~/.claude/skills/learned/react-testing-patterns.md
chezmoi cd && git commit -am "Add React testing patterns"

This builds a knowledge base that grows over time and benefits from version control.

Why This Matters for AI-Assisted Development

Version controlling your AI assistant config isn’t just about backup—it’s about treating your AI tools as a first-class part of your development environment.

Disaster Recovery

When my laptop died, I lost everything. Now I can recreate my entire AI coding environment on a new machine in under 5 minutes.

Machine Parity

My MacBook Pro and Linux workstation have identical AI assistant configurations. No more “wait, why is this skill missing?” moments when I switch machines.

Team Sharing

I’ve started sharing my skills directory with my team. We have a shared repository of specialized prompts and workflows that everyone can use:

team-sharing.sh
# Clone team's shared skills
git clone https://github.com/myteam/ai-skills.git ~/.claude/skills-team
# Reference in CLAUDE.md
echo "See ~/.claude/skills-team/ for team-specific skills" >> ~/.claude/CLAUDE.md

Iteration Tracking

I can see how my skills have evolved. Looking at the git history, I can track which prompts work and which don’t:

view-skill-history.sh
cd ~/.local/share/chezmoi
git log --oneline --follow .claude/skills/code-reviewer/skill.md

Experimentation

Want to try a new skill configuration? Create a branch:

experiment-branch.sh
chezmoi cd
git checkout -b experiment/new-skill-approach
# ... modify skills ...
chezmoi apply
# Test it out
# If it works, merge. If not, git checkout main && chezmoi apply

Common Mistakes to Avoid

I’ve made these mistakes so you don’t have to:

1. Forgetting Sensitive Data

Always encrypt or template out API keys:

check-for-secrets.sh
# Before committing, check for potential secrets
grep -r "api_key\|token\|secret" ~/.local/share/chezmoi/

2. Over-Syncing

Not every machine needs every skill. Use templates to conditionally include machine-specific configs:

machine-specific.tmpl
{{ if eq .chezmoi.hostname "work-machine" }}
# Work-specific skills
{{ end }}

3. Ignoring Templates

Templates are chezmoi’s superpower. Use them. Rename files to .tmpl to enable templating:

enable-templates.sh
# Convert a file to a template
chezmoi add --template ~/.claude/settings.json

4. Skipping .gitignore

Create a .chezmoiignore file to exclude files you don’t want to track:

.chezmoiignore
# Don't track these
README.md
LICENSE

5. No README

Document what each skill does. Future you will thank present you:

skill-README.md
# code-reviewer
Reviews code for quality, security, and performance issues.
## Usage
Run after writing any new code to get immediate feedback.
## Dependencies
None

6. Monolithic Commits

Don’t commit 15 skill changes at once. Each skill change is a separate commit:

atomic-commits.sh
# Good: One skill per commit
chezmoi cd
git add .claude/skills/security-reviewer/skill.md
git commit -m "Improve security-reviewer to detect OWASP Top 10"

7. Missing Hooks

Set up git hooks to validate configs before committing:

pre-commit-hook.sh
# .chezmoi/source/.git/hooks/pre-commit
#!/bin/bash
# Validate JSON configs before committing
find . -name "*.json" -o -name "*.jsonc" | xargs -I {} sh -c 'jq . {} > /dev/null || exit 1'

Alternative Approaches

chezmoi isn’t the only option. Here are alternatives:

Bare Git Repository

The simplest approach, mentioned earlier. Works well if you don’t need templating or encryption.

GNU Stow

A symlink farm manager. Good for organizing dotfiles into packages, but lacks templating.

yadm

Yet Another Dotfiles Manager. Git-based with some templating support. Lighter weight than chezmoi.

I chose chezmoi because it offers the best balance of features for AI assistant configs: templating for OS differences, encryption for secrets, and a clear mental model.

The Bottom Line

Your AI coding assistant configuration is an investment. Treat it like production code: version control it, test it, iterate on it, and back it up.

With chezmoi, I’ve achieved:

  • Zero data loss: My configs survive hardware failures
  • Cross-machine sync: Identical setup everywhere I work
  • Team collaboration: Shared skills across my team
  • Iteration tracking: I can see what works and what doesn’t
  • Safe experimentation: Try new approaches in branches

The setup took me about 30 minutes. The peace of mind is priceless.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments