Hop between Claude Code sessions in tmux panes
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_tmux_hop-0.2.3.tar.gz.
File metadata
- Download URL: claude_tmux_hop-0.2.3.tar.gz
- Upload date:
- Size: 31.5 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
159dc210a801ccadf842d04e43d7c58e02e0f1dcde05e521fb5d396c6dde7abc
|
|
| MD5 |
64f1b64e15a2e7d6ec3e2c9426ed0d46
|
|
| BLAKE2b-256 |
21c0918ae9fb26fd53bb389f4a2607fc71dc59340b1f5ebe1749e3d96da2ef3e
|
File details
Details for the file claude_tmux_hop-0.2.3-py3-none-any.whl.
File metadata
- Download URL: claude_tmux_hop-0.2.3-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e40f2140367003776ceb672f78676bdf2d982f603f3029a1b6ef75d0893551a8
|
|
| MD5 |
3c67df0cfcdb5398dca7a0ff92f4b55b
|
|
| BLAKE2b-256 |
893966681d49ef3ca9cc8f14bbcf52333a406b17df3f4705204125598192c7e9
|