Split always-on PATH/env, login hooks, and interactive UX into a managed tree under ~/.config/zsh, with never-overwrite local/ hooks. Agents and interactive shells share one PATH owner; deploy.sh applies the layout safely across machines.
2.9 KiB
Easy Zsh Setup
One-command zsh environment: oh-my-zsh, powerlevel10k, and a curated plugin set (autosuggestions, syntax-highlighting, completions, history-substring-search, fzf-tab, k), plus eza, zoxide, fzf, and Nerd Fonts.
Install
curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/install.sh | bash
Options: --cp-hist / -c imports bash history; --non-interactive / -n
skips the default-shell change. The installer backs up existing shell stubs
before replacing them.
From a git checkout (recommended for multi-machine sync):
./deploy.sh --migrate-zprofile
Architecture
every zsh login only interactive only
────────── ────────── ────────────────
~/.zshenv (stub) ~/.zprofile (stub) ~/.zshrc (stub)
→ config/zsh/env/* → config/zsh/login/* → config/zsh/interactive/*
→ local/env.local.zsh → local/login.local.zsh → ~/.config/zshrc/* (before omz)
→ local/interactive.local.zsh
PATH for user tools is built once in ~/.config/zsh/env/00-path.zsh
(always-on), so non-interactive agent shells (zsh -c, Codex, Claude) resolve
~/.local/bin the same way interactive terminals do.
| Path | Role | Reinstall |
|---|---|---|
~/.zshenv ~/.zprofile ~/.zshrc |
Thin stubs | Overwritten |
~/.config/zsh/env/ |
Managed always-on env (PATH, Homebrew) | Overwritten |
~/.config/zsh/interactive/ |
Managed interactive UX (omz, aliases) | Overwritten |
~/.config/zsh/login/ |
Managed login hooks (usually empty) | Overwritten |
~/.config/zsh/local/* |
Machine-local env/login/interactive | Never overwritten |
~/.config/zshrc/*.zsh |
Personal/tool overlays (before omz) | Left alone |
~/.local/bin/ |
User tools + intentional shims (e.g. grok) |
Left alone |
Do not put ~/.grok/bin on PATH wholesale (generic names like agent shadow
other tools). Link wanted entrypoints into ~/.local/bin instead.
Personal configuration
Always-on (agents see this)
# ~/.config/zsh/local/env.local.zsh
. "$HOME/.cargo/env"
Login only (vendor hooks)
# ~/.config/zsh/local/login.local.zsh
# OrbStack, MacPorts, product installers — not primary PATH policy
Interactive overlays (before oh-my-zsh)
# ~/.config/zshrc/local.zsh
plugins+=(docker)
plugins=(${plugins:#zsh-autosuggestions})
Ready-made tool configs from this repo's zshrc/ directory:
curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- fnm pyenv
Current fragments: fnm, nvm, pyenv, p10k, merlin_devbox, merlin_worker.
Aliases that must beat oh-my-zsh belong after omz loads (see managed
interactive/20-post-omz.zsh) or in ~/.config/zsh/local/interactive.local.zsh.