ShellSage
ShellSage is an AI-powered command-line assistant that integrates seamlessly with your terminal workflow through tmux. It provides contextual help for shell operations, making it easier to navigate complex command-line tasks, debug scripts, and manage your system.
Overview
ShellSage is an AI-powered command-line assistant that integrates seamlessly with your terminal workflow through tmux. It provides contextual help for shell operations, making it easier to navigate complex command-line tasks, debug scripts, and manage your system.
ShellSage works with multiple LLM providers including Claude, GPT, and Ollama. It uses tmux to automatically read your terminal history or multiple pane histories to provide contextual assistance. You can pipe command output or file contents directly to ShellSage, and it can view files, search code, create files, and make edits with your permission. When needed, it can even search the internet for up-to-date information. You can also log all your interactions directly to SQLite for later reference.
Installation
Install ShellSage directly from PyPI using pip:
pip install shell-sageInstalling with uv
If you have uv installed then you can use its powerful tool feature to install ShellSage as a global CLI — safely, with per-tool isolation and no need for manual virtualenv management.
uv tool install shell_sageThis will make the ssage CLI available everywhere on your system.
If you also want to install additional dependencies (for example fastlite), you can do it at install time:
uv tool install --with fastlite shell_sageUpgrade
To upgrade ShellSage to the latest version:
uv tool upgrade shell_sageList All Installed Tools
See everything you’ve installed via uv tool:
uv tool listUninstall
To completely remove ShellSage and its environment:
uv tool uninstall shell_sageUsing uv tool keeps ShellSage completely isolated from your project dependencies, so you can safely use ssage even when inside another virtual environment.
Prerequisites
ShellSage defaults to Anthropic’s current Haiku model (fastllm.types.haik). Export your Anthropic API key:
export ANTHROPIC_API_KEY=sk...If you prefer to use OpenAI instead, export your OpenAI API key and set the model in your ShellSage config or on the command line:
export OPENAI_API_KEY=sk...ShellSage works best with a properly configured tmux environment. I’ve created a preconfigured tmux configuration that works well with ShellSage. This configuration enables mouse support, adds pane IDs to your status bar so you can quickly reference them when having ShellSage read from specific panes, turns off alternative-screen so editor content like vim stays in the tmux buffer where ShellSage can see it, and adds a convenient shortcut (CTRL+B+E followed by the index number) for automatically extracting code fence blocks into your command prompt.
Getting Started
Your First Command
Once installed, try ShellSage with a simple greeting:
ssage hiIf everything is properly setup, you should see a welcoming greeting back from ShellSage!
Getting Help with Commands
The most basic use case is asking about shell commands:
ssage "how do I list all files including hidden ones?"ShellSage will provide the command, explain how it works, and give you practical examples.
Using Terminal Context
ShellSage automatically reads your tmux history to understand what you’re working on:
# After running some commands that produced errors (e.g. find -name "*.tmp" .)
ssage "what went wrong with my last command?"Clearing Context
Ctrl-L looks like it clears the terminal, but it only wipes the visible screen – tmux’s history still holds everything, so ShellSage keeps seeing it. The ssage_clear binding gives ctrl-L real “clear” semantics for ShellSage without destroying anything: it scrolls the screen into history and records a mark, and ShellSage captures never reach past the most recent clear, while your own scrollback stays intact.
Save the script from the link above, then add to your .bashrc:
source /path/to/ssage_clear.sh
bind -x '"\C-l": ssage_clear'Or to your .zshrc:
source /path/to/ssage_clear.sh
zle -N ssage_clear && bindkey '^L' ssage_clearThe binding is only active at the shell prompt, so full-screen apps still receive a plain ctrl-L, and outside tmux it falls back to a normal clear.
Piping Content for Analysis
One of ShellSage’s most powerful features is analyzing piped input. Piped content and terminal history are sent as literal user text, including any embedded tool or usage markers:
# Understand error messages
journalctl --since "1 hour ago" --no-pager | ssage explain this errorWorking with Multiple Tmux Panes
When you have multiple panes open, you can reference specific ones by their ID (shown in your status bar):

# Analyze what's happening in pane %2
ssage --pid %2 "what can you tell me about this pane?"Configuration and Model Providers
Configuration File
ShellSage can be customized through a configuration file located at ~/.config/shell_sage/shell_sage.conf:
[DEFAULT]
# model = anthropic/claude-sonnet-5-5 # Optional model override
search = '' # Web search effort for supported models: l, m, or h
think = '' # Reasoning effort for supported models: l, m, or h
trust = '' # Comma-delimited list of tools to always allow
mode = 'default' # or "sassy"
api_name = # API format override: openai for Responses, openai_chat for Chat Completions
base_url = '' # Alternative API base URL
api_key = '' # API key override instead of the default env var
history_lines = -1 # Lines of terminal history to include. -1 means include all
code_theme = "monokai" # Syntax highlighting theme
code_lexer = "python" # Default lexer for inline code blocks
log = False # Enable SQLite logging (required for code extraction)
safecmd = False # Enable the safecmd-backed bash tool
custom_instructions = '' # Extra instructions appended to the system prompt
Config values expand $VAR and ${VAR} when read. For example, api_key = ${MY_API_KEY} reads the current environment value while keeping the reference in the file.
Using Different Model Providers
ShellSage uses fastllm under the hood. fastllm can automatically resolve common Claude, Gemini, GPT, and OpenAI model names. For other providers, prefix the model name with the vendor, e.g. openrouter/openai/gpt-5:
| Prefix | API key source |
|---|---|
openai |
OPENAI_API_KEY |
anthropic |
ANTHROPIC_API_KEY |
gemini |
GEMINI_API_KEY |
openai_chat |
OPENAI_API_KEY |
codex |
CODEX_AUTH_TOKEN or ~/.codex/auth.json |
claude_code |
Claude Code subscription (no key needed) |
moonshot |
MOONSHOT_API_KEY |
deepseek |
DEEPSEEK_API_KEY |
openrouter |
OPENROUTER_API_KEY |
together |
TOGETHER_API_KEY |
fireworks_ai |
FIREWORKS_API_KEY |
qwen |
QWEN_API_KEY |
Claude, OpenAI, and Gemini
Common Claude, GPT, and Gemini model names are auto-resolved:
ssage --model claude-sonnet-4-6 explain systemd timers
ssage --model gpt-5 explain kubernetes pods
ssage --model gemini-2.5-pro what is journald?Vendor Prefixes
Prefix the model with a vendor when the name does not identify the provider on its own:
ssage --model openrouter/openai/gpt-5 explain cgroups
ssage --model codex/gpt-5.5 review my shell scriptA claude_code/ prefix uses your Claude Code subscription instead of an API key:
ssage --model claude_code/claude-sonnet-4-6 explain iptablesYou can also set a prefixed model in your config:
model = 'codex/gpt-5.5'
Other Providers
For another OpenAI-compatible API, provide the API base URL, API key, and model:
ssage --base-url https://your-api.com/v1 --api-key your_key --model your_model your queryFor a Responses-compatible server, pass --api-name openai. A custom URL otherwise uses Chat Completions.
For known providers, prefer the matching prefix from the table above so fastllm can use the right API format and environment variable.
Command Line Overrides
Any configuration option can be temporarily overridden via command line arguments:
# Adjust history lines
ssage --history-lines 100 what commands did I just run?
# Change the display theme
ssage --code-theme dracula --code-lexer python show me a python exampleYou can find all available code themes and lexers at https://pygments.org/styles/
Bash Tool (Safe Command Execution)
ShellSage can execute shell commands on your behalf using the safecmd library, which provides a safety layer via an allow-list approach.
Enabling the Bash Tool
Add to your config file (~/.config/shell_sage/shell_sage.conf):
safecmd = true
How It Works
When enabled, ShellSage gains access to a bash tool that:
- Validates commands against a curated allow-list before execution
- Supports pipes, redirects, and shell operators
- Blocks potentially destructive operations by default
- Can be customized to allow or restrict allowed commands/destinations
Example Usage
ssage "what files are in this directory and how big are they?"
# ShellSage can now run `ls -la` or `du -sh *` to answerSee the safecmd documentation for details on the allow-list
Extracting and Running Commands
When ShellSage suggests commands, you can extract them directly to your command line. Note that this feature requires you to have logging enabled in your configuration file:
ssage "how do I find large files?"ShellSage will respond with code blocks. Press Ctrl+B E then enter the index number (0 for first block, 1 for second, etc.) to send that command directly to your prompt. You can also directly use the console script:
ssage_extract 0
# inserts "du -ah . | sort -rh | head -20" into your tmux promptYou can also bind a keyboard shortcut in Bash to insert code fences directly into your prompt. Type a block number (or leave empty for 0), then press Ctrl+J to insert that code block. To use this, add the following to your ~/.bashrc:
ssage-insert() {
local r=$(ssage_extract --do-print "${READLINE_LINE:-0}")
READLINE_LINE="$r" READLINE_POINT=${#r}
}
bind -x '"\C-j": ssage-insert'Enabling Sassy Mode
For a more entertaining experience, try sassy mode (GLaDOS-inspired):
ssage --mode sassy explain git rebaseContributing
ShellSage is built using nbdev. For detailed contribution guidelines, please see our CONTRIBUTING.md file.
We welcome contributions of all kinds:
- Bug reports
- Feature requests
- Documentation improvements
- Code contributions
Please visit our GitHub repository to get started.