tmux-manager
Manages tmux sessions from a YAML config file. The script and its default config live together — the script always looks for tmux-sessions.yaml in the same directory as itself.
Script: {baseDir}/scripts/tmux-manager.py
Default config: {baseDir}/scripts/tmux-sessions.yaml
Sample config: {baseDir}/scripts/tmux-sessions.yaml.sample
To deploy: copy tmux-manager.py to any directory, place a tmux-sessions.yaml next to it, and run it with uv run from anywhere.
Usage
uv run {baseDir}/scripts/tmux-manager.py (--all | -s SESSION [...] | --session-group GROUP [...] [--window-group GROUP [...]] | --window-group GROUP [...]) [--kill | --restart] [--dry-run] [--list] [--config FILE]
uv run {baseDir}/scripts/tmux-manager.py --send-keys -s SESSION[:WINDOW] COMMAND
uv run {baseDir}/scripts/tmux-manager.py --tail -s SESSION[:WINDOW]
uv run {baseDir}/scripts/tmux-manager.py --validate [--config FILE]
uv run {baseDir}/scripts/tmux-manager.py --list-groups [--config FILE]
Flags
Selectors
| Flag | Meaning |
|---|
--all | Target every session in the config |
--session-group GROUP | Target sessions by session_group (repeatable, comma-separated) — all windows created |
--window-group GROUP | Filter to only matching windows (repeatable, comma-separated) — can be combined with --session-group |
-s SESSION | Target a specific session by name (repeatable) |
--all and -s are mutually exclusive with everything else. --session-group and --window-group can be used together to scope both sessions and windows.
Actions — default is create
| Flag | Meaning |
|---|
| (no action flag) | Create targeted sessions; skip ones already running |
--kill | Kill targeted sessions |
--restart | Kill then recreate targeted sessions |
--list | Show status table (running/stopped) — no changes made |
--dry-run | Preview what would happen — no changes made |
Output / Inspection
| Flag | Meaning |
|---|
--tail -s SESSION[:WINDOW] | Stream live pane output (Ctrl+C to stop) |
Send Commands
| Flag | Meaning |
|---|
--send-keys -s SESSION[:WINDOW] "cmd" | Send a shell command to a running session or specific window |
Config & Validation
| Flag | Meaning |
|---|
--config FILE | Use an alternative config file |
--validate | Check config for errors and warnings (no selector needed) |
--list-groups | List all session groups and window groups (no selector needed) |
Examples
uv run {baseDir}/scripts/tmux-manager.py --all # create all sessions
uv run {baseDir}/scripts/tmux-manager.py --all --kill # kill all sessions in config
uv run {baseDir}/scripts/tmux-manager.py --all --restart # restart all sessions
uv run {baseDir}/scripts/tmux-manager.py --all --dry-run # preview what would be created
uv run {baseDir}/scripts/tmux-manager.py --all --list # list status of all sessions
uv run {baseDir}/scripts/tmux-manager.py --session-group work # create sessions in session-group 'work'
uv run {baseDir}/scripts/tmux-manager.py --session-group work --restart # restart sessions in session-group 'work'
uv run {baseDir}/scripts/tmux-manager.py --session-group work --list # list status of sessions in session-group 'work'
uv run {baseDir}/scripts/tmux-manager.py --kill --session-group work # kill all sessions in session-group 'work'
uv run {baseDir}/scripts/tmux-manager.py --window-group dev # create sessions, only 'dev' windows
uv run {baseDir}/scripts/tmux-manager.py --window-group dev --restart # restart with only 'dev' windows
uv run {baseDir}/scripts/tmux-manager.py --window-group claude,gemini # multiple groups, comma-separated
uv run {baseDir}/scripts/tmux-manager.py --window-group claude --window-group gemini # equivalent
uv run {baseDir}/scripts/tmux-manager.py --session-group TargetTracer,N8N --window-group claude,gemini # combined
uv run {baseDir}/scripts/tmux-manager.py -s my-session # create only my-session
uv run {baseDir}/scripts/tmux-manager.py --kill -s my-session # kill only my-session
uv run {baseDir}/scripts/tmux-manager.py --restart -s my-session # restart only my-session
uv run {baseDir}/scripts/tmux-manager.py --send-keys -s my-session "cmd" # send to active window
uv run {baseDir}/scripts/tmux-manager.py --send-keys -s my-session:claude "cmd" # send to specific window
uv run {baseDir}/scripts/tmux-manager.py --tail -s my-session # stream live pane output
uv run {baseDir}/scripts/tmux-manager.py --validate # validate config file
uv run {baseDir}/scripts/tmux-manager.py --list-groups # list all groups
uv run {baseDir}/scripts/tmux-manager.py --all --config ~/my-sessions.yaml # use a specific config
Behaviour Notes
- Idempotent creates — sessions already running are skipped. Use
--restart to force recreate.
--kill requires a selector — use --all --kill to kill everything managed by this config.
--tail / --send-keys accept only a single -s SESSION[:WINDOW] target.
SESSION[:WINDOW] — append :windowname to target a specific window, e.g. my-session:claude. Without it, the active window is used.
--validate does not require a selector — warns on unknown fields, catching typos like window_grou or sesion_group.
--list-groups does not require a selector — reads config only.
pre_hook / post_hook run on the host shell, not inside tmux.
pre_hook_fail: abort — stops session creation if the pre_hook exits non-zero. Default is warn (prints warning, continues).
--window-group — sessions already running are skipped unless --restart is used. On restart, only the matching windows are created.
--session-group + --window-group combined — narrows to the specified sessions first, then opens only the matching windows within them.
- Sessions without a
session_group are only reachable via --all or -s.
Native tmux equivalents
These operations don't need a wrapper — use tmux directly:
| Operation | Native command |
|---|
| Kill all tmux sessions | tmux kill-server |
| Snapshot pane output | tmux capture-pane -p -t SESSION[:WINDOW] |
Sample Config (tmux-sessions.yaml.sample)
sessions:
# ── Project session (no env vars) ─────────────────────────────────────────
- name: Project_1
session_group: Project_1
working_dir: ~/Projects/Project_1
# focus: claude # which window to select after creation (optional)
windows:
- name: claude
window_group: claude # targeted by: --window-group claude
command: "claude --dangerously-skip-permissions --continue"
- name: gemini
window_group: gemini # targeted by: --window-group gemini
command: "gemini -y --resume"
- name: shell # no window_group — only opened via --session-group or --all
# no command = opens a plain shell
# ── Project session (with env vars) ───────────────────────────────────────
- name: Project_2
session_group: Project_2
working_dir: ~/Projects/Project_2
env:
NODE_ENV: development
PORT: 3000
windows:
#- name: server # uncomment to add a dev server window
# command: "npm run dev"
- name: claude
window_group: claude
command: "claude --dangerously-skip-permissions --continue"
- name: gemini
window_group: gemini
command: "gemini -y --resume"
- name: shell
window_group: shell
# no command = opens a plain shell
# ── Single-window utility session ─────────────────────────────────────────
- name: monitoring
session_group: system
working_dir: ~
command: "htop"
Full Config Reference
| Field | Level | Description |
|---|
name | session | Required. Must be unique. |
session_group | session | Optional. String or list. Used with --session-group — targets the whole session. A session can belong to multiple groups. |
working_dir | session / window | Starting directory. Window value overrides session. |
focus | session | Window name to select after creation. |
pre_hook | session | Shell command run before session is created. |
pre_hook_fail | session | warn (default) or abort — whether a failed pre_hook stops session creation. |
post_hook | session | Shell command run after session is created. |
env | session / window | Map of env vars. Window env sent as export statements. |
command | session / window | Program to run. On session level, creates a single-window session. |
windows | session | List of windows. Overrides session-level command. |
window_group | window | Optional. String or list. Used with --window-group — only matching windows are created. A window can belong to multiple groups. |
panes | window | List of panes to split the window into. Each can have command and working_dir. |
layout | window | Pane layout: tiled, even-horizontal, even-vertical, main-horizontal, main-vertical. |