Skip to content
JtheGunnerPublic

About

A cross-platform shell initialization engine designed to provide a unified interactive terminal experience across macOS and Linux, supporting both Bash and Zsh.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🐚 omnishell

Modular, declarative, reversible terminal configuration for macOS and Linux. One config.toml lists the modules you want; omnishell apply installs, renders and wires them into a single tool-managed init file.

πŸ“ config.toml Β β†’Β  βš™οΈ omnishell apply Β β†’Β  🐚 init.zsh Β· init.bash

License Go Platforms Shells Dependencies


🎯 What it is

omnishell is a single static binary that applies terminal configuration on macOS and Linux in a modular, declarative, reversible way. You keep a plain local file β€” config.toml β€” that lists which modules are enabled and their options. Running omnishell apply then:

  1. installs any programs a module needs (via the detected system package manager β€” brew, apt, dnf, pacman, zypper, apk β€” with a git clone fallback, pinned to a release tag, when the manager has no package for the module or its repositories cannot provide it),
  2. renders each module's shell snippet,
  3. writes everything into a single tool-managed init file per shell (init.zsh / init.bash), sourced from your ~/.zshrc / ~/.bashrc via one marker block,
  4. records the result in a lockfile for idempotency, drift detection and clean removal.

Note

Your own .zshrc / .bashrc is never rewritten beyond that one marker block, every write is backed up first, and running apply twice with no config change is a no-op. No git repo, no account, and no network are required for normal use.


πŸ“¦ Install

Homebrew:

brew install jthegunner/tap/omnishell

Curl (servers without Homebrew β€” downloads the matching binary):

curl -fsSL https://raw.githubusercontent.com/JtheGunner/omnishell/main/install.sh | sh

The installer resolves the latest release through the github.com redirect, so it does not use the rate-limited GitHub API. To install a specific release, set OMNISHELL_VERSION (for example OMNISHELL_VERSION=v0.5.0).

Go:

go install github.com/JtheGunner/omnishell/cmd/omnishell@latest

πŸ–₯️ Supported platforms

OS Architecture uname -m Release archive
🍎 macOS x86_64, arm64 x86_64, arm64 omnishell_darwin_amd64, omnishell_darwin_arm64
🐧 Linux x86_64 x86_64 omnishell_linux_amd64
🐧 Linux arm64 aarch64 omnishell_linux_arm64
🐧 Linux armv7 (also a 32-bit userland on a 64-bit CPU) armv7l, armv8l omnishell_linux_armv7
🐧 Linux armv6 (Raspberry Pi 1 / Zero) armv6l omnishell_linux_armv6

On 32-bit ARM, starship installs a release binary on armv6 and armv7 and mise on armv7. broot has no 32-bit ARM binary, so it builds from source there (needs Rust).


πŸš€ Quick start

omnishell init                 # create the config, hook it into your shells
omnishell enable fzf           # or edit ~/.config/omnishell/config.toml by hand
omnishell apply                # install packages + write the init files
exec $SHELL                    # open a new shell to pick up the changes

omnishell init creates ~/.config/omnishell/config.toml with everything disabled and inserts the source marker block into the detected shells' rc files. enable / disable / set only edit config.toml β€” nothing touches your system until you run omnishell apply.


πŸŽ›οΈ Commands

-h / --help works on every command.

Command Purpose Flags
omnishell init Create the omnishell config and hook it into your shells. Idempotent. β€”
omnishell list List known modules and their status (enabled/disabled, packages, platforms, shells, source, description). --json (emit a JSON array instead of the table; also includes each module's homepage)
omnishell tui Browse and toggle modules in a full-screen terminal UI: a module list with description, homepage, package status, platforms and shells, a / filter, and Space to enable or disable the selected module (written to config.toml at once, like enable / disable). o edits the module's options (bool, enum, string and int; each change is written at once and validated like omnishell set). a previews the plan; confirming it closes the UI and runs omnishell apply, which still asks before it changes anything. Modules that cannot run on this host are dimmed with the reason; a module that only lacks OS support can still be enabled, but apply skips it. Needs an interactive terminal (exit 2 otherwise). β€”
omnishell enable <module> Enable a module in the config. Does not apply. β€”
omnishell disable <module> Disable a module in the config. Does not apply. β€”
omnishell set <module>.<key> <value> Set a module option in the config, validated against that module's option schema. β€”
omnishell validate Check config.toml against the module option schemas and dependency rules (requires / conflicts / cycles). Computes no plan and probes nothing on the host; exit 2 on any problem. Useful in CI for a version-controlled config.toml. --json (emit a JSON object instead of the text report)
omnishell apply Bring your shells up to date with the config. --dry-run (show the plan without changing anything), --force (overwrite init files that were edited by hand), --no-packages (skip package installation), -y / --yes (apply without the confirmation prompt), --reload (re-exec $SHELL after a successful apply; no-op in a non-interactive shell)
omnishell diff Show what apply would change (apply --dry-run). β€”
omnishell doctor Check the installed shell environment for drift. Exit 3 if any drift is found. --fix repairs the drift a re-apply resolves (missing / stale init file, missing rc source line, orphaned lockfile entries); a hand-edited init file and missing packages are left for a manual apply / apply --force. --fix (repair re-apply-able drift), -y / --yes (with --fix, skip the prompt)
omnishell bench Measure how much sourcing the generated init.<shell> adds to shell startup, per managed shell, and warn when it exceeds the startup budget. A rough guide (moves with machine load), always exits 0. --json (emit a JSON object), --runs <n> (timed runs per measurement, default 5)
omnishell rollback List backup snapshots, or restore files/lockfile to their state before a chosen one (--to <timestamp>), undoing that run and everything after it. Never touches packages or config.toml. --to <timestamp>, --dry-run, -y / --yes
omnishell remove <id> Disable a module and drop its shell section, then re-apply. --dry-run, --purge (also uninstall the module's packages, run its remove hook, and delete vendored files), -y / --yes
omnishell uninstall Remove omnishell's shell integration (marker block + generated init.<shell> files). Every touched file is backed up first. --purge (also delete ~/.config/omnishell entirely), -y / --yes
omnishell version Print the omnishell version. β€”
omnishell completion Cobra-generated shell autocompletion script generator (distinct from the completion module). β€”

πŸ“– Shell completion & man page for the omnishell command

Not to be confused with the completion module (which configures your shell's completion system) β€” this is tab-completion for typing omnishell itself, plus man omnishell.

  • Homebrew installs the bash/zsh completions and the man pages automatically.
  • install.sh drops them into $XDG_DATA_HOME (~/.local/share) on a best-effort basis β€” bash into bash-completion/completions/, zsh into zsh/site-functions/ (make sure that dir is on your $fpath), man into man/man1/.
  • go install: generate on demand, e.g. omnishell completion zsh > ~/.local/share/zsh/site-functions/_omnishell.

πŸ”§ How it works

The config directory is $XDG_CONFIG_HOME/omnishell, or ~/.config/omnishell when XDG_CONFIG_HOME is unset:

Path What it is
πŸ“ config.toml The file you edit (by hand, or via enable / disable / set). The [omnishell] table also takes startup_budget_ms (default 200) β€” the per-shell added-cost threshold omnishell bench warns above.
🐚 init.zsh / init.bash Tool-generated. Do not edit β€” apply regenerates them and doctor flags manual edits.
πŸ”’ state.lock.json Machine-managed lockfile (idempotency, drift detection, clean removal). Not for editing.
πŸ’Ύ backups/<timestamp>/ Every rc-file and init-file write is copied here first.
🧩 modules/<id>/ Your own modules (same format as the built-ins).
πŸ“₯ vendor/ Clones made by the git package fallback (apply moves them to the tag the manifest pins and rebuilds) and bin/ with release binaries.

Each managed rc file gets exactly one marker block, appended at the end:

# >>> omnishell >>>
[[ -f "$HOME/.config/omnishell/init.zsh" ]] && source "$HOME/.config/omnishell/init.zsh"
# <<< omnishell <<<

The generated init.<shell> file carries a header with a Content hash, then one section per module wrapped in # >>> omnishell:<id> (v<ver>) >>> … # <<< omnishell:<id> <<< markers, in dependency order. It is written atomically (temp file + rename) after the old copy is backed up. Only apply, remove, and uninstall change your system (and init inserts the rc block); everything else just reads or edits config.toml.


🧩 Built-in modules

id Description Packages Shells Options
completion Enable shell completion with case-insensitive matching β€” (config only) zsh, bash β€”
history Larger, de-duplicated, shared shell history and prefix search β€” (config only) zsh, bash size (int, default 50000)
autosuggestions Fish-style grey inline command suggestions from history (zsh) β€” zsh-users/zsh-autosuggestions zsh-autosuggestions; git fallback zsh highlight_style (string, default fg=8)
syntax-highlighting Colour commands green/red as you type depending on validity (zsh) β€” zsh-users/zsh-syntax-highlighting zsh-syntax-highlighting; git fallback zsh β€”
fzf Ctrl+R history search as a fuzzy, scrollable list (+ optional Ctrl+T) β€” junegunn/fzf fzf; git fallback zsh, bash ctrl_r (bool, default true), ctrl_t (bool, default false), default_opts (string, default --height 40% --reverse --border)
zoxide Smarter cd that learns your most-used directories β€” ajeetdsouza/zoxide zoxide; git fallback zsh, bash cmd (string, default z)
direnv Per-directory environment variables loaded from .envrc files (each new .envrc needs a one-time direnv allow) β€” direnv/direnv direnv; git fallback zsh, bash log_format (string, default "" = silent), whitelist (list<string>, default [])
mise Per-project runtime versions (node, python, go, …) from mise.toml / .tool-versions β€” jdx/mise mise (brew, pacman); else release binary, then git + cargo fallback zsh, bash mode (enum activate | shims, default activate)
pay-respects Suggest a corrected command after a failed one, run via the alias (a Rust thefuck alternative) β€” iffse/pay-respects pay-respects (brew); else git + cargo fallback (needs Rust) zsh, bash alias (string, default f)
atuin SQLite-backed shell history with fuzzy search, context and stats β€” atuinsh/atuin. Mutually exclusive with fzf (both bind Ctrl+R) β€” enabling both is a config error. atuin (brew, pacman); else git + cargo fallback (needs Rust) zsh, bash bind_ctrl_r (bool, default true), bind_up_arrow (bool, default true)
modern-aliases Replace ls/cat/find with eza, bat and fd when selected eza, bat, fd zsh, bash replace (list<enum> of ls, cat, find; default ["ls", "cat", "find"])
colorized-man Syntax-highlighted man pages via bat when present, with a zero-dependency less colour fallback β€” (config only) zsh, bash β€”
ls-colors A consistent, readable colour palette for ls / eza and filename completion (LS_COLORS on Linux, LSCOLORS on macOS) β€” (config only) zsh, bash β€”
root-loops Recolour the terminal to a rootloops.sh-generated 16-colour palette on shell start via OSC 4/10/11 escapes (tmux-aware). Opt-in: it overrides your terminal's own colours. auto follows the system light/dark setting (AppleInterfaceStyle on macOS, the freedesktop color-scheme portal on Linux). β€” (config only) zsh, bash appearance (enum auto | dark | light, default auto)
pager-defaults Sensible less defaults: colour passthrough, quit-if-one-screen, smart-case search, a saved search history β€” (config only) zsh, bash β€”
window-title Keep the terminal window/tab title set to the current working directory β€” (config only) zsh, bash β€”
fzf-tab Replace the zsh completion menu with a scrollable, previewable fzf picker (cd <Tab>, git checkout <Tab>, …) β€” Aloxaf/fzf-tab. Requires fzf. git clone (no distro package) zsh cd_preview (bool, default true)
omnishell-prompt A small, fast, git-aware two-line prompt with no external dependency. Opt-in: it sets PROMPT / PS1 β€” leave it off if you already run a prompt framework (starship, powerlevel10k, …). β€” (config only) zsh, bash style (enum minimal | full, default minimal), show_duration (bool, default false; zsh only), char (string, default ❯)
starship The minimal, blazing-fast cross-shell prompt β€” starship.rs. Opt-in: it sets the prompt. Seeds ~/.config/omnishell/starship.toml (a curated single-line theme) the first time a shell starts and points STARSHIP_CONFIG at it β€” edit that file to taste, omnishell never overwrites it. Mutually exclusive with omnishell-prompt β€” enabling both is a config error. starship (brew, apt, pacman, apk); else release binary, then git + cargo fallback zsh, bash β€”
broot A navigable directory-tree TUI; the br function cd's into the directory you pick β€” Canop/broot broot (brew, apt, dnf, pacman); else release binary, then git + cargo fallback zsh, bash cmd (string, default br)
welcome Run fastfetch on every interactive shell start for a system summary. Opt-in β€” this runs a program on each new shell and adds visible startup latency. fastfetch; git + cmake fallback zsh, bash only_ssh (bool, default false)
tmux Auto-attach to (or start) a tmux session on interactive shell start, unless already inside one ($TMUX set). Opt-in β€” every new interactive shell drops you into the multiplexer. Loads before the prompt modules so the session is up before the prompt initialises. Set auto_attach = false to only manage the tmux package and emit nothing into shell startup. tmux (all managers) zsh, bash session (string, default default), auto_attach (bool, default true)

autosuggestions and syntax-highlighting are zsh-only and always render last (with syntax-highlighting after autosuggestions); fzf-tab, when enabled, loads after completion/fzf and before both of those. tmux, when enabled, loads before the prompt modules (starship, omnishell-prompt).

πŸ”¨ Build prerequisites for the git fallback

Note

mise, starship and broot install a verified release binary first (Linux x86_64 and arm64; on 32-bit ARM starship, and mise on armv7). The prerequisites below only apply to them on other architectures.

When no package is available, some modules are built from source. Before cloning anything, omnishell apply checks that the required tools are present (<tool> --version) and, if a minimum applies, recent enough. If something is missing, the module is reported as degraded with a message such as fallback prerequisites missing: cargo >= 1.95 (found 1.75.0); cmake (not found). omnishell does not install build tools β€” install them yourself and re-run omnishell apply.

🧱 Module Needs
πŸ¦€ mise cargo β‰₯ 1.95, cmake
πŸ¦€ starship cargo β‰₯ 1.95
πŸ¦€ atuin cargo β‰₯ 1.95
πŸ¦€ broot cargo β‰₯ 1.85
πŸ¦€ pay-respects cargo β‰₯ 1.85
βš™οΈ welcome cmake

Tip

Distribution cargo packages are often too old. Install a current Rust toolchain with rustup, and cmake from your package manager. The versions above are the minimums the upstream projects declare and can change with new releases.


✍️ Writing your own module

A module is just a folder: a manifest.toml, one zsh.tmpl / bash.tmpl per shell, and an optional hooks/ directory. Drop it in ~/.config/omnishell/modules/<id>/ and it shows up in omnishell list with no rebuild; a user module with the same id as a built-in overrides it (and doctor flags the shadowing). See docs/writing-a-module.md for the full manifest reference, the template context, and a worked example.


πŸ›‘οΈ Safety

  • Nothing changes on your system without omnishell apply, omnishell remove, or omnishell uninstall (init also inserts the rc marker block).
  • Every write to a rc file or init file is preceded by a timestamped backup under ~/.config/omnishell/backups/<timestamp>/.
  • apply refuses to overwrite an init.<shell> file that was edited by hand (exit 1); it tells you to re-run with --force. omnishell doctor reports the same condition as initfile-edited drift.
  • Init files are swapped in atomically only at the very end of apply; an abort before that leaves the old state intact.
  • omnishell doctor reports drift (missing packages, hand-edited init files, missing source line, orphaned lockfile entries, shadowed built-ins) and is CI-friendly via exit code 3.
  • omnishell rollback restores files and the lockfile from a backup snapshot (see Commands) β€” but never packages or vendored files, and never config.toml. The one-time backup omnishell init takes of your rc file before inserting the marker block is a snapshot like any other: rolling back to it removes omnishell's rc integration (like a targeted uninstall), leaving config.toml in place. Two cases stay outside rollback: an uninstall --purge backup (saved outside the config directory since --purge deletes it β€” restoring it is manual, the path is printed when it runs); and anything remove --purge uninstalled (packages, vendored files) β€” remove --purge reverses those, not rollback.

πŸ”’ Exit codes

Code Meaning
0 Success
1 Application error β€” e.g. package install failed, or β‰₯1 module degraded
2 Config / schema error β€” nothing was changed
3 Drift detected (omnishell doctor only)

🚧 Not in v1

  • fish support
  • remote module registry / installing modules from a URL
  • profiles (different module sets per machine)
  • self-update (brew / install.sh cover it)
  • Windows / PowerShell

🀝 Contributing

See CONTRIBUTING.md for build commands, test requirements, and the module-authoring reference.


πŸ“œ Changelog

See CHANGELOG.md for release history.


πŸ“„ License

MIT β€” see LICENSE. Β© 2026 Jeffry WΓΌrmli.

One binary, one config file, one init file per shell β€” and a backup before every write.

About

A cross-platform shell initialization engine designed to provide a unified interactive terminal experience across macOS and Linux, supporting both Bash and Zsh.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages