Note
Developer bliss: dotfiles, configs, keys, fonts, themes, and plugins π
This repository contains dotfiles1 for azigler. By managing dotfiles in a centralized repository, it becomes easier to synchronize and share these configurations across different machines. This repository serves as a reference for azigler's preferred settings and can be used as a starting point for others to customize their own dotfiles.
These dotfiles are the public tier: program configuration only β shell, tmux, editors, language toolchains, and the scripts that install them. Nothing here needs an agent, and a machine that clones only this repository gets a complete, working environment.
The agent tier β the always-loaded instruction file, the skills, the hooks,
the schedulers, and the machine-specific reference material they read β lives in
a separate repository, because it describes real hosts and real services. It
is resolved at runtime through exactly one indirection, the ~/.agents symlink,
and every line in sync.sh that touches it goes through that symlink.
The split is what makes the absence harmless:
| with an agent tier installed | without one | |
|---|---|---|
./sync.sh |
links configs and wires ~/.claude, ~/.codex, ~/.cursor, ~/.gemini |
links configs; agent-tier lines are silent no-ops |
| shell startup | AGENTS_ROOT is exported; claude gets the session-identity wrapper |
AGENTS_ROOT unset; plain claude, with one warning line |
prefix W in tmux |
opens the agent roster | the binding is there, the target is not |
To install an agent tier, point bootstrap-agents.sh at its repository β it is
required input, never hardcoded here:
AGENTS_REPO=owner/repo ./bootstrap-agents.sh # short form: cloned with `gh`, so a private repo works
AGENTS_REPO=git@host:owner/repo ./bootstrap-agents.sh # any git URL: cloned with `git`
AGENTS_REPO=/path/to/local/clone ./bootstrap-agents.sh # a local checkout works tooIt clones the repository (default ~/<repo>, override with AGENTS_DIR),
refuses anything that does not actually contain a tier, creates ~/.agents, and
re-runs ./sync.sh claude. It is idempotent, and it never pulls a clone you
already have.
Warning
- The
sync.shscript will create backups in the$SCRIPT_DIR/.backupfolder before attempting to create a symlink, but it is recommended to create your own backups before executingsync.sh. - The
sync.shscript will move your$HOME/.ssh/configfile to$HOME/.ssh/local, which is included in the$SCRIPT_DIR/ssh/configfile synchronized from this repository. - The
download.shscript will create a copy of your public SSH key at$SCRIPT_DIR/ssh/$(hostname -s).puband your default public GPG key at$SCRIPT_DIR/gnupg/$(hostname -s).asc, where$(hostname -s)resolves to your machine's hostname without domain information. Remove those lines from the script to disable this behavior. - Be careful not to expose sensitive information or credentials if publishing your copy of this repository.
sync.sh and download.sh are two bash scripts to assist with managing your dotfiles. In both scripts, $SCRIPT_DIR resolves to the location of the script (the root of the repository).
sync.shis used to synchronize your machine's dotfiles with your local clone of this repository. It creates symlinks from your home directory to the dotfiles in this repository. In most cases, you only need to run this script once per machine. If existing dotfiles are found in your home directory, they are backed up to the$SCRIPT_DIR/.backupdirectory.download.shis used to download supporting resources, such as plugins and fonts, for the dotfiles synchronized by this repository. This script also updates the$SCRIPT_DIR/vscode/install_extensions.shand$SCRIPT_DIR/cursor/install_extensions.shscripts with your machine's installed extensions. Depending on how you use the repository, you may wish to run this script at regular intervals to keep your downloaded resources up to date.
Both scripts are idempotent2. You should fork this repository to save any modifications.
sync.sh links, download.sh vendors, and the per-machine *.upgrade.sh scripts upgrade. They are separate on purpose: download.sh used to do the upgrades too, in a branch that only ran when it was invoked with no argument β so you could never upgrade your binaries without also regenerating every vendored resource, and never regenerate one resource without skipping the upgrades.
| Script | Job |
|---|---|
sync.sh |
symlink dotfiles from this repo into $HOME |
download.sh |
vendor supporting resources (plugins, fonts, keys, extension lists) |
mac.setup.sh / ubuntu.setup.sh |
first-run provisioning of a new machine |
mac.upgrade.sh |
upgrade every off-the-shelf binary on a macOS workstation |
ubuntu.upgrade.sh |
the same, for Linux |
pico.upgrade.sh |
the same, for a headless macOS server |
bootstrap-agents.sh |
install the separate agent tier and wire ~/.agents (see Two tiers) |
mac.upgrade.sh runs sections you can list and select, and supports a dry run:
bash mac.upgrade.sh --dry-run # print every command, change nothing
bash mac.upgrade.sh --list # section names
bash mac.upgrade.sh --only brew # one section
bash mac.upgrade.sh --casks # also upgrade casks (force-quits GUI apps)
bash mac.upgrade.sh --trust-taps # unblock third-party taps first (see below)Two behaviors worth knowing before you run it:
- On Homebrew 6, formulae from an untrusted third-party tap are silently excluded from
brew outdatedandbrew upgrade, both of which still exit0.mac.upgrade.shdetects and names the frozen upgrades instead of reporting success;--trust-tapsfixes them. claude updateis skipped whenCLAUDECODE=1, so running this from inside a live Claude Code session will not swap the binary underneath it. Pass--claudeto force.
The cursor and vscode cases of download.sh write files that are tracked in git. Running them on a machine that has only a subset of the extensions adds its own and removes nothing, so a subset machine can never silently shrink the canonical list. To make the tracked list match the current machine exactly, ask for it:
./download.sh cursor --prune # deliberate removal; review the diff before committingIf the editor CLI is missing, or reports zero extensions, the tracked file is left alone.
Important
The download.sh script requires curl.
To synchronize your machine's dotfiles to this repository and download the latest supporting resources, run the following commands in a terminal:
git clone https://github.com/azigler/dotfiles
cd dotfiles
./sync.sh
./download.shThat is the whole install β no agent tier required. To add one afterwards, see Two tiers:
AGENTS_REPO=owner/repo ./bootstrap-agents.shTo add or remove dotfiles synchronized by this repository, edit the sync.sh script's case statement that iterates over all folders in this repository. Ensure there is a corresponding folder in the repository to correspond with your entry in the case statement. For example, to synchronize the $SCRIPT_DIR/new_dotfile_folder/new_dotfile file to $HOME/.new_dotfile:
"new_dotfile_folder")
sync_source "$SCRIPT_DIR/new_dotfile_folder/new_dotfile" "$HOME/.new_dotfile"
;;To synchronize the entire $SCRIPT_DIR/new_dotfile_folder folder and its contents to $HOME/.new_dotfile_folder:
"new_dotfile_folder")
sync_source "$SCRIPT_DIR/new_dotfile_folder" "$HOME/.new_dotfile_folder"
;;Tip
To reduce repository clutter and exclude duplicate source code, add downloaded resources (like cloned repositories) to the .gitignore file.
To add or remove supporting resources, edit the download.sh script's case statement that iterates over all folders in this repository. Ensure there is a corresponding folder in the repository to correspond with your entry in the case statement. For example, to download https://url-to-download.com to $SCRIPT_DIR/new_dotfile_folder:
"new_dotfile_folder")
fetch_file "https://url-to-download.com" "$SCRIPT_DIR/new_dotfile_folder"
;;To uninstall, replace the symlinks with your original dotfiles from the $SCRIPT_DIR/.backup directory or otherwise break the symlinks.
Footnotes
-
Dotfiles are configuration files that customize the behavior and appearance of various software applications and tools. While traditionally referring only to a file or folder with a name that starts with
., in this repository a dotfile refers to any kind of configuration file or folder. β© -
Idempotence is defined as a function that can be executed several times without changing the final result beyond its first iteration. β©