My dotfiles. They've gone through many ups and downs over the years, but at the moment they're:
- text and terminal centric (hx, Rex, yazi)
- cross-platform (macOS and linux)
- designed to work just as well over ssh as run locally
Where I've taken anything from the web I've tried to give credit appropriate to the licence. If I've missed giving you a shout out, then let me know and I'll gladly add one in.
Bootstrap a new machine with:
curl -fsSL https://raw.githubusercontent.com/benswift/.dotfiles/main/install.sh | bashThis installs Homebrew and mise, clones the repo, creates symlinks, and installs mise-managed tools.
If you prefer to set things up manually:
git clone https://github.com/benswift/.dotfiles.git ~/.dotfiles
~/.dotfiles/create_symlinks.shCheck that everything is set up correctly:
dotfiles doctorWorks on macOS (Apple Silicon) and Linux. The setup is zsh-only and mise-first for tool management, using Homebrew on macOS and native package managers on Linux.
This repo provides shared configuration for multiple AI coding agents, with
AGENTS.md as the common project-level instructions file.
- Claude Code:
claude/CLAUDE.mdis symlinked to~/.claude/CLAUDE.md.claude/settings.json(keys the repo owns) andclaude/settings.seed.json(defaults a machine may change) are merged into~/.claude/settings.json, not linked, so/modeland plugin installs never touch the repo. - Codex CLI: the same global instructions are symlinked to
~/.codex/AGENTS.md, and portable notification hooks are symlinked to~/.codex/hooks.json. Model selection, project-instruction fallbacks, trusted-project paths and UI state remain machine-local in~/.codex/config.toml; theoyalias only selects full-access mode. - Antigravity CLI: the global instructions are also symlinked to
~/.gemini/AGENTS.md.antigravity/settings.jsonand its seed are merged into~/.gemini/antigravity-cli/settings.jsonthe same way, and aSessionStarthook (antigravity/hooks.json) injects theCLAUDE.mdof a repo that has noAGENTS.md, whichagydoesn't read on its own.
The create_symlinks.sh script sets up all necessary symlinks and directories.
My personal Claude Code skills library (mail, vault, benswift-writer,
phdconvenor, etc.) lives in a separate private repo,
benswift/claude-plugin-personal,
loaded as a Claude Code plugin. The setup:
- Registered via
install.sh/dotfiles updateusingclaude plugin marketplace add benswift/claude-plugin-personalandclaude plugin install --scope user ben@ben, then enabled inclaude/settings.jsonviaenabledPlugins: {"ben@ben": true}--- portable across machines, no hardcoded paths. - Claude Code clones it to
~/.claude/plugins/marketplaces/ben/on first use. That clone is read-only: Claude Code re-clones it on every update. Edit, commit and push in the working checkout at~/projects/claude-plugin-personalinstead. - Codex reads the same personal skills via per-skill symlinks inside
~/.agents/skills, Codex's supported user-level skill directory. Existing independently installed skills in that directory are left alone. - Skills appear to Claude as
ben:<skill-name>(e.g.ben:vault) and to Codex by their unnamespaced skill name.
To propagate changes across machines: push from the working checkout, then run
dotfiles update on each machine (this one included). That refreshes Claude
plugins and re-syncs Codex skill links. Requires SSH auth to GitHub (the repo is
private). The sync skips plugins entirely if claude isn't installed yet, so on
a fresh host install Claude Code before running dotfiles update.
The Usage Rules package is excellent for
injecting project-specific rules into your AGENTS.md file:
mix usage_rules.sync AGENTS.md --all --inline usage_rules:all --link-to-folder deps --link-style at --remove-missingConfig that names my accounts and machines (mail, backups, some ssh hosts) lives
in a separate private repo, cloned into private/ when the machine can read it.
Everything here works without it; lib/private.sh lists the hooks.
(c) 2012-2025 Ben Swift
MIT License