Claude Tmux Hop
Quickly hop between Claude Code sessions running in tmux panes.
Features
- Priority-based cycling: Jump to panes waiting for input first, then idle, then active
- Jump-back: Return to previous pane across sessions/windows with Alt+Space
- Auto-hop: Optionally auto-switch to panes when they need attention
- System notifications: Display OS notification when panes need attention (macOS/Linux/Windows)
- Terminal focus: Automatically bring terminal to foreground when panes need attention (macOS/Linux/Windows)
- Auto-registration: Claude Code hooks automatically track pane states
- Auto-discovery: Existing Claude Code sessions are detected on plugin load
- In-memory state: Uses tmux pane options - no files, auto-cleanup when panes close
- Cross-session navigation: Works across all tmux sessions
- Status bar integration: Show pane counts with customizable icons
- Popup picker: Interactive fzf-based picker with time-in-state display (requires fzf)
Requirements
- uv (for
uvxcommand) - tmux 3.0+
- Python 3.10+
- Claude Code
Installation
1. Install Claude Code Plugin
claude plugin marketplace add unsafe9/claude-tmux-hop
claude plugin install claude-tmux-hop
2. Install Tmux Plugin (via TPM)
Add to ~/.tmux.conf:
set -g @plugin 'unsafe9/claude-tmux-hop'
Then press prefix + I to install.
That's it! The CLI runs via uvx automatically - no manual Python installation needed.
Any existing Claude Code sessions will be automatically discovered and registered as idle on plugin load.
Usage
Key Bindings
| Key | Action |
|---|---|
prefix + Space |
Cycle to next Claude Code pane |
prefix + C-Space |
Open picker menu |
Alt + Space |
Jump back to previous pane (no prefix) |
Configuration
Add to ~/.tmux.conf:
# Customize cycle key (default: Space)
set -g @hop-cycle-key 'Space'
# Customize picker key (default: C-Space)
set -g @hop-picker-key 'C-Space'
# Customize back key (default: M-Space, root binding - no prefix)
set -g @hop-back-key 'M-Space'
# Cycle mode (default: priority)
# - priority: cycle within highest-priority group only
# - flat: cycle through all panes in priority order
set -g @hop-cycle-mode 'priority'
# Auto-hop: automatically switch to panes when they enter specific states
# Disabled by default. Set to comma-separated states to enable.
set -g @hop-auto 'waiting' # Auto-switch when a pane needs input
# set -g @hop-auto 'waiting,idle' # Also switch when tasks complete
# Priority-only mode (default: on)
# Only auto-hop if no other pane has equal or higher priority
set -g @hop-auto-priority-only 'on' # Don't hop if another pane is already waiting
# set -g @hop-auto-priority-only 'off' # Always hop regardless of other panes
# System notification: display OS notification when pane state changes
# Disabled by default. Set to comma-separated states to enable.
set -g @hop-notify 'waiting' # Notify when a pane needs input
# set -g @hop-notify 'waiting,idle' # Also notify when tasks complete
# Terminal focus: bring terminal app to foreground when pane state changes
# Disabled by default. Set to comma-separated states to enable.
set -g @hop-focus-app 'waiting' # Focus terminal when a pane needs input
# Terminal app override (auto-detected from TERM_PROGRAM by default)
# set -g @hop-terminal-app 'iTerm' # Explicitly set terminal app name
# Note: On macOS, iTerm2 and Terminal.app will focus the specific tab/window
# containing the tmux session, not just bring the app to foreground.
# Status bar integration - show pane counts in status bar
set -g status-right '#{E:@hop-status} | %H:%M'
# Status format (default: "{waiting:} {idle:}")
# Syntax: {state:icon} shows "icon count" when count > 0
set -g @hop-status-format '{waiting:} {idle:} {active:}' # Include active
# set -g @hop-status-format '{waiting:W} {idle:I} {active:A}' # ASCII icons
CLI Commands
# List all Claude Code panes
uvx claude-tmux-hop list
# Cycle to next pane (usually via keybinding)
uvx claude-tmux-hop cycle
# Jump back to previous pane (cross-session/window)
uvx claude-tmux-hop back
# Show picker menu (fzf popup if available, else display-menu)
uvx claude-tmux-hop picker
uvx claude-tmux-hop picker --menu # Force display-menu style
# Discover existing Claude Code sessions (runs automatically on plugin load)
uvx claude-tmux-hop discover
# Remove stale state from panes no longer running Claude Code
uvx claude-tmux-hop prune
# Output status for tmux status bar
uvx claude-tmux-hop status
How It Works
Pane States
| State | Trigger | Priority |
|---|---|---|
waiting |
User input required | Highest |
idle |
Task complete | Medium |
active |
Working | Lowest |
Cycling Behavior
Controlled by @hop-cycle-mode (default: priority):
Priority mode (set -g @hop-cycle-mode 'priority'):
- If waiting panes exist, cycle only through waiting panes (oldest first)
- If no waiting, cycle through idle panes (newest first)
- If no idle, cycle through active panes (newest first)
Flat mode (set -g @hop-cycle-mode 'flat'):
- Cycle through all panes in priority order (waiting → idle → active)
- Within each priority level, sorted by timestamp
State Storage
State is stored directly on tmux panes using custom options:
@hop-state: Current state (waiting/idle/active)@hop-timestamp: Unix timestamp of last state change
Benefits:
- No external files
- State auto-deleted when pane closes
- Fast (in-memory)
Notifications & Focus
Overview
Two complementary features help you stay aware of Claude Code activity:
| Feature | Option | Behavior |
|---|---|---|
| System Notification | @hop-notify |
Shows OS notification (toast) |
| Terminal Focus | @hop-focus-app |
Brings terminal to foreground and navigates to pane |
Smart Notification Suppression
Notifications are automatically suppressed when you're already looking at the terminal:
- Checks if terminal app is the frontmost application
- On macOS iTerm2/Terminal.app: also checks if the correct tab/window is focused
- If already focused → no notification (avoids redundant alerts)
This prevents notification spam when you're actively working in the terminal.
Auto-Focus Navigation
When @hop-focus-app is enabled, it performs full navigation:
Terminal App → Tab/Window → tmux Session → tmux Window → tmux Pane
| Platform | App Focus | Tab Focus | tmux Navigation |
|---|---|---|---|
| macOS | ✅ AppleScript | ✅ iTerm2, Terminal.app | ✅ |
| Linux | ✅ wmctrl/xdotool | ❌ | ✅ |
| Windows | ✅ PowerShell COM | ❌ | ✅ |
Click-to-Focus Notifications (macOS)
When @hop-focus-app is disabled but @hop-notify is enabled, clicking the notification can navigate to the pane.
Requires optional dependency:
brew install terminal-notifier
| terminal-notifier | Notification | Click Action |
|---|---|---|
| Not installed | ✅ Shows | ❌ Does nothing |
| Installed | ✅ Shows | ✅ Navigates to pane |
Without terminal-notifier, notifications still work - you just can't click them to navigate.
Platform Support
macOS (Full Support)
- Notifications: Native via AppleScript
display notification - Focus Detection: AppleScript queries frontmost app and iTerm2/Terminal.app tabs
- App Focus: AppleScript
activatecommand - Tab Focus: AppleScript searches iTerm2 sessions / Terminal.app windows by tmux session name
- Click-to-Focus: Optional via
terminal-notifier
Linux (X11)
- Notifications:
notify-send(libnotify) - Focus Detection:
xdotool getactivewindow(X11 only, not Wayland) - App/Window Focus:
wmctrlorxdotool - Click-to-Focus: Not supported (would require D-Bus complexity)
Windows
- Notifications: PowerShell Toast Notifications (Windows 10+)
- Focus Detection: PowerShell with Win32
GetForegroundWindow - App Focus: PowerShell
WScript.Shell.AppActivate - Click-to-Focus: Not supported (would require protocol handler)
Recommended Configuration
Option A: Just notifications (minimal)
set -g @hop-notify 'waiting' # Alert when input needed
Option B: Auto-focus (recommended)
set -g @hop-focus-app 'waiting' # Auto-navigate when input needed
Option C: Both (belt and suspenders)
set -g @hop-notify 'waiting' # Alert if not focused
set -g @hop-focus-app 'waiting' # Also auto-navigate
# Notification is suppressed when focus succeeds, so no duplicate alerts
Terminal App Detection
The terminal app is auto-detected from environment variables:
| Priority | Source | Example |
|---|---|---|
| 1 | @hop-terminal-app option |
User override |
| 2 | __CFBundleIdentifier (macOS) |
com.googlecode.iterm2 → iTerm |
| 3 | WT_SESSION (Windows) |
Windows Terminal |
| 4 | TERM_PROGRAM |
vscode, Alacritty, etc. |
Supported terminals include:
- macOS: Terminal.app, iTerm2, Alacritty, kitty, WezTerm, Ghostty, Hyper
- IDEs: VS Code, Cursor, Windsurf, Zed, Antigravity, all JetBrains IDEs
- Linux: gnome-terminal, Konsole, Alacritty, kitty, Tilix, Terminator
- Windows: Windows Terminal, ConEmu, Cmder
License
MIT
Metadata
Release files for claude-tmux-hop 0.2.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| claude_tmux_hop-0.2.5.tar.gz | 31.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| claude_tmux_hop-0.2.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 72.8 kB
Release files / claude_tmux_hop-0.2.5.tar.gz
| Download URL | claude_tmux_hop-0.2.5.tar.gz |
|---|---|
| Size | 31.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9f57af2d29e26d4f036181d40200ffb9b0615fd11b5025eddea41b092e493f9b
|
|
BLAKE2b-256 checksum How to use checksums |
86e0c75b6e046344b02d0ed10289087d35f241e5d72368e4c83a98a6264b1522
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / claude_tmux_hop-0.2.5-py3-none-any.whl
| Download URL | claude_tmux_hop-0.2.5-py3-none-any.whl |
|---|---|
| Size | 40.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2d0a0b5b523d96342a4dc1bf835df0704e8c84708470dcb44652600a0e088fe7
|
|
BLAKE2b-256 checksum How to use checksums |
b5d072c6a6c5612f349bca615ba3c8e7149fede7d7abcc7119d47899726a6b62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|