#tmux-session-manager #tmux #worktree #cli

app sessionx

A simple tmux session manager with optional git-worktree mode and per-project status bars

11 releases

new 0.1.11 May 12, 2026
0.1.10 May 7, 2026

#106 in Command line utilities

MIT license

195KB
5K SLoC

sessionx

CI crates.io downloads License: MIT MSRV

A small tmux session manager. Sits between tmuxp and workmux — declarative YAML, optional git-worktree mode, pre/post hooks, and per-project tmux status bars.

Status: Active — pre-1.0. APIs and config keys may change between minor releases; see CHANGELOG.md.

Requirements

  • tmux 3.0+ — brew install tmux
  • git 2.5+ (only needed for worktree mode) — brew install git
  • bash (for hook execution) — present on macOS by default

Install

Homebrew (macOS / Linux)

brew install jeromecoloma/sessionx/sessionx

Tap repo: jeromecoloma/homebrew-sessionx.

From crates.io

cargo install sessionx --locked
export PATH="$HOME/.cargo/bin:$PATH"   # if not already

Needs a Rust toolchain (stable, 1.75+). Install via rustup if you don't have one.

Prebuilt binaries

Grab a tarball for your platform from the GitHub Releases page (macOS arm64/x86_64, Linux arm64/x86_64). Each tarball ships with a .sha256 sidecar — verify with shasum -a 256 -c sessionx-vX.Y.Z-<target>.tar.gz.sha256.

From source

git clone https://github.com/jeromecoloma/sessionx
cd sessionx
./install.sh             # interactive — builds, asks about completions
./install.sh --yes       # non-interactive (uses your $SHELL)
./install.sh --no-completions
./install.sh --completions-only --shell zsh

Or manually with cargo install --path .. Building from source needs a Rust toolchain (stable, 1.75+).

Quick start

cd my-project
sessionx init                  # interactive wizard (or --yes for non-interactive)
sessionx add work              # creates session "<project>-work" and attaches
sessionx ls
sessionx rm work

No-arg interactive picker

Run sessionx with no subcommand to get a context-aware menu:

  • Attach/create project session — when .sessionx.yaml is found
  • Init .sessionx.yaml here — when in a git repo without a config
  • Open managed session — any sessionx-managed session, across projects
  • Clean up orphan worktree — leftover worktrees from a failed teardown (current project only)
  • New plain tmux session — auto-named, untracked

The picker uses fzf when installed, otherwise falls back to a built-in TUI. The installer offers to install fzf via Homebrew on macOS.

From any directory, attach to any sessionx-managed session globally:

sessionx ls --all              # list every managed session, across projects
sessionx open <TAB>            # complete full session names
sessionx open my-project-work  # attach (or switch-client if already in tmux)

Modes

  • plain (default): sessionx add <name> spawns a tmux session in the project directory.
  • worktree: set worktree_dir: in .sessionx.yaml and add will also create a git worktree + branch named <name>. rm tears it down.

Status bar

The headline feature. status: in .sessionx.yaml is applied scoped to the spawned session only — other tmux sessions are untouched.

Themes

Pick a preset or roll your own. Built-in themes:

tokyo-night, catppuccin, dracula, gruvbox, nord, rose-pine, minimal

status:
  theme: tokyo-night

Themes ship with sensible defaults for status colors, the left/right segments (host badge + prefix-aware session label + date/time), window list format, and refresh interval. The prefix-aware session label flips its icon when you press your tmux prefix (e.g. Ctrl+a), mirroring the behavior in the screenshot.

Manual overrides

Anything you set under status: overrides the theme. You can mix — pick a theme for colors, then customize the right side:

status:
  theme: tokyo-night
  right: " #(~/.sessionx/segments/clock.sh) | %m-%d %H:%M "
  segments:
    - name: clock
      command: "date +%H:%M:%S"
  status_interval: 1

Or skip themes entirely and define everything yourself:

status:
  style:
    status_style: "bg=#1e1e2e,fg=#cdd6f4"
    window_status_current_style: "bg=#89b4fa,fg=#1e1e2e,bold"
  left: " #S "
  right: " #(~/.sessionx/segments/clock.sh) "

Style keys map 1:1 to tmux options — status_style becomes status-style, etc.

Custom segments are materialized into ~/.sessionx/segments/<name>.sh and refreshed by tmux's built-in #(...) polling every status_interval seconds. No daemon.

Hooks

post_create runs after the worktree (or in the project root, plain mode) and before tmux launches. pre_remove runs before teardown. Both receive these env vars:

Var Always
SX_PROJECT_ROOT, SX_HANDLE, SX_SESSION_NAME yes
SX_WORKTREE_PATH, SX_BRANCH_NAME worktree mode
SX_ICON_<NAME> from status.icons

These mirror workmux's WM_* vars — porting an existing workmux script is mostly sed s/WM_/SX_/.

Agent placeholder

Pane commands may use <agent> as a placeholder for your AI CLI of choice. It's substituted at session-build time. Resolution order:

  1. SX_AGENT env var (e.g. SX_AGENT=codex sessionx add foo).
  2. agent: field in ~/.config/sessionx/config.yaml:
    agent: claude    # or codex, aider, gh-copilot, etc.
    
  3. Fallback: exec $SHELL. sessionx does not pick an agent for you — if nothing is configured, the agent window opens a plain shell. Configure one explicitly via sessionx init --force (interactive picker) or by editing ~/.config/sessionx/config.yaml.

The default .sessionx.yaml template ships an agent window with command: <agent> so once you set the global agent: value, every fresh session drops you straight into your AI CLI.

Commands

Command What it does
sessionx init Write a starter .sessionx.yaml. Interactive when run on a TTY: prompts for mode, worktree, theme, project-aware layout (Rust/Node/PHP/Python detection), and an optional hook recipe from sessionx-hooks. Non-interactive flags: --yes, --force, --theme <name>, --mode session|window, --worktree <dir>. Falls back to the static template under non-TTY (CI/pipes).
sessionx hooks [list|info|install|update|repo] [<id>] Manage stack-specific hook recipes from the sessionx-hooks repo. list shows what's available; install <id> drops scripts into ~/.sessionx/scripts/<id>/. sessionx init calls install for you when you opt into a recipe. Override the source with SX_HOOKS_REPO / SX_HOOKS_REF.
sessionx config [path|get|set <k> <v>] Manage the global config (~/.config/sessionx/config.yaml). No args opens it in $VISUAL/$EDITOR (creates a starter file if missing). path prints the file location; get [agent] reads; set agent <name> writes.
sessionx edit Open .sessionx.yaml in $VISUAL/$EDITOR.
sessionx add <name> [--base <ref>] [--no-attach] Create + attach.
sessionx ls [--all] [--names-only] List sessions for this project; --all lists every managed session globally.
sessionx open [<session>] Attach to any sessionx-managed session globally. No arg prints the list. Works from any cwd.
sessionx rm <name> [--force] Tear down. Accepts a handle or full session name; recovers leftover worktrees if a previous run failed mid-teardown.
sessionx themes List built-in status-bar themes (one per line).
sessionx theme Show current theme + available themes (current marked *).
sessionx theme set <name> [--no-apply] [--session <s>] Rewrite status.theme: in .sessionx.yaml and live-apply to current tmux session.
sessionx theme preview <name> [--session <s>] Apply a theme to a running session without editing the YAML.
sessionx completions <bash|zsh|fish> Print completion script.

Add -v to any command to see the underlying tmux/git calls.

Shell completions

# zsh — write to a dir on $fpath
sessionx completions zsh > "${fpath[1]}/_sessionx"

# bash
sessionx completions bash > /usr/local/etc/bash_completion.d/sessionx

# fish
sessionx completions fish > ~/.config/fish/completions/sessionx.fish

Supported shells: bash, zsh, fish. Completions are dynamic — rm <TAB> lists handles in the current project, open <TAB> lists every managed session globally.

Shell helpers (sxl / sxa / sxk)

Short shell wrappers for the most common sessionx commands. With no arg, sxa/sxk open an fzf picker over every managed session globally; with an arg they pass straight through.

# zsh / bash — works with `cargo install sessionx` (no repo needed)
eval "$(sessionx shell-init zsh)"     # or `bash`

# fish
sessionx shell-init fish | source

If you cloned the repo you can also source the file directly:

source /path/to/sessionx/shell/sessionx-helpers.sh     # zsh / bash
source /path/to/sessionx/shell/sessionx-helpers.fish   # fish
Helper Equivalent
sx [args...] sessionx (plain shortcut)
sxl [flags] sessionx ls --all (passes flags through, e.g. sxl --names-only)
sxa [name] sessionx open <name> (fzf picker if no arg)
sxk [name [--force]] sessionx rm <name> (fzf picker if no arg)

install.sh will offer to source the helpers into your shell rc.

Getting help

Contributing

PRs welcome. Read CONTRIBUTING.md before opening a non-trivial PR — scope is intentionally narrow. By participating you agree to the Code of Conduct.

License

MIT © Jerome Coloma

Dependencies

~7–13MB
~254K SLoC