AI-powered inline command editor for zsh/fish triggered by Shift+Cmd+K, with terminal context awareness.
- Inline TUI: Opens above your prompt without clearing the screen
- Chat interface: Iteratively refine commands through conversation
- Context-aware: Sees your current command buffer and working directory
- Live preview: Command updates in real-time as you chat
- Shimmer animation: Elegant loading indicator while waiting for AI
- Clean restore: Terminal returns to original state on close
- Go 1.21+ (for building)
- Ghostty terminal (for keybind integration)
- zsh or fish shell
- One AI backend: OpenAI API key, OpenRouter API key, Anthropic API key, or local Codex CLI installation/authentication
git clone https://github.com/sttts/shell-ai-widget.git
cd shell-ai-widget
go build -o ~/.bin/shell-ai-widget .Make sure ~/.bin is in your $PATH, or install to a different location.
Create ~/.config/shell-ai-widget/config.toml:
[ai]
provider = "openai" # or "openrouter" or "anthropic" or "codex-cli"
[openai]
api_key = "" # Leave empty to use OPENAI_API_KEY env var
model = "gpt-4o-mini"
[openrouter]
api_key = "" # Leave empty to use OPENROUTER_API_KEY env var
model = "openai/gpt-4o-mini"
[anthropic]
api_key = "" # Leave empty to use ANTHROPIC_API_KEY env var
model = "claude-sonnet-4-20250514"
[codex_cli]
path = "" # Leave empty to auto-detect "codex" in PATH
args = ["exec", "--json"] # optional; default is ["exec","--json"]
[ui]
context_lines = 100Set your API key (OpenAI/OpenRouter/Anthropic) either in the config or as an environment variable:
export OPENAI_API_KEY="sk-..."
# or
export OPENROUTER_API_KEY="sk-or-..."
# or
export ANTHROPIC_API_KEY="sk-ant-..."Copy or source the widget in your .zshrc:
source /path/to/shell-ai-widget/shell/zsh/ai-cmd-edit.zshOr copy it to ~/.zshrc.d/ai-cmd-edit.zsh if using a .zshrc.d directory.
Copy or source the widget in your fish config:
source /path/to/shell-ai-widget/shell/fish/ai-cmd-edit.fishOr copy it to ~/.config/fish/conf.d/ai-cmd-edit.fish.
Add to your Ghostty config (~/.config/ghostty/config or on macOS ~/Library/Application Support/com.mitchellh.ghostty/config):
# AI Command Editor - Shift+Cmd+K to open/close
keybind = cmd+shift+k=text:\x1bk
This sends the escape sequence ESC k when you press Shift+Cmd+K, which triggers the shell widget.
# Reload zsh config
source ~/.zshrc
# Restart Ghostty for keybind changes- Open: Press
Shift+Cmd+K(or your configured hotkey) - Type: Enter your request (e.g., "list files sorted by size")
- Chat: Continue the conversation to refine the command
- Accept: Press
Enteron empty input, orShift+Cmd+Kagain - Cancel: Press
ESCorCtrl+Cto restore original command
> your message here <- Your input (grey background)
⏺ AI response explaining the command <- AI response (light green marker)
❯ ls -lahS <- Current command preview
| Key | Action |
|---|---|
Enter |
Send message to AI, or accept if input empty |
Shift+Cmd+K |
Accept current command and close |
ESC |
Cancel and restore original command |
Ctrl+C |
Cancel and restore original command |
[ai]
provider = "openai" # "openai", "openrouter", "anthropic", or "codex-cli"[openai]
api_key = "" # or use OPENAI_API_KEY env var
model = "gpt-4o-mini" # or "gpt-4o", "gpt-4-turbo", etc.[anthropic]
api_key = "" # or use ANTHROPIC_API_KEY env var
model = "claude-sonnet-4-20250514" # or "claude-opus-4-20250514", etc.[openrouter]
api_key = "" # or use OPENROUTER_API_KEY env var
model = "openai/gpt-4o-mini" # e.g. "anthropic/claude-3.5-sonnet", etc.[ai]
provider = "codex-cli"
[codex_cli]
path = "" # optional, auto-detected from PATH when empty
args = ["exec", "--json"] # optionalWith provider = "codex-cli", no OPENAI_API_KEY is required.
[ui]
context_lines = 100 # Lines of terminal context to send to AIFor even better suggestions, you can pass recent terminal output to the AI. Ghostty supports write_scrollback_file for this:
# In Ghostty config (advanced setup)
keybind = cmd+shift+k=write_scrollback_file:/tmp/scrollback.txt,text:\x1bk
Then modify the zsh widget to pass the context:
result="$(~/.bin/shell-ai-widget --buffer="$BUFFER" --context-file=/tmp/scrollback.txt --shell=zsh 2>/dev/null)"┌─────────────────────────────────────────────────────────────┐
│ Ghostty │
│ Shift+Cmd+K → text:\x1bk (sends ESC k to terminal) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Zsh Widget │
│ - Receives ESC k via bindkey │
│ - Passes $BUFFER to Go binary │
│ - Sets $BUFFER from stdout on success │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Go Binary (shell-ai-widget) │
│ - Renders TUI with bubbletea │
│ - Manages chat with AI provider │
│ - Outputs final command to stdout │
└─────────────────────────────────────────────────────────────┘
git clone https://github.com/sttts/shell-ai-widget.git
cd shell-ai-widget
go build -o shell-ai-widget .This project was vibe coded with Claude.
Apache 2.0