CodeVetter · Repo Unpack · Data flow
ohmyzsh/ohmyzsh
Configuration flows inward from .zshrc variables (ZSH_THEME, plugins array, zstyle settings, DISABLE_* flags) which oh-my-zsh.sh reads while sourcing; state flows outward into $ZSH_CACHE_DIR (zcompdump, .zsh-update, probe/alias caches) and back into .zshrc itself when `omz` commands mutate it. Prompt rendering is the hot path: git status data moves from porcelain output through regex parsing into ZSH_THEME_* variables, either synchronously or through a forked async pipe read by a zle -F callback.
- Input boundary: .zshrc defines export ZSH, ZSH_THEME, plugins=(...) and optional zstyle ':omz:...' settings, then `source $ZSH/oh-my-zsh.sh` — the template file is generated by the installer via sed replacing the ZSH= line.
- Plugin data flow: $plugins names -> is_plugin() dir resolution -> dir prepended to $fpath -> <name>.plugin.zsh sourced via _omz_source, with $ZSH_CUSTOM/plugins shadowing $ZSH/plugins at both stages.
- Completion pipeline: plugin dirs + $ZSH_CACHE_DIR/completions enter $fpath, compaudit/compinit -i produce $ZSH_COMPDUMP, OMZ metadata comments are appended, and zrecompile emits $ZSH_COMPDUMP.zwc guarded by a mkdir lock.
- Update state lives in $ZSH_CACHE_DIR/.zsh-update (sourced to read LAST_EPOCH, EXIT_STATUS, ERROR) written by update_last_updated_file(); mutual exclusion is a mkdir on $ZSH/log/update.lock cleaned by an EXIT/INT/QUIT trap.
- Update-availability check: reads git config oh-my-zsh.remote/oh-my-zsh.branch, fetches the remote HEAD sha from api.github.com via curl/wget/fetch (2s timeout), then compares with local HEAD via `git merge-base`; non-GitHub remotes are assumed to have updates.
- Git prompt flow: __git_prompt_git runs `git rev-parse --git-dir --abbrev-ref HEAD` and `git status --porcelain -b`; _omz_git_prompt_status_match forces LC_ALL=C for regex parsing (workaround for REG_ILLSEQ on non-UTF-8 bytes); results map through ZSH_THEME_GIT_PROMPT_* variables into the prompt string.
- Async prompt flow: precmd hook _omz_async_request forks each registered handler writing to a pipe fd, stores fd/pid in _OMZ_ASYNC_FDS/_OMZ_ASYNC_PIDS, and zle -F triggers _omz_async_callback which stores output in _OMZ_ASYNC_OUTPUT[handler] and calls `zle .reset-prompt` only if it changed.
- .zshrc mutation flow (plugin enable/disable, theme set): awk program reads ${ZDOTDIR:-$HOME}/.zshrc -> writes .zshrc.new -> copies original to .zshrc.bck -> mv into place -> `zsh -n` syntax check -> on failure mv .zshrc.bck back -> _omz::reload execs a fresh zsh.
- Startup-cost caching: expensive probes are persisted in $ZSH_CACHE_DIR — grep alias flags (grep-alias), macOS scutil LocalHostName (localhostname, keyed by $HOST), and appearance command probes (appearance-probes, an associative array dumped via print -r).
- upgrade.sh normalizes legacy robbyrussell/oh-my-zsh remotes to ohmyzsh/ohmyzsh, stores the chosen remote in `git config oh-my-zsh.remote`, records pre-update HEAD in oh-my-zsh.lastVersion, and temporarily forces rebase.autoStash before restoring it.
- Terminal output boundary: termsupport precmd/preexec hooks emit OSC 0/1/2 title sequences and OSC 7 cwd notifications (percent-encoded via omz_urlencode) only when TERM/TERM_PROGRAM whitelists match and not inside Emacs or SSH.
- Installer data flow: env vars ZSH/ZDOTDIR/REPO/REMOTE/BRANCH/CHSH/RUNZSH/KEEP_ZSHRC drive behavior; git writes repo to $ZSH; existing .zshrc moves to .zshrc.pre-oh-my-zsh (older backups get datestamped); the old shell path is saved to ~/.shell.pre-oh-my-zsh for uninstall.sh to restore.