CodeVetter · Repo Unpack · System map
ohmyzsh/ohmyzsh
Oh My Zsh is a sourced shell framework, not a daemon: oh-my-zsh.sh is the single entrypoint sourced from ~/.zshrc and it orchestrates fpath setup, compinit, lib files, plugins, custom overrides, and the theme. Runtime state lives in $ZSH_CACHE_DIR (completion dump, .zsh-update epoch file, probe caches) and $ZSH/log (update.lock). External integrations are git (self-update via pull --rebase), the GitHub REST API (update check, PR label check), curl/wget/fetch, and chsh. CI is GitHub Actions: syntax checking, installer testing, a Vercel deploy of install.sh, vendored-dependency updates, and OpenSSF Scorecard.
- oh-my-zsh.sh is the sole runtime entrypoint, sourced from .zshrc after the user sets ZSH/ZSH_THEME/plugins; it aborts with a process-tree dump if loaded by a non-zsh shell and refuses non-zsh emulation modes.
- Three env vars define the layout: ZSH (repo dir, defaulting to the script's own dir), ZSH_CUSTOM (default $ZSH/custom, a gitignored shadow tree), and ZSH_CACHE_DIR (default $ZSH/cache, falling back to ${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh when unwritable).
- Before compinit, each name in the $plugins array is resolved by is_plugin() to $ZSH_CUSTOM/plugins/<name> or $ZSH/plugins/<name> (a dir containing <name>.plugin.zsh or _<name>) and prepended to $fpath.
- Completion init writes $ZSH_COMPDUMP (default ${ZDOTDIR:-$HOME}/.zcompdump-<SHORT_HOST>-<ZSH_VERSION>), deletes and rebuilds it when embedded '#omz revision'/'#omz fpath' metadata lines go stale, and zrecompile-compiles it under a .lock mkdir.
- _omz_source() implements the override layer: for each lib/plugins path it prefers $ZSH_CUSTOM/<path> over $ZSH/<path>, and honors 'zstyle :omz:lib:<name>|plugins:<name> aliases no' by snapshotting and restoring the alias tables around the source.
- Load order is fixed: all lib/*.zsh files, then each plugin's <name>.plugin.zsh, then every $ZSH_CUSTOM/*.zsh, then the theme resolved from $ZSH_CUSTOM, $ZSH_CUSTOM/themes, or $ZSH/themes.
- lib/cli.zsh defines the `omz` dispatcher: it maps argv[1] to functions named _omz::<command> (changelog, help, plugin, pr, reload, shop, theme, update, version) and registers a `_omz` compdef completer.
- Self-update is split across two files: tools/check_for_upgrade.sh is sourced at every shell start to gate and trigger updates, while tools/upgrade.sh does the actual `git pull --rebase $remote $branch` using per-repo git config keys oh-my-zsh.remote and oh-my-zsh.branch.
- tools/install.sh is a POSIX sh installer meant to be run via curl|sh: it does a manual `git init` + `git fetch --depth=1` into $ZSH, materializes .zshrc from templates/zshrc.zsh-template with a sed-substituted ZSH path, and optionally chsh's the login shell to zsh.
- The installer is deployed to install.ohmyz.sh by the installer.yml workflow: it copies tools/install.sh into .github/workflows/installer/ and runs `vc deploy --prod` against a Vercel project whose vercel.json rewrites '/' to '/install.sh'.
- lib/git.zsh wraps all prompt-time git calls in __git_prompt_git (GIT_OPTIONAL_LOCKS=0) and exposes git_prompt_info/git_prompt_status plus helpers like git_current_branch; lib/async_prompt.zsh provides an experimental fork-pipe-zle async framework that git.zsh registers into via _omz_register_handler.
- The repo vendors 368 plugin directories under plugins/ (each with <name>.plugin.zsh and usually a README.md; some only ship a _<name> completion file) and 143 *.zsh-theme files under themes/.
- Vendored plugin dependencies are declared in .github/dependencies.yml (repo/branch/version plus pre/post-copy shell snippets) and synced weekly by .github/workflows/dependencies/updater.py under the dependencies.yml workflow.