envoke

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: MIT

README

envoke

CI Release

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.

Full documentation →

Quickstart

brew install neirda24/tap/envoke
echo 'eval "$(envoke shell-init zsh)"' >> ~/.zshrc   # bash, fish, tcsh, powershell also supported
# ~/.envokerc
enter ~/Projects/([^/]+)
    source venv/bin/activate

leave ~/Projects/([^/]+)
    deactivate
envoke allow          # review the config once, approve it
cd ~/Projects/my-app  # venv activates, automatically

Full walkthrough in Getting Started, more config examples in Configuration.

Why envoke

  • Predictable matching — path patterns compile to Go's RE2 engine: linear-time, so a pathological pattern can't stall your shell.
  • Segment-based matching — ~/foo never accidentally matches ~/foobar.
  • Nothing runs unapproved — a new or edited config sits inert until envoke allow reviews 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> <to> shows exactly what would fire, without ever executing anything.
vs. ondir / direnv

envoke is a spiritual rewrite of ondir — same enter/leave-by-path-pattern idea. ondir is feature-complete by its own maintainer's account and still does the job, but it hasn't seen a release in years; envoke picks up the same model on a few specific points (regex engine choice, path matching semantics, a trust/approval step) and extends shell support beyond bash/zsh. direnv solves an adjacent but different problem: one .envrc per directory with load/unload semantics, not pattern-matched hooks across a whole tree.

Point-by-point: envoke vs. direnv (central config vs. per-directory .envrc, and when to use which) and Design Notes (vs. ondir).

What you can do with it

  • Activate/deactivate a Python (or any) virtualenv per project
  • Switch kubectl context / AWS_PROFILE / gcloud config per directory tree
  • Export and unset project-scoped API keys or feature flags
  • Swap Node/Ruby/Go toolchain versions per project
  • Tighten umask for a sensitive tree, restore it on the way out

Installation

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 toolchain

Or 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.

Status

Early development. The matching engine, all five shell integrations, the trust mechanism, and envoke debug are implemented and tested end-to-end against real interpreters. Packaging is live: Homebrew, Scoop, GitHub Releases, and .deb/.rpm packages, each release carrying a per-archive SBOM and cosign-signed checksums. See CLAUDE.md for exact scope and architecture.

Contributing

See CONTRIBUTING.md.

License

MIT

Directories

Path Synopsis
cmd
envoke command
Command envoke runs shell scripts when you cd into or out of a directory.
Command envoke runs shell scripts when you cd into or out of a directory.
internal
config
Package config parses envoke config files into a set of enter/leave blocks, each pairing a path pattern with a shell script body.
Package config parses envoke config files into a set of enter/leave blocks, each pairing a path pattern with a shell script body.
envoke
Package envoke wires the config, trust, matcher and executor packages together into the core enter/leave loop used for non-interactive execution (`envoke exec`).
Package envoke wires the config, trust, matcher and executor packages together into the core enter/leave loop used for non-interactive execution (`envoke exec`).
executor
Package executor runs a matched enter/leave block's script.
Package executor runs a matched enter/leave block's script.
matcher
Package matcher resolves which enter/leave config blocks fire for a directory change, including ondir-style traverse behavior: jumping straight from /a to /a/x/y/z still fires the rules for the intermediate directories /a/x and /a/x/y, not just the destination.
Package matcher resolves which enter/leave config blocks fire for a directory change, including ondir-style traverse behavior: jumping straight from /a to /a/x/y/z still fires the rules for the intermediate directories /a/x and /a/x/y, not just the destination.
shellinit
Package shellinit generates the shell hook code printed by `envoke shell-init <shell>`, meant to be eval'd/sourced from the user's shell rc file (e.g.
Package shellinit generates the shell hook code printed by `envoke shell-init <shell>`, meant to be eval'd/sourced from the user's shell rc file (e.g.
trust
Package trust implements envoke's config trust store: a config file must be explicitly approved with Allow before shell-hook will act on it, and any change to the file's content — even whitespace — revokes that trust until Allow runs again.
Package trust implements envoke's config trust store: a config file must be explicitly approved with Allow before shell-hook will act on it, and any change to the file's content — even whitespace — revokes that trust until Allow runs again.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL