Personal dotfiles managed with chezmoi, targeting macOS (Homebrew) and Arch Linux (pacman plus yay/paru for AUR packages).
On a fresh machine (installs chezmoi, pulls this repo, and applies it):
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply fabioluciano/dotOr, if chezmoi is already installed:
chezmoi init --apply https://github.com/fabioluciano/dot.git- A Bitwarden vault unlocked via the
bwCLI (bw login && bw unlock) — used to populate tokens/API keys in~/.zshenv. The expected item is nameddotfiles-tokens. - A YubiKey for GPG/SSH commit signing (the
run_before_*scripts derive the public key andallowed_signers; signing degrades gracefully if absent). - On Arch,
yayorparumust be installed beforechezmoi apply. The Pacmanfile contains AUR packages such aszsh-antidote; the sync script fails clearly instead of trying to pass them to plainpacman.
| Manifest | Target | Installed by |
|---|---|---|
dot_Brewfile.tmpl |
~/.Brewfile |
brew bundle --global (macOS; taps + casks + core formulae em work machines) |
dot_Zerobrewfile.tmpl |
~/.Zerobrewfile |
zb bundle install (macOS personal only; lista compartilhada em .chezmoitemplates/core_formulae.tmpl) |
dot_Pacmanfile |
~/.Pacmanfile |
yay -S --needed/paru -S --needed (Arch; AUR helper required) |
dot_Krewfile |
~/.Krewfile |
kubectl krew install (kubectl plugins) |
| mise | ~/.config/mise |
mise install |
Package installs run automatically on chezmoi apply via the
run_onchange_after_* scripts in .chezmoiscripts/ — they re-run only when the
corresponding manifest changes (tracked by its content hash). Separately,
run_after_60-antidote-bundles.sh.tmpl runs after those package hooks on every
chezmoi apply: it runs antidote update --bundles to update plugin clones
without updating Antidote itself, then rebuilds both static bundles. The hook is
non-fatal for treatable errors, waits up to five seconds for its common lock, and
preserves all four bundle artifacts, although the update may already have
changed some plugin clones before a later failure.
chezmoi edit <file> # edit a source file in $EDITOR
chezmoi diff # preview pending changes
chezmoi apply # apply (package sync on manifest changes; Antidote hook every apply)
chezmoi update # pull latest from the repo and apply
mise run update-safe # update host packages only (topgrade)
mise run update-full # full update: packages + dotfiles + krew + nvim + tmuxdot_zshrc.tmpl,private_dot_zshenv.tmpl,dot_zsh_plugins*.txt.tmpl— zsh (antidote static bundle, cached completions, lazy tool init).private_dot_config/— app configs (nvim/AstroNvim, tmux, ghostty, k9s, jj, starship, mise, espanso, …).private_dot_config/git/,private_dot_gnupg/,private_dot_ssh/— git identity + SSH-based commit signing via YubiKey..chezmoiscripts/—run_before_*(YubiKey key material),run_onchange_after_*(package sync), andrun_after_60-antidote-bundles.sh.tmpl(Antidote refresh and bundle rebuild on every apply).
These must be present before chezmoi init --apply will succeed:
| Dependency | Why | macOS | Arch |
|---|---|---|---|
| chezmoi (>=2.47) | dotfile manager itself | brew install chezmoi |
pacman -S chezmoi |
| git | pulls the source repo | included with Xcode CLI tools | pacman -S git |
bitwarden-cli (bw) |
unlocks dotfiles-tokens vault to populate ~/.zshenv |
brew install bitwarden-cli |
pacman -S bitwarden-cli |
| mise | installs Node/Python/etc per-project | brew install mise |
pacman -S mise |
| Homebrew (macOS) | manages ~170 formulae + casks | already on system | n/a |
| pacman + yay/paru (Arch) | manages repository and AUR packages | n/a | pacman is built in; install yay or paru before applying |
| antidote | zsh plugin manager (bundles rebuilt by the post-apply hook) | brew install antidote |
yay -S zsh-antidote or paru -S zsh-antidote (AUR) |
| pkgfile | local package index used by Arch's command-not-found plugin |
n/a | included in dot_Pacmanfile; initialize with sudo pkgfile -u |
| krew | kubectl plugin manager (dot_Krewfile) |
brew install krew |
pacman -S krew-bin |
To bootstrap an AUR helper on a fresh Arch installation, install the build
tools with pacman, then build one helper from the AUR before applying this
repository. For example:
sudo pacman -S --needed base-devel git
git clone https://aur.archlinux.org/yay.git
(cd yay && makepkg -si)
rm -rf yayAfter that, chezmoi apply can install zsh-antidote and the remaining
manifest packages through yay (replace it with paru if that is your
chosen helper). The Arch command-not-found plugin uses pkgfile; run
sudo pkgfile -u after the first installation and periodically to refresh its
local index.
Optional but expected: a YubiKey for GPG/SSH commit signing. The
run_before_* scripts derive the public key and allowed_signers; signing
degrades gracefully if absent.
Preview before applying:
chezmoi diff # show exactly what would change
chezmoi --dry-run apply # apply without touching anythingchezmoi doctor catches most misconfigurations (missing git, broken templates, stale cache):
chezmoi doctorBitwarden vault locked — the run_onchange_after_* scripts call bw to
fetch tokens. If the vault is locked, you'll see bw get failures:
bw login
bw unlock # unlock the vault, then re-run:
chezmoi applyTemplate render errors — if a .tmpl file references a missing data key
(defined in .chezmoidata/), chezmoi will fail with a template error.
Debug with:
chezmoi execute-template < private_dot_zshenv.tmplantidote bundle not refreshing —
run_after_60-antidote-bundles.sh.tmpl runs after the package hooks on every
chezmoi apply. It first runs antidote update --bundles (which updates plugin
clones, not Antidote itself) and then regenerates and compiles both static
bundles from ~/.zsh_plugins_pre.txt and ~/.zsh_plugins.txt. If updating,
rendering, validation, compilation, or lock acquisition fails, the hook is
non-fatal and preserves the four bundle artifacts byte-for-byte; inspect the
warning on stderr. The update can have changed some plugin clones before that
failure, so a later apply may retry with those clones.
The normal zsh startup path loads the static bundles. Its conditional fallback
may call antidote bundle when a manifest is newer or the Antidote cache is
missing, but it first takes the common kernel lock with a zero-second timeout.
If another process holds that lock, startup does not wait or regenerate and
loads the current bundle instead.
Updating plugins — explicit plugin references in these manifests are not
pinned to SHA values. On every chezmoi apply, antidote update --bundles
updates their clones before antidote bundle regenerates and compiles the
static bundles; antidote bundle itself does not pull updates. Review with
chezmoi diff before applying. If the refresh fails, the current four bundle
artifacts stay intact, even though some clones may already have been updated.
Entries using kind:defer are a deliberate exception: Antidote injects
romkatv/zsh-defer internally and provides no officially supported syntax for
pinning that injected dependency. This keeps those plugins on the deferred
startup path.
chezmoi apply is idempotent. The source directory is the source of truth; the
target files are derived from it. To undo a change:
-
Inspect what changed:
chezmoi diff
-
Revert in the source directory:
# undo the last commit git -C "$(chezmoi source-dir)" revert HEAD # or checkout a specific file git -C "$(chezmoi source-dir)" checkout HEAD -- <path>
-
Re-apply from the reverted source:
chezmoi apply
Because chezmoi apply re-syncs from source, reverting a commit and applying
restores the previous state. The --dry-run flag lets you verify the rollback
before committing.
Note: Package installs (brew/pacman) are not automatically undone by
reverting a dotfile commit. If you added a formula and want to remove it,
edit dot_Brewfile.tmpl/dot_Zerobrewfile.tmpl/dot_Pacmanfile and run
chezmoi apply again.
The change-providers command switches providers across all coding agents
(opencode, omp, pi) in one shot, or per-agent via subcommand:
change-providers zai # switch all agents to ZAI (default profile)
change-providers zai recommended # all agents, recommended profile
change-providers opencode zai # only opencode
change-providers omp xiaomi ultra # only omp, xiaomi, ultra profile
change-providers pi deepseek # only pi
change-providers status # show all agents' state
change-providers reset # reset all to default
change-providers dry-run zai # preview without applyingHow it works:
- Writes the chosen provider name to each agent's state file
(
~/.config/{opencode,omp,pi}/.active_provider). - Runs
chezmoi applyto re-render each agent's config from its template, which reads.active_provideras the single source of truth. - Each agent resolves the native provider id for its binary via the shared
[providers.<key>]registry in.chezmoidata/providers.toml.
Fallback behavior: opencode is configured with automatic intra-provider fallback
between tiers (pro → fast → cheap) when the primary model is unavailable
(rate-limited, throttled, etc.). Fallback stays within the active provider —
it never crosses to a different provider. The tier matrix in .chezmoidata/providers.toml
controls the model for each tier.
Profiles: pass an optional profile as the last argument. moderate is the
default, optimized/super trade quality for cost, and recommended applies
the Oh My OpenAgent recommended effort/variant tiers per role where the active
provider supports them.
ultra minimizes cost further by selecting the lowest safe reasoning variant
for each provider/model family and leaving unsupported cases for the provider
runtime default.
Verify current provider:
change-providers statusThe change-providers command is part of this dotfiles repo (chezmoi-managed
at ~/.local/bin/change-providers).
Opencode skills are managed by the skills CLI and are not tracked by chezmoi.
Skill files live in ~/.config/opencode/skills/ and the lock file is at
~/.agents/.skill-lock.json. Use mise run skills-* tasks (defined in
~/.config/mise/config.toml) or run the skills CLI directly to install,
update, and remove skills across machines.