Imported from arbourd/dotfiles (
AGENTS.md). Install upstream withnpx skills add arbourd/dotfiles. Copyright stays with the author.
AGENTS.md
Automated macOS environment as code. Dotfiles are symlinked into place; nothing is copied.
Entry point
dot (zsh) is the single entry point for all setup tasks:
| Command | What it does |
|---|---|
help |
Prints the usage dialog |
init |
Clones this repo to ~/src/github.com/arbourd/dotfiles and symlinks dot to ~/.local/bin/dot |
link |
Symlinks all dotfiles into ~ and removes stale symlinks |
install |
Runs brew + defaults + fisher + vim in order |
install-brew |
Installs/updates Homebrew packages from Brewfile |
install-defaults |
Applies macOS defaults write settings |
install-fisher |
Installs/updates Fisher and fish plugins |
install-vim |
Installs/updates vim-plug and Vim plugins |
update |
Pulls latest changes and reports the version and whether it was updated |
version |
Prints the current commit SHA of the dotfiles repository |
On a new machine, run commands in this order: init → link → install. link must run before install because the install steps (fisher, vim) depend on config files already being in place at their expected locations.
Repository layout
dot # entry point — init/update/link/install subcommands
.macOS # zsh script that applies macOS defaults write settings
Brewfile # Homebrew formulae, casks, and Mac App Store apps
agents # global AI agent instructions, persona, and skill definitions
ghostty # Ghostty terminal emulator config
git # global git config, attributes, and gitignore
gpg # GPG agent and key config
iterm # iTerm 2 config (archived — do not modify or delete)
sh # shell config: fish (primary), bash, and zsh fallback
ssh # SSH client config
vim # vimrc and vim-plug plugin list
zed # Zed editor settings and keybindings
tests # bats test suite for dotfiles
AI Agents & Skills
AI configuration is managed via agents/ and symlinked to tool-specific global paths.
agents/AGENTS.md: Shared global instructions, loaded by every tool on every project (e.g. "don't push without being asked"). Project-specific instructions still belong in that project's ownAGENTS.md, not here.agents/personas: Persona or subagent definitions.agents/skills: Tool definitions and scripts.agents/claude: Claude Code-only files, symlinked as-is into~/.claude/.
Individual symlinks are used to allow personal, non-repo agents and skills to coexist in the target directories.
| Tool | Skills | Personas / agents | Global instructions |
|---|---|---|---|
| Claude Code | ~/.claude/skills/<name>/SKILL.md |
~/.claude/agents/*.md |
~/.claude/AGENTS.md, manually imported by CLAUDE.md |
| Antigravity | ~/.agents/skills/<name>/SKILL.md |
~/.gemini/agents/*.md |
~/.gemini/GEMINI.md |
| OpenCode | ~/.agents/skills/<name>/SKILL.md |
~/.config/opencode/agents/*.md |
— |
| Pi | ~/.agents/skills/<name>/SKILL.md |
~/.pi/agent/prompts/*.md |
~/.pi/agent/AGENTS.md |
| Codex | — | — | ~/.codex/AGENTS.md |
Antigravity replaced Gemini CLI (retired 2026-06-18) but still reads ~/.gemini/. Its skills/persona paths above are carried over from the old CLI, unverified — treat as best-effort.
~/.claude/CLAUDE.md and ~/.claude/RTK.md are not symlinked — they're owned and regenerated by the rtk CLI's own installer. CLAUDE.md manually imports both @AGENTS.md (dotfiles-managed) and @RTK.md (rtk-managed); if rtk ever overwrites CLAUDE.md, re-add the @AGENTS.md line by hand.
agents/claude/settings.json is not symlinked directly — it's merged into ~/.claude/settings.json via jq (permissions.allow is unioned, not overwritten), so a live machine's local settings additions survive dot link.
Shell
Primary shell is fish (/opt/homebrew/bin/fish). sh/.shrc is a POSIX-compatible fallback used for bash and zsh. dot is zsh to maintain compatibility with macOS.
Private/sensitive env vars go in ~/.config/fish/private.fish (not tracked; created empty by _ensure). Git private config goes in ~/.config/git/private (not tracked; included via git/config).
Homebrew
Packages are in Brewfile. Run with HOMEBREW_BUNDLE_NO_LOCK=1 — no Brewfile.lock.json is generated or committed.
Testing
Run the bats suite locally after any dot script change:
bats tests/dot.bats
Adding or removing a command
When a dot command is added, renamed, or removed, update all five of these in the same change:
dot—_usage()and thecasestatementREADME.md— usage block in InstallationAGENTS.md— command table and repo layout comment.github/workflows/ci.yml—matrix.commandlisttests/dot.bats— add or remove the corresponding test(s)
CI
GitHub Actions (.github/workflows/ci.yml) runs each dot command as a matrix job on macos-latest, plus a separate job that runs the bats test suite on ubuntu-latest. MAS installs are skipped in CI via HOMEBREW_BUNDLE_MAS_SKIP. Dependabot keeps Actions up to date daily.
Adding a new dotfile
- Add the config file under an appropriately named directory.
- Add an
_ensurecall for its target directory in_linkif needed. - Add an
ln -vsfline in_linkpointing it to its target path. - If it requires a new package, add it to
Brewfile.
What not to change
- Do not add a
Brewfile.lock.json; the bundle runs lock-free intentionally. - Do not add a
hookskey toagents/claude/settings.json; the merge in_merge_claude_settingsreplaces arrays wholesale (onlypermissions.allowis unioned), which would silently delete thePreToolUsehook thatrtkitself installs into~/.claude/settings.json. - Do not symlink
~/.claude/CLAUDE.mdor~/.claude/RTK.mdfrom the repo; both are owned and regenerated by thertkCLI's installer. - Do not commit
~/.config/fish/private.fishor~/.config/git/private; these are machine-local secrets. - Do not skip GPG signing on commits (
--no-gpg-sign).