macOS path_helper runs after .zshenv and can move system Python ahead of pyenv. Add an idempotent login hook and preserve it across later easyzsh migrations.
The pyenv fragment lived in the interactive overlay, so agents and zsh -c fell back to system Python. Install it through the always-on fragment path and keep XDG destinations aligned with the loader.
fnm lived in interactive-only ~/.config/zshrc, so ssh/agents/zsh -c
missed fnm-managed node. Source ~/.config/zsh/*.zsh from .zshenv and
install the fragment as zsh/fnm instead.
Always-on and machine hooks already live in .zshenv / local.zsh.
Drop the empty stub, remove it on deploy, and leave real .zprofile
files to optional migration into local.zsh only.
Drop ~/.config/zsh/{env,interactive,login} modules. PATH and local.zsh
live in .zshenv; interactive UX is a single .zshrc again. Deploy only
installs the three stubs and removes obsolete trees/examples.
Replace the local/ directory of split env/login/interactive files with
one always-on local.zsh sourced from .zshenv. Deploy migrates old
fragments and never overwrites local.zsh.
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.
Non-interactive agent shells (Codex, Claude) skip .zshrc and never saw
user-local tools installed via pipx/uv/grok. Add ~/.local/bin in
.zshenv with an idempotent guard, and source optional
~/.config/zshenv.local for machine-local early env.
Move brew shellenv into .zshenv so PATH is available outside
interactive shells, and make install guarantee a Trash backend
for safer rm aliases on both macOS and Linux.