Run a shell script automatically when you cd into — or out of — a directory.
Activate a virtualenv the moment you step into a project. Switch kubectl
context per repo. Export project-scoped secrets and have them vanish the
moment you leave. One static binary, every major shell, nothing runs until
you say so.
brew install neirda24/tap/envoke
echo 'eval "$(envoke shell-init zsh)"' >> ~/.zshrc # bash, fish, tcsh, powershell also supported# ~/.envokerc
enter ~/Projects/([^/]+)
source "$ENVOKE_DIR/venv/bin/activate"
leave ~/Projects/([^/]+)
deactivate
envoke allow # review the config once, approve it
cd ~/Projects/my-app # venv activates, automatically- Predictable matching — path patterns compile to Go's RE2 engine: linear-time, so a pathological pattern can't stall your shell.
- Segment-based matching —
~/foonever accidentally matches~/foobar. - One file, or one per project — patterns in
~/.envokerccover whole trees of repos you don't own, and anenvokerc.ddirectory splits rules per project. A config committed inside a repo joins in by a symlink you create, with patterns written relative to it (enter ./src). - Nothing runs unapproved, and nothing is discovered — envoke only loads
configs from your own config directory, and each sits inert until
envoke allowreviews and trusts it; any further edit revokes trust until you re-approve. - One binary, every shell — bash, zsh, fish, tcsh, and PowerShell hooks
are all generated by
envoke shell-init, not hand-maintained per shell. - Dry-run first —
envoke debug <from>shows exactly what would fire on the way from there to where you are, without ever executing anything. - An off switch that isn't your rc file —
envoke disable/enable, orENVOKE_DISABLEfor one terminal. Andeval "$(envoke reload)"applies a freshly approved config where you're standing.
- Activate/deactivate a Python (or any) virtualenv per project
- Switch
kubectlcontext /AWS_PROFILE/gcloudconfig per directory tree - Export and unset project-scoped API keys or feature flags
- Swap Node/Ruby/Go toolchain versions per project
- Tighten
umaskfor a sensitive tree, restore it on the way out
Each of these is written out as a complete enter/leave pair, unwinding
included, in Recipes.
| Install, hook your shell, write a first block | Getting Started |
| Config syntax, path patterns, what a script sees | Configuration |
| Worked examples with their teardown | Recipes |
| Why a block didn't fire | Troubleshooting |
| Every command, flag, variable and exit code | Reference |
Why envoke allow exists and how it works |
Trust Model |
brew install neirda24/tap/envoke # Homebrew (macOS/Linux)
scoop bucket add neirda24 https://github.com/Neirda24/scoop-bucket && scoop install envoke # Scoop (Windows)
go install github.com/Neirda24/envoke/cmd/envoke@latest # Go toolchainOr grab a prebuilt binary, .deb, or .rpm from Releases
for macOS/Linux/Windows (amd64/arm64) — each release's checksums.txt is
cosign-signed, see the release notes to verify.
envoke is a spiritual rewrite of ondir —
the same enter/leave-by-path-pattern model, picked up on a few specific
points (regex engine choice, path matching semantics, a trust/approval step)
and extended past bash/zsh to five shells.
direnv solves an adjacent problem: one .envrc per
directory, found by walking into it, shaped around environment variables with
automatic load/unload and a large stdlib.
Point by point: envoke vs. direnv and Design Notes (vs. ondir).
Early development — the mileage is early, not the feature list. Everything below is implemented and tested end to end against real interpreters:
- the matching engine — patterns, intermediate directories, ordering;
- all five shell integrations (bash, zsh, fish, tcsh, PowerShell);
- the
envokerc.dfragment directory — relative patterns, symlinked project configs; - the trust mechanism —
allow,revoke,list,prune; - the
disable/enableoff switch,reload, non-interactiveexec, anddebugdry-run diagnostics; - packaging — Homebrew, Scoop, GitHub Releases, and
.deb/.rpmpackages, each release carrying a per-archive SBOM and cosign-signed checksums.
There is no roadmap section here on purpose: if envoke help doesn't list it,
it doesn't exist. Every command, flag, environment variable, file and exit
code is inventoried in the
Reference.
See CONTRIBUTING.md.