Help us shape the future of Go! Take the 2026 Go Developer Survey

projmux

module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: MIT

README

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.
  • On WSL, projmux sends Windows toast notifications through powershell.exe and auto-registers its toast AppUserModelID on first use when possible.
  • On Linux, notify-send is used for desktop notifications 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 (atomic install + apply live config):

git clone https://github.com/es5h/projmux.git
cd projmux
make install

make install builds the binary, atomically replaces ~/.local/bin/projmux, and runs projmux tmux apply so the live -L projmux server picks up any new bindings or status segments without a manual source-file.

To build without installing:

make build
install -m 0755 .bin/projmux ~/.local/bin/projmux

Make sure ~/.local/bin is on your PATH:

export PATH="$HOME/.local/bin:$PATH"

Upgrading

projmux upgrade rebuilds the active binary via go install and then atomically replaces it. The live tmux config is reapplied unless you opt out:

projmux upgrade                       # @latest, replace current binary, then apply
projmux upgrade --ref @v0.2.0          # pin a specific tag
projmux upgrade --ref @main            # track a branch
projmux upgrade --target /usr/local/bin/projmux  # replace another path
projmux upgrade --no-apply             # skip 'projmux tmux apply' afterwards
projmux upgrade --dry-run              # print the steps without executing

The upgrade reads PROJDIR/RP from the calling shell when set and memoizes the resolved value to ~/.config/projmux/projdir, so the new binary keeps the same project root context as the one it replaces.

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.

On WSL, the built-in sender targets Windows toast notifications through powershell.exe. projmux attempts to register the projmux.TmuxCodex AppUserModelID automatically so the toast channel has a stable display name in Windows notification settings.

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)"

To regenerate the isolated app config and live-source it on the running -L projmux socket without restarting the server:

projmux tmux apply

projmux tmux apply is what make install and projmux upgrade run after a successful binary swap. It is safe to call manually any time you change pin or workdir state and want the running server to pick up new sidebar entries.

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 apply
projmux tmux popup-toggle <mode>
projmux tmux rename-pane <pane> <title>
projmux attention toggle [pane]
projmux status git [path]
projmux status kube [session]

Self-update:

projmux upgrade [--ref @latest|@vX.Y.Z|@main] [--target /path] [--no-apply] [--dry-run]

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.2.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.

For permanent search-root customization, the Project Picker section also includes:

  • + Add Workdir... - append a single directory to the saved workdirs list.
  • Workdirs - review and remove saved workdirs. The same picker also surfaces any active PROJMUX_MANAGED_ROOTS / TMUX_SESSIONIZER_ROOTS env values as read-only rows so you can see why an env list might be overriding the saved file.

Add Workdir > Type path manually... gives you a typed entry that skips the filesystem scan. Use it for paths you do not want crawled, e.g. WSL mounts (/mnt/c/Users/...), large NFS mounts, or per-project temp roots.

The saved file lives at ~/.config/projmux/workdirs (one absolute path per line, # comments allowed). It is consulted only when the env vars are unset.

Environment Variables

Variable Purpose
PROJDIR Sessionizer repo root for the current shell. Wins over RP.
RP Legacy repo root env. Honored when PROJDIR is unset.
PROJMUX_MANAGED_ROOTS Colon-separated list of search roots. Wins over saved/default.
TMUX_SESSIONIZER_ROOTS Legacy alias for PROJMUX_MANAGED_ROOTS.
PROJMUX_NOTIFY_HOOK External executable for AI desktop notifications.
@projmux_projdir tmux user-option declarative source for PROJDIR. Set it via tmux set-option -g @projmux_projdir <path>.

When PROJDIR (or RP) is set explicitly, projmux memoizes the resolved value to ~/.config/projmux/projdir so subsequent runs without the env var keep the same project root.

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

Saved files under ~/.config/projmux:

File Contents
pins Pinned project directories (one path per line).
tags Tagged session names (one per line).
projdir Memoized single PROJDIR value (auto-written when env is used).
workdirs Persistent search-roots list, one absolute path per line. Managed via Settings.
tmux.conf Isolated -L projmux server config, regenerated by projmux tmux install-app or projmux tmux apply.

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.

Directories

Path Synopsis
cmd
projmux command
internal
app
integrations/tmux
Package tmux holds tmux command adapters and output parsing.
Package tmux holds tmux command adapters and output parsing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL