A tmux plugin that provides floating popup-based access to Claude LLM with dedicated command and Q&A modes. Features real-time streaming responses, persistent conversation history, and seamless integration with your tmux workflow.
-
🚀 Dual-Mode Operation:
-
🎯 Separate Sessions: Independent conversation contexts for command and ask modes
-
📡 Real-Time Streaming: See Claude's response as it's generated (no buffering)
-
💾 Persistent History: Per-pane conversation memory that survives popup toggles
-
⌨️ Smart Command Injection: Commands automatically sent to your active pane
-
📋 Clipboard Integration: Copy responses with a single key press
-
🎨 Enhanced UI: Optional
gumandglowsupport for beautiful formatting -
🔧 Special Commands:
/ror/reset: Clear conversation history/hor/history: View previous queries
-
⚙️ Configurable: Custom key bindings and model selection
-
🔒 Secure: API key via environment variable or tmux option
Inspired by tmux-floax - Popup toggle pattern adapted from floax's elegant session management approach.
- tmux 3.0 or higher (for
display-popupsupport) curlcommand-line tooljqfor JSON processing- Claude API key from Anthropic
- Optional but recommended:
gumfor enhanced UI andglowfor markdown rendering
- Clone or download this repository:
cd ~/.tmux/plugins
git clone <your-repo-url> tmux-llm-assistant
# OR if you have it locally:
cp -r /path/to/tmux-llm-assistant ~/.tmux/plugins/- Make scripts executable:
chmod +x ~/.tmux/plugins/tmux-llm-assistant/llm-assistant.tmux
chmod +x ~/.tmux/plugins/tmux-llm-assistant/scripts/*.sh- Add to your
~/.tmux.conf:
# Load the plugin
run-shell ~/.tmux/plugins/tmux-llm-assistant/llm-assistant.tmux- Reload tmux configuration:
tmux source-file ~/.tmux.confIf you use TPM, add this to your ~/.tmux.conf:
set -g @plugin 'your-username/tmux-llm-assistant'Then press prefix + I to install.
Option A: Environment Variable (Recommended)
export CLAUDE_API_KEY="your-api-key-here"Add this to your ~/.bashrc, ~/.zshrc, or shell profile to make it persistent.
Option B: Tmux Option
tmux set-option -g @llm-assistant-api-key "your-api-key-here"Add this to your ~/.tmux.conf to make it persistent.
Default key binding is prefix + l (normal) and prefix + L (zoom). To change it:
tmux set-option -g @llm-assistant-key "a" # Use prefix + a (normal) and prefix + A (zoom)Add to ~/.tmux.conf to make it persistent.
Default model is claude-opus-4-5-20251101. To use a different model:
tmux set-option -g @llm-assistant-model "claude-opus-4-5-20251101"The plugin provides two independent interaction modes, each with its own session and conversation history:
- Small popup at bottom (15% height)
- Optimized for quick shell commands
- Responses automatically sent to your active pane
- Session:
llm-cmd-<pane_id>
Example:
> find all files modified in the last 7 days
Output: find . -mtime -7 (automatically injected into your pane)
- Larger centered popup (70% height)
- Perfect for Q&A and explanations
- Markdown-formatted responses
- Session:
llm-ask-<pane_id>
Example:
> what is the difference between git merge and git rebase?
Output: Detailed explanation with formatting
Press the same key to open/close the popup:
- First press: Opens popup with new or existing session
- Second press (inside popup): Closes popup (session persists)
- Third press: Reopens popup with conversation history intact
Benefits:
- ✅ Real-time streaming - See responses as they're generated
- ✅ Persistent sessions - Conversation context preserved across toggles
- ✅ Per-pane isolation - Each pane gets its own command and ask sessions
- ✅ Full tmux features - Scrollback, copy mode, search all work perfectly
Available in both modes:
/ror/reset: Clear conversation history for current mode/hor/history: View all previous queries in current session
Type these at the input prompt to use them.
After Claude responds, you'll see an interactive viewer using less pager:
Navigation in the response viewer:
- Use arrow keys, Page Up/Down, or vim keys (
j/k,Space/b) to scroll through the response - The response is displayed with markdown formatting (if
glowis installed) or plain text
Action keys (shown at bottom of viewer):
- [Enter]: Execute/send the response to your pane (command mode only)
- [c]: Copy response to clipboard
- [q]: Go back to input stage to ask another question
- [Esc]: Exit the popup completely
Independent History per Mode:
- Each mode (command/ask) maintains its own conversation history
- Command mode:
/tmp/llm_history_<pane_id>.json - Ask mode: Separate history file per session
- History persists across popup toggles - context is preserved
- Use
/rto reset history,/hto view past queries - [q] key in response viewer goes back to input while preserving history
Workflow:
- Open popup (
prefix + lorprefix + L) - Ask questions, see streaming responses
- Close popup anytime (press key again or
Ctrl+C) - Do other work...
- Reopen same popup - conversation history intact
- Ask follow-up questions referencing previous context
After Claude responds:
- [Enter]: Execute/send response (command mode) or dismiss (ask mode)
- [c]: Copy response to clipboard
- [q]: Back to input (preserves history)
- [r]: Reset conversation history
- [Esc]: Exit popup completely
- Press the bound key again (inside popup) to close
Ctrl+CorEscto force exit- Leave input empty and press Enter to exit
> find all files modified in the last 7 days
> show disk usage sorted by size
> kill all processes using port 8080
> create a tar archive of the logs directory
> explain what this bash script does: [paste your code]
> what is the difference between git merge and git rebase?
> how do I optimize Docker build times?
> explain the tmux copy mode workflow
- Make sure you've set the API key using one of the methods above
- Verify the key is accessible:
echo $CLAUDE_API_KEY - Check tmux option:
tmux show-option -gqv "@llm-assistant-api-key"
- Check your internet connection
- Verify curl is working:
curl -I https://api.anthropic.com - Check firewall/proxy settings
- HTTP 401: Invalid API key - verify your key is correct
- HTTP 429: Rate limit exceeded - wait and try again
- HTTP 400: Invalid request - check if model name is correct
- Check Claude API status: https://status.anthropic.com/
- Verify your API key has the correct permissions and credits
- Ensure you're using tmux 3.0+
- Verify the plugin is loaded:
tmux list-keys | grep llm - Check that scripts are executable:
chmod +x scripts/*.sh
- Check if the target pane is still active
- Note: Only command mode responses are sent to the pane automatically
- Install
jq:brew install jq(macOS) orapt-get install jq(Linux)
- Install
gumfor better UI:brew install gum(macOS) or see gum installation - Install
glowfor markdown rendering:brew install glow(macOS) or see glow installation - The plugin works without these, but with a simpler interface
tmux-llm-assistant/
├── llm-assistant.tmux # Main plugin file
├── scripts/
│ ├── llm-popup.sh # Popup handler script
│ └── claude-api.sh # Claude API integration
└── README.md
- Never commit your API key to version control
- Use environment variables for API keys (recommended)
- API keys passed via tmux session environment (not visible in
ps) - All temporary files have 600 permissions (owner read/write only)
✅ API Key Protection
- API key passed via tmux session environment (not command args)
- Not visible in process list (
psoutput) - Simple and secure - uses tmux's
-eflag
✅ File Security
- All temp files created with 600 permissions (owner only)
- History files protected from other users
- Marker files have restricted access
- Automatic cleanup on exit via trap handlers
- Conversation history stored unencrypted in
/tmp/ - History persists across sessions (by design for continuity)
- Use
/rcommand to clear sensitive conversations - Consider manual cleanup:
rm /tmp/llm_history_*if needed
The plugin automatically detects and uses the best available clipboard method:
pbcopy(macOS)xcliporxsel(Linux)- tmux buffer (fallback)
Command mode automatically strips markdown code blocks and extra formatting from Claude's responses, ensuring clean commands ready for execution.
Each pane maintains independent command and ask sessions:
llm-cmd-%0,llm-ask-%0for pane%0llm-cmd-%1,llm-ask-%1for pane%1- etc.
This allows different workflows in different panes without context mixing.
- tmux-floax - Inspired the popup toggle pattern and session management approach
- Anthropic Claude - Powering the LLM interactions
- charm.sh -
gumandglowfor beautiful terminal UI
MIT License - feel free to modify and distribute.
Contributions welcome! Please feel free to submit a Pull Request.
Note: This project was fully vibe coded. 🎨

