# ohmyzsh/ohmyzsh — codebase unpack

> Canonical page: https://codevetter.com/unpack/ohmyzsh

This is a deterministic Repo Unpack scan of ohmyzsh/ohmyzsh — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: 86ef6555e068663736a33376e4055aca9c1acc89 (2026-09-22)
- Last upstream commit: feat(hermes): add hermes plugin (#14111)
- Generated by codevetter 1.12.0 on 2026-09-22
- 1142 files scanned · 4.4 MB

## Languages

- Shell: 400 files
- Markdown: 394 files
- YAML: 14 files
- Python: 8 files
- JSON: 3 files

## Repository structure

- plugins/ — 937 files
- themes/ — 143 files
- lib/ — 22 files
- .github/ — 21 files
- tools/ — 7 files
- templates/ — 2 files
- .devcontainer/ — 1 files

Probable source entrypoint: `lib/` (inferred from the tree, not upstream docs)

## Structural health signals

Average score 7.7/10 across 8 files; 1 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- 86ef6555e068 (2026-09-22) feat(hermes): add hermes plugin (#14111)
- 32d7277ac34b (2026-09-22) docs(gh): fix the completion cache path in the README (#14117)
- e0d3557e14e5 (2026-09-21) fix(gradle): remove echo when running gradlew (#12893)
- b6830a53d575 (2026-09-21) feat(otp): honour OTP_HOME and XDG_DATA_HOME (#12953)
- fa82d8a3eb84 (2026-09-22) fix(frontend-search): use fallback search for dead dartlang docs URL (#14112)

## Overview

Oh My Zsh is a community-driven framework for managing zsh configuration: a user's .zshrc exports ZSH, ZSH_THEME and a plugins array, then sources oh-my-zsh.sh which wires up $fpath, runs compinit, and loads ~22 lib files, ~368 bundled plugins, and ~143 themes. It ships a self-updater that polls the GitHub API and re-pulls the repo via git, an `omz` CLI (lib/cli.zsh) that rewrites .zshrc to manage plugins/themes, and a curl|sh installer (tools/install.sh) that is deployed to install.ohmyz.sh via Vercel. Distinctive traits: everything is pure zsh sourced into the live shell, customization is layered through a $ZSH_CUSTOM shadow directory, and behavior is tunable via zstyle contexts under ':omz:...'.

## System map

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. — [oh-my-zsh.sh#L10-46](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L10-L46) [templates/zshrc.zsh-template#L78](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/zshrc.zsh-template#L78)
- 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). — [oh-my-zsh.sh#L50-68](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L50-L68) [.gitignore](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.gitignore)
- 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. — [oh-my-zsh.sh#L81-98](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L81-L98)
- 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. — [oh-my-zsh.sh#L129-185](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L129-L185)
- _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. — [oh-my-zsh.sh#L187-226](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L187-L226) [README.md#L374-424](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/README.md#L374-L424)
- 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. — [oh-my-zsh.sh#L230-264](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L230-L264)
- 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. — [lib/cli.zsh#L3-21](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L3-L21) [lib/cli.zsh#L23-117](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L23-L117)
- 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/check_for_upgrade.sh#L151-176](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L151-L176) [tools/upgrade.sh#L205-264](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L205-L264)
- 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. — [tools/install.sh#L307-352](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L307-L352) [tools/install.sh#L354-416](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L354-L416) [tools/install.sh#L418-515](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L418-L515)
- 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'. — [.github/workflows/installer.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/installer.yml) [.github/workflows/installer/vercel.json](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/installer/vercel.json)
- 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. — [lib/git.zsh#L10-12](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L10-L12) [lib/git.zsh#L171-236](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L171-L236) [lib/async_prompt.zsh#L28-43](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/async_prompt.zsh#L28-L43)
- 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/. — [plugins/git/git.plugin.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/git/git.plugin.zsh) [plugins/github/github.plugin.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/github/github.plugin.zsh) [themes/random.zsh-theme](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/themes/random.zsh-theme)
- 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. — [.github/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/dependencies.yml) [.github/workflows/dependencies/updater.py](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies/updater.py) [.github/workflows/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies.yml)

## Feature catalog

User-facing surface = (a) the `omz` CLI with plugin/theme/update/pr/changelog subcommands, (b) a large catalog of plugins and themes enabled via zshrc variables, (c) lib features that reshape the interactive shell (directory stack aliases, history behavior, key bindings, completion tuning, clipboard helpers, terminal title/OSC7 integration, git prompt API), and (d) lifecycle tooling (install, upgrade, changelog, uninstall, diagnostics).
- `omz plugin enable|disable|info|list|load` manage the plugins array: enable/disable rewrite .zshrc with an awk program, back up to .zshrc.bck, syntax-check the result with `zsh -n`, and reload the shell; load sources a plugin for the current session only. — [lib/cli.zsh#L228-322](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L228-L322) [lib/cli.zsh#L324-416](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L324-L416) [lib/cli.zsh#L493-539](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L493-L539)
- `omz theme list|set|use` enumerate and switch themes; `set` rewrites the ZSH_THEME= line in .zshrc (or prepends one) with the same backup + `zsh -n` + rollback discipline as the plugin commands. — [lib/cli.zsh#L748-797](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L748-L797) [lib/cli.zsh#L799-886](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L799-L886)
- `omz update` shells out to `zsh -f $ZSH/tools/upgrade.sh -i -v <mode> -c <days>`, writes LAST_EPOCH into $ZSH_CACHE_DIR/.zsh-update, removes the update lock, and execs a fresh zsh if HEAD changed. — [lib/cli.zsh#L888-931](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L888-L931)
- `omz pr test <N|URL>` fetches a pull request into branch ohmyzsh/pull-N, first querying api.github.com for the 'testers needed' label (node_id MDU6TGFiZWw4NzY1NTkwNA==) and requiring a typed 'yes' if the PR is unlabeled, then rebases onto master and spawns `zsh -l` for testing. — [lib/cli.zsh#L591-724](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L591-L724)
- `omz changelog` delegates to tools/changelog.sh, a Conventional-Commits parser that buckets subjects by type (feat/fix/perf/docs main; refactor/style/other grouped; chore/ci/etc ignored) and renders them per release. — [lib/cli.zsh#L185-203](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L185-L203) [tools/changelog.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/changelog.sh) [CONTRIBUTING.md#L172-241](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/CONTRIBUTING.md#L172-L241)
- The git plugin (plugins/git/git.plugin.zsh) ships ~200 aliases plus functions like git_main_branch (probing main/trunk/mainline/default/stable/master then remote HEAD), git_develop_branch, and gbcopy (branch name to clipboard via clipcopy). — [plugins/git/git.plugin.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/git/git.plugin.zsh) [plugins/git/README.md](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/git/README.md)
- ZSH_THEME='random' is implemented as a real theme file themes/random.zsh-theme: it gathers candidates from ZSH_THEME_RANDOM_CANDIDATES or the theme dirs minus ZSH_THEME_RANDOM_IGNORED, picks one with $RANDOM, sources it, and records it in $RANDOM_THEME. — [themes/random.zsh-theme](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/themes/random.zsh-theme) [templates/zshrc.zsh-template#L7-17](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/zshrc.zsh-template#L7-L17)
- lib/directories.zsh enables auto_cd/auto_pushd and defines the `...`=`../..` global aliases, numeric `1..9`=`cd -N` aliases, `d` for the dir stack, and ls listing aliases (l, ll, la, lsa). — [lib/directories.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/directories.zsh)
- lib/history.zsh replaces `history` with omz_history (supports -c clear with confirmation and HIST_STAMPS-driven date formats), sets HISTFILE=~/.zsh_history, floors HISTSIZE=50000/SAVEHIST=10000, and enables share_history/hist_verify. — [lib/history.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/history.zsh)
- lib/completion.zsh configures the completer: matcher-list driven by CASE_SENSITIVE/HYPHEN_INSENSITIVE, menu select, use-cache into $ZSH_CACHE_DIR, ignored system users, COMPLETION_WAITING_DOTS spinner widget, and bashcompinit for bash completions. — [lib/completion.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/completion.zsh)
- lib/termsupport.zsh auto-sets terminal/tab titles via title() on precmd/preexec (special-casing `fg` job resolution and sudo/ssh prefixes) and emits OSC 7 file://host/path cwd notifications via omz_termsupport_cwd, skipped under Emacs/SSH. — [lib/termsupport.zsh#L9-116](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/termsupport.zsh#L9-L116) [lib/termsupport.zsh#L131-170](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/termsupport.zsh#L131-L170)
- lib/clipboard.zsh defines clipcopy/clippaste dispatching across pbcopy, cygwin, wl-copy, xsel, xclip, lemonade, doitclient, win32yank, and tmux depending on platform and WAYLAND_DISPLAY/DISPLAY/TMUX. — [lib/clipboard.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/clipboard.zsh)
- lib/functions.zsh provides grab-bag utilities: take/mkcd/takedir (mkdir+cd), takeurl/takezip/takegit (download/extract+cd), open_command (cross-platform opener honoring $BROWSER), omz_urlencode/omz_urldecode, zsh_stats, and uninstall_oh_my_zsh. — [lib/functions.zsh#L1-88](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/functions.zsh#L1-L88) [lib/functions.zsh#L176-284](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/functions.zsh#L176-L284)
- lib/diagnostics.zsh ships omz_diagnostic_dump, a defensive (builtin/command-prefixed) troubleshooting-report generator with -v/-V verbosity levels that cats config state into a single postable file. — [lib/diagnostics.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/diagnostics.zsh)
- plugins/themes/themes.plugin.zsh adds an interactive `theme` command (default random) plus `lstheme` listing, and tools/theme_chooser.sh previews every theme interactively after sourcing oh-my-zsh.sh. — [plugins/themes/themes.plugin.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/themes/themes.plugin.zsh) [tools/theme_chooser.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/theme_chooser.sh)

## Data flow

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. — [templates/zshrc.zsh-template#L5-78](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/zshrc.zsh-template#L5-L78) [tools/install.sh#L405-413](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L405-L413)
- 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. — [oh-my-zsh.sh#L81-98](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L81-L98) [oh-my-zsh.sh#L206-211](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L206-L211) [oh-my-zsh.sh#L235-239](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L235-L239)
- 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. — [oh-my-zsh.sh#L66-68](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L66-L68) [oh-my-zsh.sh#L146-185](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L146-L185)
- 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. — [tools/check_for_upgrade.sh#L136-149](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L136-L149) [tools/check_for_upgrade.sh#L209-235](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L209-L235)
- 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. — [tools/check_for_upgrade.sh#L62-134](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L62-L134)
- 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. — [lib/git.zsh#L14-50](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L14-L50) [lib/git.zsh#L52-70](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L52-L70) [lib/git.zsh#L72-169](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L72-L169)
- 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. — [lib/async_prompt.zsh#L46-142](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/async_prompt.zsh#L46-L142)
- .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. — [lib/cli.zsh#L249-322](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L249-L322) [lib/cli.zsh#L814-863](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L814-L863)
- 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). — [lib/grep.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/grep.zsh) [oh-my-zsh.sh#L101-127](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L101-L127) [lib/theme-and-appearance.zsh#L16-38](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/theme-and-appearance.zsh#L16-L38)
- 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. — [tools/upgrade.sh#L205-243](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L205-L243) [tools/upgrade.sh#L268-341](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L268-L341)
- 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. — [lib/termsupport.zsh#L19-45](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/termsupport.zsh#L19-L45) [lib/termsupport.zsh#L130-170](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/termsupport.zsh#L130-L170) [lib/functions.zsh#L176-238](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/functions.zsh#L176-L238)
- 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. — [tools/install.sh#L18-40](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L18-L40) [tools/install.sh#L354-416](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L354-L416) [tools/uninstall.sh#L1-38](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/uninstall.sh#L1-L38)

## Behavior traces

Three flows matter most. Startup: .zshrc -> oh-my-zsh.sh guards -> env defaults -> check_for_upgrade -> fpath/compinit -> lib -> plugins -> custom -> theme. Update: startup hook -> epoch/frequency gates -> GitHub API compare -> upgrade.sh git rebase -> epoch write -> optional exec. Config mutation: omz subcommand -> awk rewrite of .zshrc -> zsh -n validation -> rollback or reload. Install is a fourth boundary: curl|sh -> git init/fetch -> .zshrc template -> chsh -> exec zsh.
- Startup sequence in order: ZSH_VERSION guard with omz_ptree diagnostics -> `emulate` mode check -> ZSH/ZSH_CUSTOM/ZSH_CACHE_DIR defaults -> mkdir cache/completions + fpath -> source tools/check_for_upgrade.sh -> plugin dirs into fpath -> SHORT_HOST -> compinit/zcompdump -> _omz_source each lib/*.zsh -> each plugin -> each $ZSH_CUSTOM/*.zsh -> theme -> LS_COLORS zstyle. — [oh-my-zsh.sh#L10-267](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L10-L267)
- Auto-update trace: check_for_upgrade.sh resolves zstyle ':omz:update' mode (legacy DISABLE_UPDATE_PROMPT/DISABLE_AUTO_UPDATE mapped to auto/disabled) -> bails on disabled/unwritable/non-tty -> sources .zsh-update and returns early inside the frequency window (default 13 days) -> handle_update takes update.lock -> is_update_available -> prompt ('Would you like to update? [Y/n]') or silent modes -> update_ohmyzsh runs upgrade.sh. — [tools/check_for_upgrade.sh#L14-55](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L14-L55) [tools/check_for_upgrade.sh#L203-289](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L203-L289)
- background-alpha update mode registers _omz_bg_update on precmd which forks handle_update and installs _omz_bg_update_status to report EXIT_STATUS/ERROR from .zsh-update on a later prompt. — [tools/check_for_upgrade.sh#L291-341](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L291-L341)
- upgrade.sh execution order: re-exec under zsh if needed -> cd $ZSH -> parse -v/-i/-c flags -> rewrite legacy robbyrussell remotes -> set core.eol/autocrlf/fsck/rebase.autoStash git config -> checkout update branch -> git pull --rebase (or cooldown path: fetch + find first FETCH_HEAD commit older than cooldown days + merge --ff-only) -> run changelog.sh if interactive -> restore previous HEAD and autoStash. — [tools/upgrade.sh#L7-49](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L7-L49) [tools/upgrade.sh#L205-341](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L205-L341)
- Insecure-completion handling: unless ZSH_DISABLE_COMPFIX=true, compfix.zsh is sourced, compinit runs with -i to skip insecure dirs, and handle_completion_insecurities lists `compaudit` output with a chmod g-w,o-w fix hint. — [oh-my-zsh.sh#L153-164](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L153-L164) [lib/compfix.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/compfix.zsh)
- `omz plugin disable git` trace: omz -> _omz::plugin -> _omz::plugin::disable validates names against $plugins -> builds gsub() awk program -> awk .zshrc > .zshrc.new -> cp .zshrc .zshrc.bck -> mv .zshrc.new .zshrc -> `zsh -n` check -> rollback mv on syntax error -> _omz::reload execs ${ZSH_ARGZERO:-zsh} (with -l for login shells). — [lib/cli.zsh#L228-322](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L228-L322) [lib/cli.zsh#L735-746](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L735-L746)
- Git prompt render trace (async default on zsh >= 5.0.6): precmd -> _defer_async_git_register checks whether $(git_prompt_info)/$(git_prompt_status) appear in PS1/RPROMPT/etc -> _omz_register_handler -> _omz_async_request forks _omz_git_prompt_info -> _omz_async_callback fills _OMZ_ASYNC_OUTPUT -> zle reset-prompt -> git_prompt_info stub echoes the cached output. — [lib/git.zsh#L171-236](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L171-L236) [lib/async_prompt.zsh#L46-142](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/async_prompt.zsh#L46-L142)
- Install trace: main() detects non-tty stdin -> forces RUNZSH=no CHSH=no OVERWRITE_CONFIRMATION=no -> setup_ohmyzsh (umask g-w,o-w; git init; core.eol=lf, autocrlf=false, zeroPaddedFilemode ignores; fetch --depth=1; checkout $BRANCH) -> setup_zshrc (backup, sed template) -> setup_shell (locate zsh in /etc/shells, save old shell, sudo chsh) -> print_success -> exec zsh -l. — [tools/install.sh#L538-604](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L538-L604)
- `omz pr test 123` trace: URL basename normalized -> digit check -> git symbolic-ref saves current branch -> remote list scanned for ohmyzsh/ohmyzsh -> curl api.github.com/repos/ohmyzsh/ohmyzsh/pulls/123 -> 'testers needed' label check (jq or grep on node_id) -> typed 'yes' gate if unlabeled -> git fetch refs/pull/123/head:ohmyzsh/pull-123 -> rebase onto master with commit.gpgsign temporarily disabled -> `zsh -l` test shell -> optional checkout back. — [lib/cli.zsh#L591-724](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L591-L724)
- Uninstall trace: uninstall_oh_my_zsh -> tools/uninstall.sh restores shell from ~/.shell.pre-oh-my-zsh via chsh, confirms, rm -rf ~/.oh-my-zsh, renames ~/.zshrc to .zshrc.omz-uninstalled-<timestamp>, and restores .zshrc.pre-oh-my-zsh. — [lib/functions.zsh#L7-9](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/functions.zsh#L7-L9) [tools/uninstall.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/uninstall.sh)

## Testing signals

Testing is thin for a project of this reach. CI (main.yml) does only `zsh -n` syntax checking over the entrypoint, lib files, plugin entrypoints/completions, and themes — no behavioral test runs. Real tests exist but are scattered and not wired into workflows: lib/tests/cli.test.zsh exercises the plugin-disable awk script, and a few plugins (alias-finder, dotenv) ship zunit suites. The installer gets its own matrix test on ubuntu+macos, and all workflows run step-security/harden-runner in audit mode.
- main.yml's only test step is a `zsh -n` syntax sweep over ./oh-my-zsh.sh, lib/*.zsh, plugins/*/*.plugin.zsh, plugins/*/_*, and themes/*.zsh-theme on ubuntu-latest; the job is gated on github.repository == 'ohmyzsh/ohmyzsh'. — [.github/workflows/main.yml#L20-43](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/main.yml#L20-L43)
- lib/tests/cli.test.zsh duplicates the plugin-disable awk program inline and tests it against oneline/multiline/mixed plugins=(...) formats, asserting both `zsh -n` validity and exact diff output via run_awk_and_test. — [lib/tests/cli.test.zsh#L1-169](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/tests/cli.test.zsh#L1-L169)
- The awk script tested by lib/tests/cli.test.zsh is a copy of the one embedded in _omz::plugin::disable in lib/cli.zsh, so the test validates a clone of the logic rather than the shipped code path. (inferred) — [lib/tests/cli.test.zsh#L9-55](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/tests/cli.test.zsh#L9-L55) [lib/cli.zsh#L250-295](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L250-L295)
- Plugin-level tests exist in zunit format: plugins/alias-finder/tests/test_run.sh (@setup/@test/@assert blocks) and plugins/dotenv/tests/{basic-parsing,compatibility,security}.zunit. — [plugins/alias-finder/tests/test_run.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/alias-finder/tests/test_run.sh) [plugins/dotenv/tests/security.zunit](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/dotenv/tests/security.zunit)
- Neither the zunit suites nor cli.test.zsh are invoked by any workflow; grep of .github/workflows shows only the syntax-check job and the installer test, so these tests run only when a developer runs them manually. (inferred) — [.github/workflows/main.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/main.yml) [.github/workflows/installer.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/installer.yml)
- installer.yml runs `sh ./tools/install.sh` on ubuntu-latest and macos-latest on pushes touching tools/install.sh, then deploys install.sh to Vercel (install.ohmyz.sh) on master via `vc deploy --prod` with VERCEL_* secrets. — [.github/workflows/installer.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/installer.yml)
- Every workflow pins actions by SHA and prepends step-security/harden-runner with egress-policy: audit; permissions are minimal (contents: read) except dependencies.yml which grants contents: write for pushing update branches. — [.github/workflows/main.yml#L26-29](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/main.yml#L26-L29) [.github/workflows/dependencies.yml#L16-24](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies.yml#L16-L24) [.github/workflows/scorecard.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/scorecard.yml)
- scorecard.yml runs OpenSSF Scorecard analysis weekly and on master pushes, uploading results to the code-scanning dashboard (security-events: write). — [.github/workflows/scorecard.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/scorecard.yml)
- dependencies.yml runs updater.py weekly: it reads .github/dependencies.yml entries (upstream repo/branch/pinned version + precopy/postcopy shell), fetches upstream releases, and opens/commits vendored-plugin updates authenticated as the ohmyzsh[bot] GitHub App. — [.github/workflows/dependencies/updater.py](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies/updater.py) [.github/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/dependencies.yml) [.github/workflows/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies.yml)
- project.yml uses pull_request_target with an empty default permission set plus a GitHub App token to add new issues/PRs to the ohmyzsh org Project board and set Plugin/Theme fields. — [.github/workflows/project.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/project.yml)
- CONTRIBUTING.md mandates Conventional Commits (type(scope)!: subject) because tools/changelog.sh generates the user-facing changelog from commit subjects — so commit-message discipline is itself part of the test/release pipeline. — [CONTRIBUTING.md#L172-241](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/CONTRIBUTING.md#L172-L241) [tools/changelog.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/changelog.sh)
- No test covers oh-my-zsh.sh init order, compfix/compinit handling, upgrade.sh, check_for_upgrade.sh, or lib/git.zsh prompt parsing — the riskiest shell logic is verified only by the syntax sweep. (inferred) — [.github/workflows/main.yml#L35-43](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/main.yml#L35-L43)

## Risk map

The dominant risks are supply-chain and self-modification: every user runs curl|sh installer code and an auto-updater that git-pulls new shell code into a live config; `omz` commands rewrite the user's .zshrc with awk; and 368 community plugins execute unchecked code at every shell start. Mitigations exist (compfix permission checks, PR-test label gating, .zshrc backups + syntax validation, hardened CI), but coverage of the critical paths is minimal.
- The documented install path is `sh -c "$(curl -fsSL .../tools/install.sh)"` — remote code executed with user privileges; the script then chsh's the login shell (via sudo when available) and execs zsh. — [tools/install.sh#L1-8](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L1-L8) [tools/install.sh#L497-504](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L497-L504) [tools/install.sh#L601](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L601)
- install.sh resolves $HOME via `eval echo ~"$USER"` when HOME is unset — an acknowledged CWE-78-adjacent path that is only safe because $USER is first restricted to [alnum, _, ., -]. — [tools/install.sh#L52-76](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L52-L76)
- Auto-update executes freshly fetched code: upgrade.sh does `git pull --rebase` on master and the new oh-my-zsh.sh/plugins run at next shell start; the 'cooldown' zstyle exists specifically to delay applying new commits as a supply-chain buffer. — [tools/upgrade.sh#L259-265](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L259-L265) [tools/check_for_upgrade.sh#L74-88](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L74-L88) [README.md#L477-491](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/README.md#L477-L491)
- Every plugin file is arbitrary code sourced into every interactive shell; the only vetting is maintainer review, and `omz pr test` explicitly warns unlabeled PRs 'may contain malicious code' before fetching and running them. — [oh-my-zsh.sh#L235-239](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L235-L239) [lib/cli.zsh#L652-666](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L652-L666)
- omz plugin/theme commands write directly into ${ZDOTDIR:-$HOME}/.zshrc via awk transformations; mitigations are the .zshrc.bck backup and the post-write `zsh -n` syntax check with automatic rollback, but a semantically-wrong-but-parseable edit would stick. — [lib/cli.zsh#L297-315](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L297-L315) [lib/cli.zsh#L832-856](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L832-L856)
- compinit -i skips completion dirs that fail compaudit ownership/permission checks; users hitting this get a warning via handle_completion_insecurities — ZSH_DISABLE_COMPFIX=true bypasses the check entirely by switching to compinit -u. — [oh-my-zsh.sh#L153-164](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L153-L164) [lib/compfix.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/compfix.zsh)
- check_for_upgrade.sh's GitHub API call uses a 2s connect timeout and treats non-GitHub remotes as always-updateable; is_update_available returning 0 on merge-base failure assumes updates exist — fail-open rather than fail-closed. — [tools/check_for_upgrade.sh#L90-134](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L90-L134)
- uninstall.sh runs `rm -rf ~/.oh-my-zsh` and `chsh` after a single y/N prompt, and install.sh's setup_shell runs `sudo chsh` — destructive/account-level operations driven by tty prompts that are bypassed only in unattended mode. — [tools/uninstall.sh#L13-28](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/uninstall.sh#L13-L28) [tools/install.sh#L497-512](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L497-L512)
- update.lock is a stale-able mkdir lock under $ZSH/log: the code deletes locks older than a day, and the EXIT/INT/QUIT trap must return $ret correctly so Ctrl+C actually interrupts — a fragile bit of signal semantics the comments call out. — [tools/check_for_upgrade.sh#L209-235](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L209-L235)
- Async prompt handler cancellation kills the process group only under MONITOR; without job control it can only TERM the direct child, and the file itself notes forked grandchildren 'may be orphaned and left behind'. — [lib/async_prompt.zsh#L60-77](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/async_prompt.zsh#L60-L77)
- lib/vcs_info.zsh exists specifically to %-quote hook_com fields before vcs_info hooks run — a workaround for CVE-2021-45444 where crafted branch/repo data could trigger command substitution in prompts on zsh 5.0.3-5.8. — [lib/vcs_info.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/vcs_info.zsh)
- git.zsh documents real-world fragility: a =~ regex on non-UTF-8 git output aborted with REG_ILLSEQ (fixed via LC_ALL=C scoping), and async prompt is behind ':omz:alpha:lib:git' with 'force'/opt-out because of known issue reports; the CentOS-7 workaround carries a dated TODO. — [lib/git.zsh#L52-70](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L52-L70) [lib/git.zsh#L171-236](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L171-L236)
- SECURITY.md states only the latest master commit is supported and relies on 'automated updates to minimize the time between vulnerability publication and patch release' — there is no stable/release line to pin. — [SECURITY.md](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/SECURITY.md)
- The dependencies updater executes precopy/postcopy shell snippets declared in .github/dependencies.yml inside CI with a write-capable token — a code-execution path driven by YAML data. — [.github/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/dependencies.yml) [.github/workflows/dependencies/updater.py](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies/updater.py) [.github/workflows/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies.yml)

## Extension points

Oh My Zsh is built to be extended without editing upstream files: $ZSH_CUSTOM shadows every lib file, plugin, and theme; new plugins are just directories with a <name>.plugin.zsh or _<name> completion; new themes are *.zsh-theme files; behavior is tuned via zstyle contexts and env-var flags; and the `omz` CLI dispatches to _omz::<cmd> functions. Theme authors integrate through prompt-info functions and ZSH_THEME_* variables.
- $ZSH_CUSTOM is the primary extension root: files in $ZSH_CUSTOM/*.zsh load last (after lib and plugins), and $ZSH_CUSTOM/<path> shadows $ZSH/<path> inside _omz_source, letting users override any lib file or plugin without touching the repo. — [oh-my-zsh.sh#L206-211](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L206-L211) [oh-my-zsh.sh#L241-245](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L241-L245) [custom/example.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/custom/example.zsh) [README.md#L349-358](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/README.md#L349-L358)
- A plugin is any directory under plugins/ or $ZSH_CUSTOM/plugins/ containing <name>.plugin.zsh (sourced at load) or _<name> (a compinit completion); is_plugin() is the registry check and simply enabling the name in plugins=(...) wires it in. — [oh-my-zsh.sh#L81-98](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L81-L98)
- A theme is a *.zsh-theme file found in $ZSH_CUSTOM/, $ZSH_CUSTOM/themes/, or $ZSH/themes/ (search order); it typically sets PROMPT/RPROMPT and consumes ZSH_THEME_* styling variables plus *_prompt_info functions. — [oh-my-zsh.sh#L248-264](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L248-L264) [lib/theme-and-appearance.zsh#L8-13](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/theme-and-appearance.zsh#L8-L13)
- zstyle contexts form a typed config API: ':omz:update' mode/frequency/cooldown/verbose, ':omz:lib:theme-and-appearance' gnu-ls, ':omz:alpha:lib:git' async-prompt, and ':omz:lib:<n>'/':omz:plugins:<n>' aliases toggles. — [tools/check_for_upgrade.sh#L14-20](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L14-L20) [lib/theme-and-appearance.zsh#L89-91](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/theme-and-appearance.zsh#L89-L91) [lib/git.zsh#L177-214](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L177-L214) [oh-my-zsh.sh#L191-197](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L191-L197)
- Env-var feature flags read at startup include DISABLE_MAGIC_FUNCTIONS, DISABLE_LS_COLORS, DISABLE_AUTO_TITLE, ENABLE_CORRECTION, CASE_SENSITIVE, HYPHEN_INSENSITIVE, COMPLETION_WAITING_DOTS, DISABLE_UNTRACKED_FILES_DIRTY, HIST_STAMPS, ZSH_DISABLE_COMPFIX — all documented in the zshrc template. — [templates/zshrc.zsh-template#L19-66](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/zshrc.zsh-template#L19-L66) [lib/misc.zsh#L4-16](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/misc.zsh#L4-L16) [lib/correction.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/correction.zsh) [oh-my-zsh.sh#L153](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L153)
- Theme-facing integration contract: themes call git_prompt_info/git_prompt_status/ruby_prompt_info/nvm_prompt_info etc.; lib/prompt_info_functions.zsh predefines no-op stubs (chruby, rbenv, hg, pyenv, svn, vi_mode, virtualenv, jenv, azure, tf, conda, go) so themes don't error when plugins are absent. — [lib/prompt_info_functions.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/prompt_info_functions.zsh) [lib/git.zsh#L179-236](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L179-L236) [lib/nvm.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/nvm.zsh)
- Prompt-status symbols are themselves a plugin/theme API: ZSH_THEME_GIT_PROMPT_{PREFIX,SUFFIX,DIRTY,CLEAN,UNTRACKED,ADDED,MODIFIED,RENAMED,DELETED,UNMERGED,AHEAD,BEHIND,DIVERGED,STASHED} map parsed statuses to glyphs. — [lib/git.zsh#L77-116](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L77-L116) [lib/theme-and-appearance.zsh#L8-13](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/theme-and-appearance.zsh#L8-L13)
- Async prompt extension: any function can be registered with _omz_register_handler and its output surfaced via $_OMZ_ASYNC_OUTPUT[handler] inside a stub prompt function — documented in the file header as the intended (but unstable) API. — [lib/async_prompt.zsh#L8-43](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/async_prompt.zsh#L8-L43)
- The `omz` CLI is open for new subcommands: `omz foo` dispatches to _omz::foo if the function exists, and the _omz completer's cmds/subcmds arrays are the registry to extend; plugin/theme/pr use $0::subcommand namespacing. — [lib/cli.zsh#L3-21](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L3-L21) [lib/cli.zsh#L25-35](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L25-L35) [lib/cli.zsh#L205-226](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L205-L226)
- Random-theme selection is extensible via ZSH_THEME_RANDOM_CANDIDATES and ZSH_THEME_RANDOM_IGNORED arrays; the themes plugin additionally provides `theme`/`lstheme` for ad-hoc switching. — [themes/random.zsh-theme](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/themes/random.zsh-theme) [plugins/themes/themes.plugin.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/plugins/themes/themes.plugin.zsh)
- Vendored upstream completions are an extension surface managed declaratively: adding an entry to .github/dependencies.yml (repo, branch, version, pre/postcopy hooks) lets the weekly updater pull new upstream completion sources into plugins/. — [.github/dependencies.yml](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/dependencies.yml) [.github/workflows/dependencies/updater.py](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/dependencies/updater.py)
- add-zsh-hook (precmd/preexec) is the sanctioned way libs hook the prompt lifecycle — termsupport registers omz_termsupport_precmd/preexec/cwd, async_prompt registers _omz_async_request, and git.zsh prepends _defer_async_git_register to precmd_functions. — [lib/termsupport.zsh#L111-116](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/termsupport.zsh#L111-L116) [lib/async_prompt.zsh#L144-145](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/async_prompt.zsh#L144-L145) [lib/git.zsh#L207-213](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L207-L213)
- Plugin README convention: `omz plugin info <name>` looks for $ZSH_CUSTOM/plugins/<name>/README.md then $ZSH/plugins/<name>/README.md and pages it through glow/bat/less — each plugin is expected to ship a README documenting its aliases. — [lib/cli.zsh#L418-454](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L418-L454) [README.md#L167-170](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/README.md#L167-L170)

## Contributor handoff

This is a pure-shell repo: no build step, no package manifest, no unit-test harness wired to CI. The safe edit boundary is 'add or modify files, don't reorder init'. Read oh-my-zsh.sh first (it defines load order and the _omz_source override contract), then the specific lib/ or plugins/ file. Validate changes with `zsh -n` on every touched file — that is literally all CI runs. Mind zsh-only syntax (emulate modes, zstyle, zparseopts, associative arrays), POSIX-sh vs zsh script split (install.sh is sh; upgrade.sh/tools are zsh), and that many variables/hooks are user-facing API you cannot rename.
- Read order for any task: oh-my-zsh.sh (init order, _omz_source, compinit handling) -> templates/zshrc.zsh-template (the user-facing config contract) -> the target lib/*.zsh or plugins/<n>/<n>.plugin.zsh -> CONTRIBUTING.md commit conventions. — [oh-my-zsh.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh) [templates/zshrc.zsh-template](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/zshrc.zsh-template) [CONTRIBUTING.md#L172-241](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/CONTRIBUTING.md#L172-L241)
- Never reorder the load sequence in oh-my-zsh.sh: plugin fpath entries must precede compinit, lib files precede plugins, $ZSH_CUSTOM/*.zsh loads last, and the theme loads after everything so it can use lib-defined functions. — [oh-my-zsh.sh#L88-98](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L88-L98) [oh-my-zsh.sh#L228-264](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L228-L264)
- tools/install.sh is POSIX sh (#!/bin/sh, run via curl|sh) while tools/upgrade.sh, tools/check_for_upgrade.sh, and tools/changelog.sh are zsh scripts — do not use zsh-isms in install.sh or assume sh semantics in the tools. — [tools/install.sh#L1](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L1) [tools/upgrade.sh#L1-14](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/upgrade.sh#L1-L14) [tools/changelog.sh#L1-3](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/changelog.sh#L1-L3)
- The only CI gate is `zsh -n` over oh-my-zsh.sh, lib/*.zsh, plugins/*/*.plugin.zsh, plugins/*/_*, and themes/*.zsh-theme — replicate it locally before submitting; there is no formatter config for shell (only .prettierrc for docs at 110 cols). — [.github/workflows/main.yml#L35-43](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.github/workflows/main.yml#L35-L43) [.prettierrc](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.prettierrc)
- Public API you must not break: plugin/theme/env-var names (ZSH_THEME, plugins, ZSH_CUSTOM, ZSH_CACHE_DIR, DISABLE_*, HIST_STAMPS), zstyle contexts ':omz:...', prompt functions (git_prompt_info, parse_git_dirty, *_prompt_info stubs), and aliases — all are consumed by user dotfiles and external themes/plugins. — [templates/zshrc.zsh-template](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/zshrc.zsh-template) [lib/prompt_info_functions.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/prompt_info_functions.zsh) [lib/git.zsh#L230-236](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L230-L236)
- When writing shell that runs at startup, avoid forks and subshells; the codebase caches probes in $ZSH_CACHE_DIR (grep-alias, localhostname, appearance-probes) precisely to avoid per-start process spawns — follow that pattern for new probes. — [lib/grep.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/grep.zsh) [lib/theme-and-appearance.zsh#L16-38](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/theme-and-appearance.zsh#L16-L38) [oh-my-zsh.sh#L101-127](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L101-L127)
- Quote % in anything that reaches the prompt: git.zsh escapes % to %% in branch names and upstreams, vcs_info.zsh exists because unquoted hook_com fields enabled command substitution (CVE-2021-45444), and _omz::log sets nopromptsubst for the same reason. — [lib/git.zsh#L49](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L49) [lib/vcs_info.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/vcs_info.zsh) [lib/cli.zsh#L137-141](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L137-L141)
- Use `command`/`builtin` prefixes for external calls in lib code (diagnostics.zsh documents why: users redefine echo/which), and route git prompt calls through __git_prompt_git so GIT_OPTIONAL_LOCKS=0 is set. — [lib/diagnostics.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/diagnostics.zsh) [lib/git.zsh#L3-12](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L3-L12)
- ZDOTDIR is a first-class citizen: all .zshrc-mutating code resolves ${ZDOTDIR:-$HOME}, and the installer picks $ZDOTDIR/ohmyzsh as $ZSH when ZDOTDIR is set and != HOME — replicate this resolution rather than hardcoding ~/.zshrc. — [lib/cli.zsh#L297-299](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L297-L299) [tools/install.sh#L82-92](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/install.sh#L82-L92)
- Trap: editing the plugin-enable/disable awk logic means updating two copies — lib/cli.zsh and the duplicated copy inside lib/tests/cli.test.zsh. — [lib/cli.zsh#L250-295](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/cli.zsh#L250-L295) [lib/tests/cli.test.zsh#L9-55](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/tests/cli.test.zsh#L9-L55)
- The devcontainer (.devcontainer/devcontainer.json) symlinks the workspace to ~/.oh-my-zsh and installs templates/minimal.zshrc as ~/.zshrc — the fastest way to smoke-test a change is a new container or `zsh -f` with a minimal zshrc sourcing the repo. — [.devcontainer/devcontainer.json](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/.devcontainer/devcontainer.json) [templates/minimal.zshrc](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/templates/minimal.zshrc)
- New aliases face an explicit bar in CONTRIBUTING.md (used by many, common tasks, prefer generic over specific, don't shadow existing commands), and new themes are currently not accepted at all — check these policies before generating either. — [CONTRIBUTING.md#L93-127](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/CONTRIBUTING.md#L93-L127) [README.md#L65-66](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/README.md#L65-L66)
- Known fragile spots to test manually: compfix/compinit interaction (ZSH_DISABLE_COMPFIX), async prompt registration ordering (_defer_async_git_register must run before _omz_async_request), and the update.lock EXIT trap's $ret propagation for SIGINT. — [oh-my-zsh.sh#L153-164](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/oh-my-zsh.sh#L153-L164) [lib/git.zsh#L193-213](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/lib/git.zsh#L193-L213) [tools/check_for_upgrade.sh#L223-235](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/check_for_upgrade.sh#L223-L235)
- Commit messages must follow Conventional Commits with scope = plugin/theme name (e.g. feat(git):, fix(agnoster):) because tools/changelog.sh parses subjects into the user-facing changelog; '!' marks breaking changes. — [CONTRIBUTING.md#L172-219](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/CONTRIBUTING.md#L172-L219) [tools/changelog.sh](https://github.com/ohmyzsh/ohmyzsh/blob/86ef6555e068663736a33376e4055aca9c1acc89/tools/changelog.sh)

Source repository: https://github.com/ohmyzsh/ohmyzsh
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/ohmyzsh.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
