This repository contains a personal dotfiles setup for shell, editor, and terminal tooling.
The layout is optimized for:
- fast interactive shell startup
- clear ownership boundaries
- safe bootstrapping with backups
- local overrides without polluting the main configuration
zsh: thin entrypoint, modular options, lazy tool integrations, aliases, secrets, and plugin loadingai: secret loading for AI and API toolingutil: editor and terminal-related configs, including tmux, Kitty, wezterm, and JetBrains-related files
ai/
.claude/ Claude settings and home-link helper
.codex/ Codex harness, hooks, and local setup
.hermes/ Hermes profiles, gateways, and sync scripts
archive/ historical configuration only
docs/ tutorials, how-tos, references, explanations
scripts/ bootstrap entrypoint and regression tests
util/ JetBrains, Kitty, tmux, WezTerm, assets
zsh/ startup orchestration and shell modules
.taskmaster/ task graph and planning metadata
Active configuration lives under ai/, util/, and zsh/. Runtime state such as logs, caches, databases, sessions, and heartbeat files is not part of the documented source layout. archive/ is historical data and is not loaded during startup.
Required:
gitbashzshoh-my-zshneovimtmuxfzf
Optional:
colorlsorezakubectlsshpassnvmsdkman
git clone https://github.com/hrllk/dotfiles.git ~/dotfiles
bash ~/dotfiles/scripts/bootstrap.shThe bootstrap script supports explicit stages:
--shell-only(the default when no option is provided): clones shell/terminal plugins, creates backups, and links shell/terminal configuration--ai: links Claude and Hermes configuration and prints Codex local-profile guidance without copying or linking Codex files--ai --sync-secrets: runs the explicit Hermes runtime secret synchronization step--dry-run: previews the selected stage without network, filesystem, launchctl, or secret writes- invalid flag combinations exit with code
2before any stage runs
The bootstrap script:
- clones
powerlevel10k,fzf-tab,zsh-autosuggestions, andzsh-syntax-highlightingwhen missing - clones tmux plugin manager (TPM) when missing
- backs up existing shell and terminal config files with a shared invocation timestamp
- creates symlinks for
zsh,ideavim,tmux,gitmux,kitty, andwezterm - keeps shell secret loading separate from Hermes runtime synchronization
Targets after bootstrap:
~/.zshrc->~/dotfiles/zsh/.zshrc~/.ideavimrc->~/dotfiles/util/jetbrains/.ideavimrc~/.tmux.conf->~/dotfiles/util/tmux/.tmux.conf~/.gitmux.conf->~/dotfiles/util/tmux/.gitmux.conf~/.tmux->~/dotfiles/util/tmux/.tmux~/.config/kitty/kitty.conf->~/dotfiles/util/kitty/kitty.conf~/.wezterm.lua->~/dotfiles/util/wezterm/wezterm.lua- the
--aistage can link~/.claudeand~/.hermes - Codex is never copied or linked automatically; prepare it explicitly with
ai/.codex/init-home-codex - tmux plugins are installed under
~/.local/share/tmux/plugins/and are not tracked in this repo - use tmux
prefix + Ito install plugins after startup
~/.zshrcis only an entrypoint; real shell config lives under~/dotfiles/zshindex.zshfiles act as orchestration layerssource_if_existsis used for optional local or machine-specific filessecrets/is split by domain with a shared helper and a single index entrypointintegrations/lazy/contains runtime loaders that are only initialized when needed
Start at the documentation index, or jump straight to a quadrant.
Tutorial
- First setup: install the environment on a new Mac
How-to
- Bootstrap: rerun, verify, and troubleshoot installation
- Add configuration: add an alias, module, secret domain, or Hermes profile
Reference
- Project structure: directory ownership and deployment paths
- Shell commands: every alias, function, lazy wrapper, and key binding
- Bootstrap CLI: flags, environment variables, exit codes
- Hermes gateways: profiles, wrappers, launchd wiring
Explanation
- Configuration architecture: startup order and fallbacks
- Secret handling: why tracked
.envfiles carry no secrets
Design and review
- AI agent tmux unread design: shared Codex/Claude Code completion state in tmux windows
- Structural review (2026-08-26): known structural issues and change candidates
time zsh -i -c exitMeasured on this machine:
- current setup:
real 0.14s,user 0.04s,sys 0.03s - full oh-my-zsh load:
real 0.54s,user 0.22s,sys 0.22s
The comparison is directional, but it shows the cost of loading the full OMZ stack.
~/.zshrcis only an entrypoint; real shell config lives under~/dotfiles/zshindex.zshfiles act as orchestration layerssource_if_existsis used for optional local or machine-specific filessecrets/is split by domain with a shared helper and a single index entrypointintegrations/lazy/contains runtime loaders that are only initialized when needed
zshinitialization is intentionally modular to keep interactive startup lightweightllusescolorlswhen available, and falls back to standard directory listings if it is notarchive/util/iterm/keeps historical iTerm export data out of the active config setenv.zshprefers~/.sdkman/candidates/java/currentfor Java when SDKMAN is installed, and otherwise falls back tojava_home -v 17when availablepath.zshowns PATH construction and is loaded afterenv.zshso it can use the environment values defined there- after
sdk default java <version>,which javashould resolve to~/.sdkman/candidates/java/current/bin/java - If you move to another machine, split machine-specific overrides into
env.local.zsh - The current layout is optimized for this machine, not for full portability