Dotfiles for my macos setup

README.md

joelazar's dotfiles ๐Ÿš€ #

Screenshots ๐Ÿ–ผ๏ธ #

Wallpaper + Raycast ๐Ÿ–Œ๏ธ #

joedotfiles - wallpaper+raycast

Neovim with my custom config ๐Ÿ“ #

joedotfiles - neovim

Eza + fzf ๐Ÿ“‚๐Ÿ” #

joedotfiles - eza+fzf

Lazygit ๐Ÿฆฅ๐ŸŒฑ #

joedotfiles - lazygit

Zen browser ๐Ÿง˜โ€โ™€๏ธ #

joedotfiles - zen


Overview ๐Ÿงฐ #

This repo is the source of truth for my macOS setup.

I use chezmoi to manage shell config, editor settings, package installs, macOS defaults, AI tooling, and a pile of small workflow tweaks that are easy to forget until you lose them. The point is simple: I should be able to set up a new machine, run chezmoi apply, and get back to work without rebuilding my environment from memory.

A few quick facts:


What lives here ๐Ÿ“ #

Path What it contains
dot_config/ App and CLI configuration for tools like Fish, Ghostty, Yazi, Television, Starship, Mise, Lazygit, pgcli, Wireshark, and more
dot_pi/ Pi agent configuration, prompts, themes, skills, and extension config
dot_claude/ Claude Code configuration
private_dot_local/bin/ Personal utility scripts
scripts/ Shared helper scripts used by install/setup flows, including pi-packages-update
Brewfile Homebrew packages, casks, and npm globals

Highlights โœจ #

Shell and terminal ๐Ÿš #

My day-to-day shell is Fish, with config in dot_config/private_fish/.

That setup includes:

The terminal is Ghostty, configured in dot_config/ghostty/config. It uses Catppuccin Mocha, Maple Mono NF, split navigation shortcuts, a huge scrollback buffer, and keybinds to dump the scrollback into an editor or the browser.

Editors โœ๏ธ #

I mostly use Neovim.

Neovim lives in a separate repo: joelazar/nvim-config. run_onchange_before_clone-repos.sh.tmpl clones it to ~/Code/joelazar/nvim-config, and chezmoi symlinks ~/.config/nvim to that checkout.

Search, navigation, and file management ๐Ÿ”Ž #

A lot of this setup is about moving around quickly:

Those Television channels cover far more than files. There are pickers for git branches, worktrees, diffs, repositories, Docker and Kubernetes resources, AWS resources, ports, launchd services, recent files, markdown search, and more.

Git and GitHub workflow ๐ŸŒฟ #

Git tooling is a big part of this repo:

The Lazygit setup includes custom PR commands, conventional commit helpers, GitHub shortcuts, Catppuccin Mocha styling, and delta-powered diff views.

macOS workflow ๐ŸŽ #

This repo also handles the machine itself, not just terminal tools.

AeroSpace is set up with workspace assignments, vim-style focus movement, resize modes, and app launch shortcuts for tools I use constantly.


AI and coding-agent setup ๐Ÿค– #

A lot of this repo is devoted to AI-assisted development. That part has grown quite a bit.

Agent clients and configs ๐Ÿ› ๏ธ #

This repo currently tracks config for:

Codex and Antigravity CLI are installed from the Brewfile but carry no tracked config. Topgrade updates all of these agents (brew step) plus Pi's local packages.

Pi agent ๐Ÿฅง #

Pi is where most of the custom work happens.

The config in dot_pi/agent/ includes:

Models cycle forward with ctrl+space via dot_pi/agent/keybindings.json. The enabled set lives in enabledModels in the managed settings.

Pi extensions ๐Ÿงฉ #

My extensions live in their own repos and are wired in through private_settings.json.

The extensions list loads individual entries from joelazar/pi-extensions, the personal collection: sandbox, context, split-fork, spawn, commit, pr-create, cwd-history, export-md, save-md, anthropic-extra, web-tools, rtk, ask-user, skill-toggle, thinking-back, footer, and btw.

The packages list pulls in standalone packages:

Only dot_pi/agent/extensions/guardrails.json stays here, since it configures the third-party pi-guardrails package rather than an extension of mine.

Agent skills ๐ŸŽฏ #

Skills live in a separate repo: joelazar/skills. The same clone script puts it in ~/Code/joelazar/skills, and chezmoi symlinks ~/.agents/skills to that checkout. ~/.claude/skills is a symlink to ~/.agents/skills, so every agent reads the same library.


Package management ๐Ÿ“ฆ #

Packages are listed in the Brewfile. On first apply, run_once_install_packages.sh.tmpl takes care of the rest. That script installs the Homebrew bundle, Rust via rustup, UV tools, GitHub CLI plugins, and Yazi plugins.

Some notable pieces from the current setup:

  • Node globals installed by Homebrew bundle npm entries: Pi, gondolin, ccusage, npm-check, and obsidian-headless
    • .chezmoiscripts/run_onchange_rebuild-node-native-modules.sh.tmpl rebuilds native addons (e.g. better-sqlite3) of global npm packages whenever the Node ABI changes
  • UV tools installed with extra dependencies: ansible-core (with ansible and netaddr), pgcli (with Catppuccin styling and psycopg[binary]), and pylatexenc for inline LaTeX rendering in Neovim
  • GitHub CLI plugin gh-dash
  • Yazi plugins toggle-pane, smart-filter, diff, git, ouch, smart-enter, and fr
  • Casks for the desktop side: Ghostty, Raycast, AeroSpace, Karabiner-Elements, 1Password, Obsidian, CleanShot, Claude, Codex, Antigravity CLI, and more

Setup โšก #

Fresh machine ๐Ÿ†• #

If Homebrew and chezmoi are not installed yet, start with:

curl -sSL https://raw.githubusercontent.com/joelazar/dotfiles/main/bootstrap.sh | bash

Or clone locally and run:

git clone https://github.com/joelazar/dotfiles.git
cd dotfiles
./bootstrap.sh

Existing chezmoi setup ๐Ÿ”ง #

If you already have Homebrew and chezmoi:

brew install chezmoi
chezmoi init https://github.com/joelazar/dotfiles.git
chezmoi apply

First-time prompts ๐Ÿ’ฌ #

During initialization, chezmoi asks for:

  • git email
  • git username
  • git email and username for work repositories

Those values come from .chezmoi.toml.tmpl.

Important note โš ๏ธ #

This repo is the chezmoi source directory, not the live destination.

If you edit files here, you need to run:

chezmoi apply

Without that step, your real dotfiles under $HOME will not change.


Day-to-day maintenance ๐Ÿ” #

A few commands I use a lot:

chezmoi apply            # push source changes into the live home directory
chezmoi diff             # preview what will change

Custom scripts ๐Ÿง‘โ€๐Ÿ’ป #

Most of the personal helpers live in private_dot_local/bin/.

Script What it does
custom-update Interactive end-of-topgrade steps
discord-summary Summarizes the last 24h of selected Discord channels via kagi
fonttest Checks terminal font rendering
formatter Formats USB drives and SD cards with a gum UI
term-tab Opens a new Rex or Ghostty tab in a directory, optionally with a command
git-default-branch Prints origin's default branch; shared by the other git scripts
git-get git get <repo>: clones into a gj.root-based directory layout
git-moji git moji: gitmoji commit picker built on gum (lazygit ctrl+g; conventional commits on ctrl+v)
git-pr git pr: fills in every PR field, then shows a review screen (lazygit ctrl+r)
git-sync git sync [--hard] [--submodules] [dir...]: fetch and fast-forward repos and submodules (lazygit U)
git-wt git wt <branch>: worktree under the gj layout; fish gwt also cds into it
kokoro Local text-to-speech via the Kokoro ONNX model
listen-later Turns an article, file, or text into a Kokoro-narrated Spotify episode
pi Runs the Pi agent CLI through the mise-managed Node 26 runtime
restic-backup Backs up selected dotfiles and configs to $RESTIC_REPOSITORY via restic
restic-maintain Prunes old snapshots from the restic backup repo
restic-mount Mounts the restic repo to browse and copy files
switch-main-display Changes the primary display on multi-monitor setups
toggle-lid-sleep Raycast script that toggles clamshell sleep
transcribe Offline audio/video transcription via whisper.cpp
untilfail Repeats a command until it fails
workspace-tabs Opens the daily terminal workspace: Obsidian vault in nvim plus gh-dash
wtfport Shows what is listening on a port and can kill it

The restic scripts share private_dot_local/lib/restic-common.sh. Shared shell helpers used by the setup scripts live in scripts/utils and scripts/utils_install.


Theming ๐ŸŽจ #

Catppuccin Mocha is the common thread through most of the environment: Ghostty, Tmux, Fish, Yazi, Television, Lazygit, Bat, Btop, Starship, Atuin, Eza, Delta, Fzf, Gh-Dash, and K9s all use it in one form or another.

Fonts are centered on Maple Mono and Maple Mono NF, including OpenType alternates like cv02, cv05, cv61, and cv63.


Acknowledgements ๐Ÿ™ #

Some helper functions and setup patterns were originally adapted from alrra/dotfiles.

Parts of the Pi setup are also adapted from or inspired by work from:

Author GitHub Contributions
Mario Zechner @badlogic Pi itself, plus extensions and skills adapted from the Pi ecosystem, such as sandbox
Armin Ronacher @mitsuhiko Extensions and skills adapted from agent-stuff, including answer, context, and split-fork
Aliou Diallo @aliou pi-guardrails package
Nico Bailon @nicobailon visual-explainer package

License ๐Ÿ“„ #

This repository is available under the MIT license.