by craftzdog
Run many Claude Code sessions across your projects, each in its own tmux session — then list them, see which are done vs. still working, and jump to one from a single popup.
# Add to your Claude Code skills
git clone https://github.com/craftzdog/tmux-claude-session-managerGuides for using ai agents skills like tmux-claude-session-manager.
Last scanned: 6/22/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-06-22T09:49:11.309Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}tmux-claude-session-manager is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by craftzdog. Run many Claude Code sessions across your projects, each in its own tmux session — then list them, see which are done vs. still working, and jump to one from a single popup. It has 289 GitHub stars.
Yes. tmux-claude-session-manager passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/craftzdog/tmux-claude-session-manager" and add it to your Claude Code skills directory (see the Installation section above).
tmux-claude-session-manager is primarily written in Shell. It is open-source under craftzdog on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh tmux-claude-session-manager against similar tools.
No comments yet. Be the first to share your thoughts!
Run many Claude Code sessions across your projects, each in its own tmux session — then list them, see which are done vs. still working, and jump to one from a single popup.
If you launch Claude per-directory (one nested session per project), you quickly end up with a dozen of them and no way to tell which are finished without opening each one. This plugin gives you:
prefix + u) listing every running Claude agent —
several in one project, and any running loose in an ordinary pane.working / waiting / idle — read straight
from claude agents --json, so you instantly see which need you. No setup.prefix + y) that opens/attaches a Claude session for the
current directory.ctrl-x) of a finished agent from the picker.Status needs no configuration. Claude Code publishes each agent's own state and the picker reads it — there are no hooks to install.
display-popup)claude agents --jsonclaude agents command (claude --version to check)Add to ~/.tmux.conf (or ~/.config/tmux/tmux.conf):
set -g @plugin 'craftzdog/tmux-claude-session-manager'
Then hit prefix + I to install.
Keybinding note: by default the plugin binds
prefix+y(launch) andprefix+u(list). If your config binds those elsewhere, either change the options below, or make sure the plugin loads after your own bindings (putrun '~/.tmux/plugins/tpm/tpm'after them) so the one you want wins.
git clone https://github.com/craftzdog/tmux-claude-session-manager ~/clone/path
Add to ~/.tmux.conf, then reload (prefix + r or tmux source ~/.tmux.conf):
run-shell ~/clone/path/claude_session_manager.tmux
| Key | Action |
|---|---|
prefix + y |
Launch (or re-attach to) a Claude session for the current directory, in a popup |
prefix + u |
Open the agent picker |
Inside the picker:
| Key | Action |
|---|---|
enter |
Jump to the agent (see How it works) |
ctrl-x |
Kill the highlighted agent |
↑ / ↓, type to filter |
fzf navigation |
Agents needing your attention (waiting, idle) sort to the top.
Every running Claude gets its own row — the picker identifies each by its process, not by its tmux session. So several agents in one project all show up separately, as does a Claude you started by hand in an ordinary pane.
Set any of these before the plugin loads (defaults shown):
set -g @claude_launch_key 'y' # prefix key: launch/open for current dir
set -g @claude_list_key 'u' # prefix key: open the picker
set -g @claude_command 'claude' # command run in new sessions
set -g @claude_args '' # extra args appended to the command
set -g @claude_session_prefix 'claude-' # tmux session name prefix
set -g @claude_popup_width '90%' # popup width
set -g @claude_popup_height '90%' # popup height
set -g @claude_fzf_options '' # extra options passed to the fzf picker
For example, to skip permission prompts in launched sessions:
set -g @claude_args '--dangerously-skip-permissions'
@claude_fzf_options is passed straight to fzf, so you can add your own bindings.
Here is a vim keybinding example:
set -g @claude_fzf_options "\
--prompt 'nav> ' \
--bind 'j:down' \
--bind 'k:up' \
--bind 'q:abort' \
--bind 'x:execute-silent(kill {3})+reload(sleep 0.3; \$CLAUDE_PICKER --list)' \
--bind 'i:unbind(j,k,q,i,a,x)+change-prompt(filter> )' \
--bind 'a:unbind(j,k,q,i,a,x)+change-prompt(filter> )' \
--bind 'esc:rebind(j,k,q,i,a,x)+change-prompt(nav> )'"
The picker opens in nav mode:
| Key | Action |
|---|---|
j / k |
move down / up |
i / a |
switch to filter mode — type to fuzzy-match |
x |
kill the highlighted agent (like the built-in ctrl-x) |
q |
close the picker |
enter |
jump to the agent (both modes) |
esc |
filter mode → back to nav |
Only the bound keys are special in nav mode; any other key still filters as you
type. x reloads the list through $CLAUDE_PICKER, a path the picker exports for
exactly this — write it as \$CLAUDE_PICKER inside the double-quoted value above
so tmux stores a literal $ (in a single-quoted value, use a bare
$CLAUDE_PICKER).
claude-<hash-of-dir> tmux session running
claude, records the window it came from in @claude_origin, and attaches to
it in a popup.claude agents --json is the source of truth for what is running and how it
is doing. Each Claude session self-reports its state (busy / waiting /
idle) to a supervisor daemon, which that command publishes. Nothing here scans
processes for a claude command name — on macOS a pane reports its parent shell,
never the claude child running inside it.agents.sh pairs each running Claude with the tmux pane it occupies by
joining pid → tty → pane. That join is why identity is the Claude process
rather than the tmux session, and therefore why several agents in one project
each get their own row. It costs three subprocesses per render, whatever the
number of sessions or panes.claude agents --json reports only startedAt, never a last-activity
time. A brand-new agent that has yet to take a turn shows -.capture-pane preview. On enter
a dedicated agent (in a claude-* session) resumes in the popup over the
window it was launched from, while a loose one (any other pane) is focused in
place. ctrl-x kills the Claude process itself: a dedicated session dies with
its last window, and a loose pane keeps the shell that hosted it.prefix + u from inside a session popup detaches that popup
first (closing it), then reopens the picker full-size on the outer host client —
so you never end up with a cramped popup-in-popup.MIT © Takuya Matsuyama