# Show HN: Vibe zsh, turn natural language into shell commands

> Source: <https://github.com/skymoore/vibe-zsh>
> Published: 2026-06-29 23:01:22+00:00

Transform natural language into shell commands using AI. Works natively with OpenAI, Anthropic, Groq, OpenRouter, Ollama, LM Studio, and more.

```
# Type your intent in natural language
list all docker containers

# Press Ctrl+G

# Get the command with explanations
docker ps -a
# docker: Docker command-line tool
# ps: List containers
# -a: Show all containers (not just running)
```

- 🧠
**Natural language to commands**- Just describe what you want - 🖥️
**OS-aware generation**- Commands that work on YOUR system (macOS/Linux/Windows) - ⚡
**Lightning fast**- Cached responses are 100-400x faster - 🎬
**Streaming output**- Typewriter effect with progress indicators - 🔌
**Multi-provider**- Native support for OpenAI, Anthropic, Groq, OpenRouter, Ollama, LM Studio, and more - 🛡️
**Safe by default**- Preview commands before execution - 📚
**Learn while you work**- Inline explanations for every command - 📜
**Query history**- Interactive menu to browse and re-run previous queries - 🎯
**Single binary**- One compiled binary, no runtime dependencies to install

```
brew tap skymoore/tap
brew install --cask vibe-zsh
```

The Homebrew installation automatically:

- Installs vibe to
`~/.oh-my-zsh/custom/plugins/vibe`

- Adds
`vibe`

to your plugins list in`~/.zshrc`

- Creates a global
`vibe-zsh`

command for CLI usage

After installation, reload your shell:

```
source ~/.zshrc
```

**Note:** Requires Oh-My-Zsh. If not installed, the installer will provide instructions.

For oh-my-zsh integration:

```
curl -fsSL https://raw.githubusercontent.com/skymoore/vibe-zsh/main/install.sh | bash
```

Or using wget:

```
wget -qO- https://raw.githubusercontent.com/skymoore/vibe-zsh/main/install.sh | bash
```

This script downloads the latest release and installs it to `~/.oh-my-zsh/custom/plugins/vibe`

. You'll need to manually add `vibe`

to your plugins list in `~/.zshrc`

.

-
**Clone the repository:**

```
git clone https://github.com/skymoore/vibe-zsh.git ~/.oh-my-zsh/custom/plugins/vibe
```

-
**Build the binary:**

```
cd ~/.oh-my-zsh/custom/plugins/vibe
make build
```

-
**Add to your**`.zshrc`

:

```
plugins=(... vibe)
```

-
**Reload your shell:**

```
source ~/.zshrc
```

Add these to your `~/.zshrc`

(all optional).

vibe-zsh uses [gollm](https://github.com/teilomillet/gollm) to talk to each
provider natively. There are two kinds of provider:

**Hosted providers**(`openai`

,`anthropic`

,`groq`

,`openrouter`

,`deepseek`

,`google-openai`

,`mistral`

,`cohere`

) have a fixed endpoint built in. You only need to choose the provider, set`VIBE_API_KEY`

, and pick a`VIBE_MODEL`

— you do**not** set`VIBE_API_URL`

.**Local providers**(`ollama`

,`lmstudio`

,`vllm`

) run on your machine. Set`VIBE_API_URL`

to point at the local server; no API key is required.

Select a provider with `VIBE_PROVIDER`

. If you don't set it, vibe infers the
provider from `VIBE_API_URL`

(e.g. an `openrouter.ai`

or `:11434`

URL), which is
mainly there to keep older configs working. **Setting VIBE_PROVIDER explicitly
is the recommended approach.**

The default

`VIBE_MODEL`

is`llama3:8b`

(chosen for the default Ollama setup). Always set`VIBE_MODEL`

when you use a hosted provider, or requests will ask for a model that doesn't exist there.

```
export VIBE_PROVIDER="openai"
export VIBE_API_KEY="sk-..."
export VIBE_MODEL="gpt-4o"
# No VIBE_API_URL needed — the openai provider always targets api.openai.com.
export VIBE_PROVIDER="anthropic"
export VIBE_API_KEY="sk-ant-..."
export VIBE_MODEL="claude-3-5-sonnet-20241022"
export VIBE_PROVIDER="groq"
export VIBE_API_KEY="gsk_..."
export VIBE_MODEL="llama-3.1-70b-versatile"
export VIBE_PROVIDER="openrouter"
export VIBE_API_KEY="sk-or-..."
export VIBE_MODEL="anthropic/claude-3.5-sonnet"
export VIBE_PROVIDER="ollama"
export VIBE_API_URL="http://localhost:11434/v1"
export VIBE_MODEL="llama3:8b"
# Ollama must be running; no API key required.
export VIBE_PROVIDER="lmstudio"
export VIBE_API_URL="http://localhost:1234/v1"
export VIBE_MODEL="local-model"
# LM Studio must be running and reachable when vibe starts.
```

Note on validation:gollm checks your configuration when vibe starts. Hosted providers validate the API key format up front (for example, Anthropic keys must start with`sk-ant-`

), and local providers must already be running and reachable. If a provider is misconfigured, vibe reports an actionable error on the first query rather than silently failing.

Custom OpenAI-compatible gateways:the`openai`

provider always points at`api.openai.com`

, so it can't be redirected to a self-hosted gateway via`VIBE_API_URL`

. To use an OpenAI-compatible endpoint that isn't OpenAI itself, set`VIBE_PROVIDER`

to`lmstudio`

or`vllm`

and point`VIBE_API_URL`

at your gateway.

- Type a natural language description in your terminal
- Press
`Ctrl+G`

- Review the generated command (with explanations)
- Press
`Enter`

to execute, or edit first

**History Menu:**

Access your query history in two ways:

**Keybinding**: Press`Ctrl+X`

then`H`

**Command**: Type`vh`

and press Enter

Both methods open an interactive menu where you can:

- Browse previous queries with arrow keys
- Search with
`/`

(filter mode) - Press
`Enter`

to insert the generated command into your buffer - Press
`G`

to regenerate a new command from the original query - Press
`V`

to edit the original query in your buffer - Press
`A`

or`Home`

to jump to the first entry - Press
`E`

or`End`

to jump to the last entry - Press
`Esc`

or`Q`

to cancel

The selected command appears on your command line, ready to execute!

**Quick Regenerate:**

Press `Ctrl+X`

then `G`

to instantly regenerate a new command from your most recent query without opening the menu.

**Note**: Don't run `vibe-zsh history`

or `./vibe history`

directly - use `vh`

or the keybinding instead.

You can also use vibe directly from the command line:

```
# Homebrew installation
vibe-zsh "list all docker containers"

# Manual installation (Oh-My-Zsh plugin)
~/.oh-my-zsh/custom/plugins/vibe/vibe "list all docker containers"
```

**CLI Flags:**

```
vibe-zsh --help                    # Show all available flags
vibe-zsh --debug "query"           # Enable debug logging
vibe-zsh --temperature 0.1 "query" # Override temperature
vibe-zsh --interactive "query"     # Confirm before execution
```

**History Commands:**

```
vh                                 # Interactive menu (recommended)
vibe-zsh history list              # List history in plain text
vibe-zsh history clear             # Clear all history

# Note: Use 'vh' or Ctrl+X H for interactive menu
# Don't use 'vibe-zsh history' directly (it just outputs to stdout)
```

**Query History:**

```
# Open history menu with keybinding
Ctrl+X H

# Or use the command
vh

# List history in plain text
vibe-zsh history list

# Clear all history
vibe-zsh history clear
```

**File Operations:**

```
show me all hidden files including their sizes
# → ls -lah
```

**Docker:**

```
show logs of nginx container and follow them
# → docker logs -f nginx
```

**Git:**

```
show me commits from last week
# → git log --since="1 week ago"
```

**Find & Search:**

```
find all python files modified today
# → find . -name "*.py" -mtime 0
```

**Tab Completion:**

```
vibe <TAB><TAB>
# Shows common query suggestions
```

**Hide Explanations:**

```
export VIBE_SHOW_EXPLANATION=false
```

**Interactive Mode** (confirm before inserting):

```
export VIBE_INTERACTIVE=true
```

**Disable Cache:**

```
export VIBE_ENABLE_CACHE=false
```

**Disable Auto-Updates:**

```
export VIBE_AUTO_UPDATE=false
```

**Customize History Keybinding:**

```
export VIBE_HISTORY_KEY="^R"      # Use Ctrl+R for history menu
export VIBE_REGENERATE_KEY="^[r"  # Use Alt+R for quick regenerate
# Note: Avoid ^H (Ctrl+H) as it conflicts with Backspace
```

**Disable History:**

```
export VIBE_ENABLE_HISTORY=false
```

| Variable | Default | Description |
|---|---|---|
API Configuration |
||
`VIBE_PROVIDER` |
(inferred from `VIBE_API_URL` ) |
LLM provider. Hosted: `openai` , `anthropic` , `groq` , `openrouter` , `deepseek` , `google-openai` , `mistral` , `cohere` . Local: `ollama` , `lmstudio` , `vllm` . Recommended to set explicitly. |
`VIBE_API_URL` |
`http://localhost:11434/v1` |
Endpoint URL for local providers only (`ollama` , `vllm` ). Hosted providers ignore this and use their fixed endpoints. |
`VIBE_API_KEY` |
`""` |
API key. Required for hosted providers; ignored by local providers. |
`VIBE_MODEL` |
`llama3:8b` |
Model to use. Set this for hosted providers — the default only suits Ollama. |
`VIBE_TEMPERATURE` |
`0.2` |
Generation temperature (0.0-2.0) |
`VIBE_MAX_TOKENS` |
`1000` |
Max response tokens |
`VIBE_TIMEOUT` |
`30s` |
Request timeout |
Display Options |
||
`VIBE_SHOW_EXPLANATION` |
`true` |
Show command explanations |
`VIBE_SHOW_WARNINGS` |
`true` |
Show warnings for dangerous commands |
`VIBE_SHOW_PROGRESS` |
`true` |
Show progress spinner during generation |
`VIBE_PROGRESS_STYLE` |
`dots` |
Spinner style: dots, line, circle, bounce, arrow, runes (ᛜ ᛃ ᛋ) |
`VIBE_STREAM_OUTPUT` |
`true` |
Stream output with typewriter effect |
`VIBE_STREAM_DELAY` |
`20ms` |
Delay between streamed words |
Behavior |
||
`VIBE_INTERACTIVE` |
`false` |
Confirm before inserting command |
`VIBE_USE_STRUCTURED_OUTPUT` |
`true` |
Use JSON schema for structured responses |
`VIBE_ENABLE_CACHE` |
`true` |
Enable response caching |
`VIBE_CACHE_TTL` |
`24h` |
Cache lifetime |
Parsing & Retry |
||
`VIBE_MAX_RETRIES` |
`3` |
Max retry attempts for failed parsing |
`VIBE_ENABLE_JSON_EXTRACTION` |
`true` |
Extract JSON from corrupted responses |
`VIBE_STRICT_VALIDATION` |
`true` |
Validate response structure |
`VIBE_SHOW_RETRY_STATUS` |
`true` |
Show retry progress during generation |
History |
||
`VIBE_ENABLE_HISTORY` |
`true` |
Enable query history tracking |
`VIBE_HISTORY_SIZE` |
`100` |
Maximum number of history entries |
`VIBE_HISTORY_KEY` |
`^Xh` (Ctrl+X H) |
Keybinding for history menu |
`VIBE_REGENERATE_KEY` |
`^Xg` (Ctrl+X G) |
Keybinding to regenerate last command |
Updates & Debugging |
||
`VIBE_AUTO_UPDATE` |
`true` |
Enable auto-update checks |
`VIBE_UPDATE_CHECK_INTERVAL` |
`7d` |
How often to check for updates |
`VIBE_DEBUG_LOGS` |
`false` |
Enable debug logging for troubleshooting |

**Capture**- You type natural language and press`Ctrl+G`

**Context**- vibe detects your OS (macOS/Linux/Windows) and shell (zsh/bash/etc.)** Generate**- vibe sends your query with system context to the configured LLM** Parse**- Response is structured as command + explanations** Cache**- Response is cached for 24 hours (configurable)** Stream**- Command is streamed to your terminal with typewriter effect** Insert**- Command appears in your buffer for review** Execute**- You press Enter to run (or edit first)

vibe automatically detects your operating system and shell, ensuring generated commands work on your system:

**macOS**: Uses BSD utilities (e.g.,`find`

without`-printf`

,`sed -i ''`

)**Linux**: Uses GNU utilities (e.g.,`find -printf`

,`sed -i`

)**Shell-specific**: Generates syntax appropriate for zsh, bash, etc.

This means you get commands that actually work on your system, not generic Linux commands that fail on macOS!

**First query:**~500ms-2s (depends on LLM)** Cached query:**~5-10ms (100-400x faster!)** Binary size:**~8MB** Memory usage:**<10MB

- ✅ Commands are never executed automatically
- ✅ Full preview before execution
- ✅ Edit commands before running
- ✅ Warnings for dangerous commands
- ✅ Optional interactive confirmation mode
- ✅ Local-first with Ollama (your data stays private)

vibe automatically checks for updates once a week in the background (zero impact on performance). When an update is available, you'll see a notification:

```
⚠️  vibe v1.2.4 available (current: v1.2.3)
   Run: vibe --update
```

**Manual Commands:**

```
vibe --version              # Show current version
vibe --update               # Download and install latest version
```

**Configuration:**

```
export VIBE_AUTO_UPDATE=false           # Disable auto-update checks
export VIBE_UPDATE_CHECK_INTERVAL=14d   # Check every 2 weeks instead
```

**Security:**

- All downloads are verified using SHA256 checksums
- Checksums are published with each release
- Original binary is backed up before replacement
- Safe atomic file replacement

The update check runs in a background process after each command, so it never slows down your workflow. Updates are never installed automatically - you always control when to update.

**Command not working after install:**

- Reload your shell:
`source ~/.zshrc`

- Verify plugin is in list:
`echo $plugins`

- Check binary exists:
`ls ~/.oh-my-zsh/custom/plugins/vibe/vibe`

**Slow responses:**

- Enable caching:
`export VIBE_ENABLE_CACHE=true`

- Use a faster model or local LLM
- Check your network connection

**Bad command suggestions:**

- Try a different/better model
- Make your query more specific
- Check model supports structured output

**Corrupted or garbage output:**

- vibe now automatically handles corrupted LLM responses with multi-layer parsing
- Enable debug logs to see what's happening:
`export VIBE_DEBUG_LOGS=true`

- Check logs for raw responses and parsing attempts
- Try increasing retries:
`export VIBE_MAX_RETRIES=5`

**Parsing errors:**

- Enable JSON extraction:
`export VIBE_ENABLE_JSON_EXTRACTION=true`

(default) - Disable strict validation temporarily:
`export VIBE_STRICT_VALIDATION=false`

- Check debug logs to see which parsing layer succeeded/failed
- Some models produce cleaner JSON with lower temperature:
`export VIBE_TEMPERATURE=0.3`

**Ctrl+G does nothing:**

- Ensure plugin is loaded:
`which vibe`

(should show a function) - Check no other plugin uses Ctrl+G
- Try rebinding:
`bindkey '^G' vibe`

- Zsh with Oh-My-Zsh
- An LLM provider — hosted (OpenAI, Anthropic, Groq, OpenRouter, etc.) or local (Ollama, LM Studio, vLLM)
- macOS or Linux

```
brew uninstall --cask vibe-zsh
brew untap skymoore/tap  # Optional: remove the tap
```

Then remove `vibe`

from your plugins list in `~/.zshrc`

and reload:

```
source ~/.zshrc
curl -fsSL https://raw.githubusercontent.com/skymoore/vibe-zsh/main/uninstall.sh | bash
```

Or using wget:

```
wget -qO- https://raw.githubusercontent.com/skymoore/vibe-zsh/main/uninstall.sh | bash
```

Then remove `vibe`

from your plugins list in `~/.zshrc`

and reload:

```
source ~/.zshrc
git clone https://github.com/skymoore/vibe-zsh.git
cd vibe-zsh
make build        # Build for current platform
make build-all    # Build for all platforms
make test         # Run tests
make install      # Install to oh-my-zsh
```

Contributions welcome! This project uses:

- Go 1.26+
- Standard zsh scripting
[gollm](https://github.com/teilomillet/gollm)for native multi-provider LLM access

GPLv3 License - see [LICENSE](/skymoore/vibe-zsh/blob/main/LICENSE)

Inspired by [LoganPederson/vibe](https://github.com/LoganPederson/vibe)

Built for terminal productivity enthusiasts 🚀
