A shiv package is a git repo with a mise.toml and tasks in .mise/tasks/. shiv clones the repo, resolves its dependencies, and puts a shim on your PATH. From then on it's a regular command — version-controlled, self-updating, with tab completions.
# Install a tool
shiv install shimmer
# Use it — spaces work as namespace separators
shimmer agent message k7r2 "hello"
# See what's installed
shiv list
# Update everything
shiv update
# Check health
shiv doctorshiv manages itself the same way. It's a shiv package too.
When you run shiv install foo, shiv:
- Looks up
fooin the package index (sources.json) - Clones the repo to
~/.local/share/shiv/packages/foo/ - Runs
mise installto resolve dependencies - Generates a shim at
~/.local/bin/foo - Registers the package in
~/.config/shiv/registry.json
The shim is a bash script that forwards commands to mise -C <repo> run. It exports a package-specific caller variable (for example, SHIMMER_CALLER_PWD) so tools know where you invoked them, translates space-separated arguments to colon-joined task names (agent message → agent:message), and provides tab completions for all available tasks.
curl -fsSL shiv.knacklabs.co/install.sh | bashOr on Windows:
irm shiv.knacklabs.co/install.ps1 | iexBoth platforms are fully supported. The installer detects your environment, installs mise if needed, clones shiv, configures package sources, and sets up shell integration. On Windows, shiv generates .ps1 and .cmd shims and configures your PowerShell profile.
What does the installer do?
- Detects OS, architecture, and shell
- Installs mise if not present (via winget on Windows)
- Clones shiv and resolves its dependencies
- Configures package source registries
- Creates the self-hosting shiv shim and sets up shell integration
- Verifies the installation
Add this to your shell config to activate shiv on startup:
eval "$(shiv shell)"shiv looks up packages from JSON source files in ~/.config/shiv/sources/. The installer seeds this directory with the default KnickKnackLabs index. Add your own by dropping a JSON file there:
# ~/.config/shiv/sources/my-org.json
{
"my-tool": "my-org/my-tool",
"another": "my-org/another"
}By default, package-index installs use the newest stable semver release tag. Use an explicit ref when you want branch tracking or an exact pin:
shiv install notes # newest released semver tag
shiv install notes@latest # same as bare install
shiv install notes@main # track a branch explicitly
shiv install notes@v0.8.4 # pin an exact tag
shiv install notes@abc1234 # pin an exact commitshiv update preserves that intent: release-channel installs advance to the newest release tag, branch installs pull their branch, and exact tag/commit pins stay fixed until you reinstall at another ref. Legacy installs without recorded intent are refused with guidance to choose @latest or @main explicitly.
You can also install directly from a local path:
shiv install my-tool /path/to/repoSome useful tools are smaller than a package. shiv run-url runs a single pinned uv script from a raw URL without cloning a repo. Use it for small diagnostics, migrations, and experiments that may or may not grow into packages later.
# Pinned GitHub raw or gist URL required by default
shiv run-url https://raw.githubusercontent.com/owner/repo/<commit>/task.py --json
# Floating URLs are allowed only when made explicit
shiv run-url --floating https://raw.githubusercontent.com/owner/repo/main/task.pyRemote code execution is the point and the risk: pinned revisions are the default, query strings are rejected, downloads are cached by content hash, and the script receives SUCKER_CALLER_PWD for the directory where you invoked shiv.
Any git repo with a mise.toml and executable scripts in .mise/tasks/ is a shiv package. Each task becomes a subcommand:
my-tool/
├── mise.toml # dependencies
└── .mise/tasks/
├── hello # → my-tool hello
└── greet/
└── world # → my-tool greet world (or greet:world)To make it installable by name, add it to a source file. To register it in the default index, add an entry to sources.json in this repo.
git clone https://github.com/KnickKnackLabs/shiv.git
cd shiv && mise trust && mise install
mise run testTests use BATS — the default run covers 284 tests across 14 suites. Completion tests run separately.
