projmux
Project-aware tmux workspace management for people who live in terminals.
projmux turns project directories into durable tmux workspaces with previews,
sidebar navigation, generated keybindings, status metadata, and AI-pane
attention signals. It can run as its own tmux app (projmux shell) or install
the same behavior into your existing tmux server.
한국어 README
Why projmux
Most tmux project switchers stop at "pick a directory and attach a session".
projmux treats that as the foundation, then adds the app-level pieces needed
for a daily terminal workspace:
- Project identity stays stable. Directories, pins, live sessions, preview
selection, and lifecycle commands all use the same normalized session model.
- The UI shows context before you switch. Popup and sidebar pickers preview
sessions, windows, panes, git branch, Kubernetes context, and pane metadata.
- The tmux layer is generated, not hand-spliced.
projmux writes the tmux
config it needs for popup launchers, window/pane rename flows, status
segments, pane borders, attention badges, and app mode.
- AI panes are first-class. Codex and Claude panes can be launched,
labeled, tracked as thinking or waiting, surfaced in pane/window/session
badges, and announced through desktop notifications.
- You can choose isolation or integration. Use
projmux shell as a
self-contained tmux app, or install the generated snippet into your normal
tmux server.
What It Does
- Creates or switches to tmux sessions from project directories.
- Shows existing sessions with window and pane previews.
- Provides popup and sidebar navigation surfaces backed by
fzf.
- Pins important projects and scans common source roots for new ones.
- Persists preview selection for fast window and pane cycling.
- Generates tmux bindings for launchers, rename prompts, pane borders, status
segments, and attention hooks.
- Displays git branch and Kubernetes context/namespace in the status area.
- Launches AI splits and keeps their agent name, topic, status, and
notification state visible in tmux.
Typical Workflow
projmux shell
Open the app once, then use its generated tmux bindings to:
- jump between projects from a sidebar or popup,
- inspect sessions before attaching,
- split Codex, Claude, or a plain shell into the current workspace,
- rename windows and AI pane topics without losing metadata,
- see which panes need review from badges and desktop notifications.
Requirements
- Go 1.24 or newer.
- tmux.
- fzf for interactive pickers.
- zsh for the generated isolated app config.
- git for branch/status metadata.
- kubectl is optional and only needed for Kubernetes status segments.
notify-send is used for desktop notifications on Linux unless
PROJMUX_NOTIFY_HOOK is set.
Install
With Go:
GOBIN="$HOME/.local/bin" go install github.com/es5h/projmux/cmd/projmux@latest
hash -r
By default, go install writes binaries to $(go env GOPATH)/bin. That may
install or update a different projmux than the one your shell finds first on
PATH. The command above installs directly to ~/.local/bin, which is the
recommended location if that directory is already on your PATH. hash -r
clears your shell's cached command lookup after an update.
Make sure ~/.local/bin is on your PATH:
export PATH="$HOME/.local/bin:$PATH"
As a fallback, add $(go env GOPATH)/bin to PATH instead, or copy the binary
from $(go env GOPATH)/bin/projmux to a directory that appears earlier on
PATH.
From source:
git clone https://github.com/es5h/projmux.git
cd projmux
make build
install -m 0755 .bin/projmux ~/.local/bin/projmux
Make sure ~/.local/bin is on your PATH:
export PATH="$HOME/.local/bin:$PATH"
Check the binary:
projmux version
projmux help
AI desktop notifications can be routed through a custom executable:
export PROJMUX_NOTIFY_HOOK="$HOME/.local/bin/projmux-notify"
The hook receives seven arguments: summary, body, urgency, app name, tag, group,
and icon path. When this variable is set, projmux uses the hook instead of its
built-in desktop notification sender.
That is enough to use the standalone app path. projmux shell generates its own
tmux config and does not require an existing .tmux.conf include, zsh framework,
or shell framework.
For development, use:
make fmt
make fix
make test
make test-integration
make test-e2e
Quick Start
Launch the isolated projmux tmux app:
projmux shell
This writes ~/.config/projmux/tmux.conf and starts:
tmux -L projmux -f ~/.config/projmux/tmux.conf new-session -A -s main
This is the recommended first-run entrypoint: projmux owns this tmux server, its
generated config, status bar, and popup bindings.
Inside that app session, the left status badge shows the current project name,
and the right status area shows the current path, kube segment, git segment, and
clock.
Common app bindings are generated by projmux. If your terminal emulator needs
explicit key forwarding, see Terminal Keybindings.
Apply To Your Existing tmux
If you want projmux inside your normal tmux server instead of the isolated app
server, install the generated tmux snippet:
projmux tmux install --bin "$(command -v projmux)"
tmux source-file ~/.tmux.conf
That writes ~/.config/tmux/projmux.conf, adds a source line to
~/.tmux.conf, and installs bindings that call projmux directly.
To inspect the snippet before installing:
projmux tmux print-config --bin "$(command -v projmux)"
To only regenerate the isolated app config:
projmux tmux install-app --bin "$(command -v projmux)"
zsh Integration
The lowest-friction setup is an alias:
alias pmx='projmux shell'
If you want new interactive zsh shells to enter the projmux app automatically,
add a guarded hook to ~/.zshrc:
if [[ -o interactive && -z "${TMUX:-}" ]] && command -v projmux >/dev/null 2>&1; then
exec projmux shell
fi
Keep machine-specific shell policy in your own zsh config. projmux provides
the stable app entrypoint and generated tmux config; it does not own terminal
emulator or login-shell policy.
Commands
High-level navigation:
projmux shell
projmux switch [--ui=popup|sidebar]
projmux sessions [--ui=popup|sidebar]
projmux settings
projmux current
Session lifecycle:
projmux attach auto [--keep=N] [--fallback=home|ephemeral]
projmux prune ephemeral [--keep=N]
Pins and preview state:
projmux pin add <dir>
projmux pin remove <dir>
projmux pin toggle <dir>
projmux pin list
projmux preview select <session> <window> <pane>
projmux preview cycle-window <session> <next|prev>
projmux preview cycle-pane <session> <next|prev>
Tmux integration helpers:
projmux tmux install
projmux tmux install-app
projmux tmux popup-toggle <mode>
projmux tmux rename-pane <pane> <title>
projmux attention toggle [pane]
projmux status git [path]
projmux status kube [session]
Run projmux help or <command> --help for the full command surface.
Releases
GitHub Actions publishes release archives when a v* tag is pushed. The current
app baseline release is v0.1.1.
How It Finds Projects
projmux switch combines pinned directories, live tmux sessions, and discovered
project roots. The default discovery logic favors common source locations such
as ~/source, ~/work, ~/projects, ~/src, ~/code, and ~/source/repos
when they exist. projmux settings also has Project Picker > Add Project...,
which scans those filesystem roots up to depth 3 so projects outside ~ and
~rp can be added to the picker. Session names are derived from normalized
directory paths, so a project keeps the same tmux session name across launches.
Configuration And State
Default paths follow XDG conventions:
- Config:
~/.config/projmux
- State:
~/.local/state/projmux
- Cache:
~/.cache/projmux and tmux-specific cache files under ~/.cache/tmux
- Runtime kube session files:
$XDG_RUNTIME_DIR/kube-sessions when available
The generated app tmux config lives at:
~/.config/projmux/tmux.conf
The generated normal tmux snippet lives at:
~/.config/tmux/projmux.conf
Scope
projmux owns the portable session-management core: naming, discovery, pins,
preview state, tmux orchestration, status segments, and generated tmux bindings.
Development
Useful commands:
make build
make fmt
make fix
make test
make test-integration
make test-e2e
make verify
More documentation:
License
MIT. See LICENSE.