Skip to content

binGhzal/dotfiles

Repository files navigation

dotfiles

Chezmoi-driven, reset-ready macOS + Linux workstation. Source of truth for packages, shell, editors, terminal, app preferences, system defaults, secrets, and automation.

V10 architecture (May 2026): bash engine + per-domain catalog + profile-cube persona detection. See docs/architecture.md for the layered map and docs/adr/0001-v10-decisions.md for the locked design decisions.

Bootstrap

macOS / Linux / WSL

sh -c "$(curl -fsLS https://binghzal.github.io/dotfiles/setup.sh)"

This:

  1. Installs Homebrew (macOS) or chezmoi (Linux/WSL via get.chezmoi.io)
  2. Runs chezmoi init binGhzal/dotfiles
  3. Prompts persona cube (4 bools + identity); skipped in CI/Codespaces

Set DOTFILES_APPLY=1 when you want the installer to run chezmoi init --apply. Containers and Codespaces set that automatically.

GitHub Codespaces / devcontainer

Either set dotfiles_repo: binGhzal/dotfiles in your Codespaces user settings, or add to .devcontainer/devcontainer.json:

{
  "postCreateCommand": "sh -c \"$(curl -fsLS https://binghzal.github.io/dotfiles/setup.sh)\""
}

Auto-detects ephemeral env, forces non-interactive apply, skips secrets.

Forker override

DOTFILES_OWNER=<you> DOTFILES_REPO=dotfiles \
  sh -c "$(curl -fsLS https://binghzal.github.io/dotfiles/setup.sh)"

Stack

Layer Tool
Dotfile manager chezmoi 2.70+
macOS packages Homebrew (brew + cask + mas)
Linux packages apt / dnf / pacman / zypper / apk (auto-detected)
Cross-platform runtimes mise (node/go/python/rust/...)
Shell zsh + zinit
Terminal Ghostty / iTerm2 (macOS), zellij multiplexer
Editors nvim / VS Code / Cursor
VCS git (+ jj opt-in)
Secrets 1Password + age (encrypted_*.age committed)
Automation bin/pkgwatch + bin/autosync

Daily commands

make help                  # list available targets
chezmoi --source="$PWD/home" diff
chezmoi --source="$PWD/home" apply -v
make defaults-all          # apply all macOS settings (idempotent)
make defaults-dock         # apply just dock domain
make validate-fast         # fast source gate
make validate              # clean-HOME dry-run gate
make lint                  # pre-commit
make test                  # shellcheck + bats
make brew-check            # rendered Brewfile is installed
make catalog-list          # entry counts per macOS domain
bin/pkgwatch list-pending  # see brew packages awaiting promotion
bin/autosync dry-run       # show policy-driven capture plan
bin/autosync status        # inspect autosync state
bin/manual-actions         # post-bootstrap human-required checklist

Profile cube

Persona-driven conditionals. Set once at chezmoi init, persisted in ~/.config/chezmoi/chezmoi.toml:

Flag Default Drives
use_secrets true 1Password + age decryption
personal_computer false Personal apps + install_personal_extras follow-up
homelab_member false Tailscale, homelab services
dev_computer true mise, gh, language runtimes
install_personal_extras false Heavy personal apps (gated by personal_computer)
hyprland_flavor none Linux desktop only; v2 hook

Auto-detected (never prompted): is_ephemeral, is_codespaces, is_devcontainer, is_wsl, is_darwin, is_linux, is_server, has_gui, chassis.

Full reference: docs/profile-cube.md.

Repository layout

.
├── home/                          # chezmoi source (.chezmoiroot points here)
│   ├── .chezmoi.toml.tmpl         # config template + persona cube
│   ├── .chezmoiignore.tmpl        # profile-aware path filter
│   ├── .chezmoidata/              # chezmoi data tree (auto-merged)
│   │   ├── 10-darwin/             # macOS catalog (per-domain TOML)
│   │   ├── 20-linux/              # Linux catalog (gsettings/wsl/server)
│   │   └── packages.yaml          # package source of truth
│   ├── .chezmoiscripts/           # OS-gated wrappers (templated, thin)
│   │   ├── darwin/                # defaults + pkgwatch/autosync LaunchAgents
│   │   └── linux/                 # pkg/gsettings/sshd/autosync wrappers
│   ├── .chezmoitemplates/lib/     # sourced bash function libraries
│   │   ├── apply_setting.sh.tmpl  # 14-branch dispatcher
│   │   ├── gs.sh.tmpl             # gsettings idempotency
│   │   ├── pkg.sh.tmpl            # cross-distro pkg installer
│   │   └── log.sh.tmpl            # leveled stderr
│   ├── dot_*                      # deployed dotfiles (zsh, git, etc.)
│   ├── private_dot_ssh/           # encrypted SSH config
│   └── Library/                   # macOS-specific app configs
├── install/                       # raw bash engine entry-points
│   ├── macos/common/apply-defaults.sh
│   └── linux/{common,desktop,server}/*.sh
├── bin/                           # user-facing helpers
│   ├── pkgwatch                   # brew install detection daemon
│   ├── snapshot                   # pre-apply tar.zst backup
│   ├── autosync                   # policy-driven source capture
│   ├── autosync-push              # one-release compatibility shim
│   ├── manual-actions             # post-bootstrap checklist
│   ├── recapture-plists           # reviewed plist recapture
│   ├── nerd-font-smoke-test
│   └── discover-default           # GUI-tweak → catalog suggestion
├── tests/                         # bats test suites
│   ├── agent-tooling.bats
│   ├── chezmoi/                   # integration
│   └── bin/                       # bin helpers
├── scripts/                       # validation, render, import, archive
├── docs/                          # architecture, profile-cube, runbooks, ADRs
├── .chezmoiroot                   # "home"
├── .chezmoiversion                # "2.70.0"
├── Makefile                       # `make help` for full target list
├── setup.sh                       # thin bootstrap handoff
└── .github/                       # CI workflows + CODEOWNERS + dependabot

Idempotency contract

Every chezmoi apply is gated by 3 layers:

  1. run_onchange_* content hash — chezmoi only fires the wrapper when source content changes (incl. lib hash baked into script comment).
  2. Engine dirty-set — only entries whose defaults read differs from desired contribute to the killall union.
  3. Lib _apply_* branches — read-before-write per entry. Outputs unchanged or changed: A -> B.

Result: second make defaults-all produces zero defaults write and zero killall. Verify with make test-idempotence.

Documentation

Doc What
docs/architecture.md Top-down layered map, idempotency contract
docs/profile-cube.md Persona flag truth tables + jq inspection
docs/adr/0001-v10-decisions.md V10 design decisions
docs/runbooks/new-machine.md Bootstrap walkthrough (mac/linux/wsl/codespaces)
docs/runbooks/recovery.md When chezmoi apply breaks something
docs/runbooks/secret-rotation.md Age key rotation procedure
docs/macos-defaults.md, docs/packages.md, etc. Current package/defaults surfaces

Forking

  1. Fork on GitHub

  2. Edit home/.chezmoidata/personal.toml:

    [personal]
    default_email = "you@example.com"
    default_name = "Your Name"
    default_github_user = "your-handle"
  3. Edit home/.chezmoidata/preferences.toml for your theme/editor preferences

  4. Tweak home/.chezmoidata/10-darwin/<domain>.toml per-domain catalog as needed

  5. Run DOTFILES_OWNER=your-handle sh -c "$(curl -fsLS https://your-handle.github.io/dotfiles/setup.sh)"

If you fork from V4 (pre-PR1), inspect scripts/archive/v4-migration/; those scripts are preserved history, not normal bootstrap steps.

V10 changelog

  • PR1 #11: Restructure to home/ chezmoi source root, drop dot CLI
  • PR2 #12: Bash engine replaces 715-line Python dotfiles_settings.py
  • PR3 #13: 4-bool persona cube + 9 detected flags + ephemeral skip
  • PR4 #14: Catalog migration from V4 settings.toml (65 entries across 7 domains)
  • PR5 #15: Linux engine scaffold (apt/dnf/pacman/zypper/apk + GNOME + WSL)
  • PR6 #16: pkgwatch LaunchAgent + 7 bin/ helpers + hooks wiring
  • PR7 #17: Slim setup.sh (208 → 111 lines), 8 ADRs, architecture, recovery runbook
  • PR8-PR20: macOS catalog split, Linux render/apply CI, package/runtime ownership, agent-tooling source split, and reset-readiness docs
  • PR21: Source-root resolver, real gates, snapshot safety, autosync V2, bridge untracking, package drift merge, and command-surface cleanup
  • PR21 cleanup follow-up: Make cleanup targets, approved generated-cache cleanup, reviewed Homebrew removal-candidate uninstall, and CI action cleanup

License

MIT. See LICENSE (if present).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors