An AI command palette for your terminal. Type what you want. Cast a spell. Run the command.
English · 简体中文
spell is a single-binary TUI that turns plain English (or Chinese, or anything your model speaks) into shell commands. It runs in the terminal you already use, talks to the LLM you already pay for, and stays out of the way.
✦ how do I find files larger than 100MB modified in the last week
$ find . -type f -size +100M -mtime -7The generated command lands directly in the input box, ready to run or edit. enter to execute, ctrl+r to regenerate, esc to start over. One round-trip, no result page.
| spell | thefuck |
gh copilot cli |
shell-gpt | Warp | |
|---|---|---|---|---|---|
| Open source | ✅ | ✅ | ❌ | ✅ | partial |
| Local LLMs (Ollama, etc.) | ✅ | ❌ | ❌ | ✅ | ❌ |
| Bring-your-own provider | ✅ any OpenAI-compatible | ❌ | ❌ | ❌ | |
| Single binary, no runtime | ✅ Go | ❌ Python | gh |
❌ Python | ❌ GUI |
| TUI preview before running | ✅ | ❌ | ❌ | ✅ | |
| Works on top of your shell | ✅ | ✅ | ✅ | ✅ | ❌ replaces it |
brew install rockscy/tap/spellgo install github.com/rockscy/spell/cmd/spell@latestGrab the right archive from Releases and put spell on your $PATH.
git clone https://github.com/rockscy/spell && cd spell
make build && ./bin/spell --helpspell initThat's it. spell init walks you through a 4-step picker — provider → API key → model → default — and writes the config for you. You can re-run it any time to add another provider, change the default, or edit an existing one.
✦ spell init
Let's get you a provider configured.
? Pick a provider
▸ OpenAI
Anthropic (Claude)
Xiaomi MiMo (Token Plan, Singapore)
DeepSeek
Moonshot / Kimi
Groq (fast inference)
OpenRouter (one key, every model)
Ollama (local, no key needed)
Custom (any OpenAI- or Anthropic-compatible endpoint)
? Base URL
https://api.openai.com/v1
> press Enter to keep the default, or paste a different endpoint
(regional mirror, proxy, self-hosted gateway, etc.)
? API key for openai
●●●●●●●●●●●●
> paste the key, or leave blank to use $OPENAI_API_KEY.
? Model
▸ ★ GPT-4o mini (fast, cheap)
GPT-4o
o4-mini (reasoning)
Custom (type your own)
? Set "openai" as the default provider? [Y/n]
✓ Saved to ~/.config/spell/config.toml
Reasoning models (o-series, MiMo Pro, DeepSeek-R1) automatically get max_tokens = 2048 so they have budget for chain-of-thought plus the final command.
If you'd rather hand-edit, the config file is plain TOML at $(spell --where).
Anything that speaks OpenAI-compatible chat completions OR Anthropic Messages. That includes — but is not limited to:
OpenAI · Anthropic · Ollama · DeepSeek · Moonshot/Kimi · Zhipu · Qwen/DashScope · Doubao · Groq · Together · Fireworks · OpenRouter · vLLM · LM Studio · LocalAI · Xiaomi · Baichuan · 01.AI · MiniMax · …
If your provider has an OpenAI-compatible endpoint, you set base_url and you're done.
spell # opens the prompt
spell list all docker containers # one-shot: auto-submits and goes straight to the command
spell -p ollama "compress this folder" # pick a provider for one shotEverything renders inline — spell never takes over your screen. Run a one-shot, hit enter to confirm, the command's output streams right below in the same scrollback.
spell execs the chosen command in a fresh shell, which means env changes (like cd) won't survive. To run the suggestion inside your current shell, drop this in your ~/.zshrc / ~/.bashrc:
sp() {
local cmd
cmd="$(SPELL_PRINT=1 spell "$@")" || return $?
[ -n "$cmd" ] && print -s -- "$cmd" && eval "$cmd"
}Then sp "make me a python venv called spike" and the cd sticks.
Sometimes you don't want a command — you have one and want to know what it does. Pipe it through spell explain:
spell explain "find . -type f -mtime -7 -size +50M"Streams a plain-prose explanation to stdout, no TUI, no confirmation. Pipe-safe.
spell install-hook prints a tiny zsh / bash function. Append it to your ~/.zshrc (or ~/.bashrc) and any time you mistype a command, spell quietly suggests what you probably meant:
spell install-hook >> ~/.zshrc
exec zsh
gti staus
# → Did you mean: `git status`
# Show the working tree status of the current Git repository.The hook only fires for commands that don't exist — it never intercepts your real commands. Remove the block from your rc file to disable.
| key | does |
|---|---|
enter (intent) |
cast — send your query to the model |
enter (command) |
run the generated command |
ctrl+r (command) |
regenerate from the same intent |
esc (command) |
start over with a fresh intent |
esc (intent) |
quit |
ctrl+c |
abort, anywhere |
The command lives in the same input box as the intent — edit it inline, then enter runs it.
Every cast is appended to ~/.local/share/spell/history.jsonl so you can grep your past commands. One line, one cast:
{"ts":"2026-04-30T18:42:01Z","provider":"ollama","query":"…","command":"…","explain":"…"}spell only talks to the provider URL you configure. No telemetry, no analytics, no calls home. The binary is pure Go with net/http — strings(spell) | grep -i posthog will turn up nothing.
make build # ./bin/spell
make install # to $GOPATH/bin
make run # build + run
make release-snap # local goreleaser dry run- Shell hook: auto-explain failed commands (
command_not_found_handler) —spell install-hook(v0.4.0) -
spell explain <cmd>— reverse mode, what does this command do (v0.4.0) - Inline completion via
widget::accept-line - Tools / function calling for safer multi-step plans
- More built-in provider presets
- Theming via
LIPGLOSS_NO_COLORand a[theme]block
PRs welcome — please keep the binary small, dependencies few, and the TUI snappy. See CONTRIBUTING.md.
MIT © 2026 — built with Bubble Tea, Lip Gloss, and a healthy disrespect for sluggish Electron apps.