- Shell 95%
- Lua 5%
joelazar's dotfiles ๐ #
Screenshots ๐ผ๏ธ #
Wallpaper + Raycast ๐๏ธ #
Neovim with my custom config ๐ #
Eza + fzf ๐๐ #
Lazygit ๐ฆฅ๐ฑ #
Zen browser ๐งโโ๏ธ #
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:
- Platform: macOS
- Dotfile manager: chezmoi
- Bootstrap path:
bootstrap.sh - First-run automation:
run_once_install_packages.sh.tmpl,run_once_settings.sh.tmpl, plusrun_onchange_*scripts for cloning my repos to~/Code/joelazar(run_onchange_before_clone-repos.sh.tmpl), default apps, CleanShot,pmsetsudoers, and Node native module rebuilds - Theme: Catppuccin Mocha across most of the stack
- Fonts: Maple Mono / Maple Mono NF
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:
- vi-style key bindings
- Starship prompt with
mise,sudo, and Yazi indicators viadot_config/starship.toml - Atuin for history
- Zoxide for smarter directory jumping
- Mise for runtime management via
dot_config/mise/config.toml - Television shell integration so
Ctrl+Topens context-aware pickers instead of a generic file list
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:
- Yazi for file management via
dot_config/yazi/ - fzf, fd, and ripgrep for fast terminal navigation
- Eza for directory listings via
dot_config/eza/ - Television with 67 channels in
dot_config/television/cable/
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:
- Lazygit config in
dot_config/lazygit/config.yml - gh-dash config in
dot_config/gh-dash/config.yml delta+codediff.nvimfor readable diffs- custom scripts for repo cleanup, submodule updates, and recursive repo management
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 tiling window manager config in
dot_config/aerospace/aerospace.toml - Karabiner-Elements keyboard remapping in
dot_config/private_karabiner/, including adisable_cmd_tab.jsonprofile - macOS defaults and shell/editor bootstrapping in
run_once_settings.sh.tmpl - launch agents in
private_Library/LaunchAgents/ - app defaults, file associations, Dock behavior, keyboard repeat, Touch ID for
sudo, and similar setup tasks
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:
- Claude Code in
dot_claude/ - Pi in
dot_pi/ - llama.cpp (
llama-server) for local models in router mode (pi:/llama,/model), kept running by a launch agent
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:
- Catppuccin Mocha theme in
dot_pi/agent/themes/ - local model definitions in
dot_pi/agent/models.json - guardrails for secrets, sensitive files, and permissions in
dot_pi/agent/extensions/guardrails.json - tracked agent settings in
dot_pi/agent/private_settings.json
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:
- joelazar/pi-tuicr, review the diff in tuicr and send the comments back to pi
- joelazar/pi-lazygit, open lazygit from inside a session
- joelazar/pi-nvim, open Neovim from inside a session, landing on changed files
- joelazar/pi-review, a
/reviewand/end-reviewcode review workflow - joelazar/pi-copy-block, copy a code block out of the last reply
- third-party:
pi-guardrails,visual-explainer,pi-claude-code-use,session-recall, andi-have-adhd
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
npmentries: Pi,gondolin,ccusage,npm-check, andobsidian-headless.chezmoiscripts/run_onchange_rebuild-node-native-modules.sh.tmplrebuilds native addons (e.g.better-sqlite3) of global npm packages whenever the Node ABI changes
- UV tools installed with extra dependencies:
ansible-core(withansibleandnetaddr),pgcli(with Catppuccin styling andpsycopg[binary]), andpylatexencfor inline LaTeX rendering in Neovim - GitHub CLI plugin
gh-dash - Yazi plugins
toggle-pane,smart-filter,diff,git,ouch,smart-enter, andfr - 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.