| name | tmux |
| description | tmux and tmuxp session configuration, management, and troubleshooting. Use when creating, editing, debugging, or optimizing tmuxp YAML configs, designing tmux workspace layouts, fixing tmux session errors, managing multi-environment terminal setups, or working with tmux panes, windows, and sessions. Also use when the user mentions tmuxp, .tmuxp, tmux layouts, session_name, or terminal workspace organization. |
| allowed-tools | Read, Write, Edit, Bash, Grep, Glob |
tmux & tmuxp Skill
Create, edit, debug, and optimize tmux sessions via tmuxp YAML configurations.
Quick Decisions
| Task | Approach |
|---|
| New project workspace | Create tmuxp YAML from template |
| Fix session load error | Check session_name, YAML syntax, tool availability |
| Multi-environment K8s | Use environment vars + per-env windows with safety guards |
| Simple dev setup | 2-3 windows: editor, server, terminal |
| Complex infra | before_script validation + helper scripts + monitoring windows |
| Capture existing layout | tmuxp freeze then clean up the output |
Session Name Rules
tmux session names cannot contain periods (.) or colons (:).
Common pitfall: using ${USER} in session_name when the username contains periods (e.g., first.last). Always use a static name or sanitize:
session_name: ${USER}-project
session_name: project-dev
session_name: project-${USER//\./-}
Configuration Structure
session_name: project-name
start_directory: ~/Projects/foo
environment:
PROJECT_ROOT: ~/Projects/foo
suppress_history: false
before_script: |
echo "Validating..."
after_script: |
echo "Cleaning up..."
windows:
- window_name: editor
focus: true
layout: main-vertical
start_directory: ~/Projects/foo/src
options:
main-pane-width: 70%
shell_command_before:
- source ~/.zshrc
panes:
-
Layouts
| Layout | Use For | Pane Arrangement |
|---|
main-vertical | Editor + sidebars | Large left, stacked right |
main-horizontal | Logs + status | Large top, split bottom |
even-horizontal | Equal side-by-side | Equal horizontal splits |
even-vertical | Equal stacked | Equal vertical splits |
tiled | Monitoring dashboards | Grid of equal panes |
Control main pane size via options:
options:
main-pane-width: 70%
main-pane-height: 65%
Capture a custom layout from a running session:
tmux display-message -p '#{window_layout}'
Pane Definitions
panes:
- vim README.md
- shell_command:
- cd ~/project
- source .venv/bin/activate
- python app.py
- null
- focus: true
shell_command:
- k9s
Environment Variables
environment:
PROJECT_NAME: my-app
HOME_DIR: ${HOME}
K8S_CTX_DEV: aks-myapp-dev
K8S_CTX_STG: aks-myapp-stg
K8S_CTX_PRD: aks-myapp-prd
EDITOR: ${EDITOR:-vim}
Never hardcode secrets. Reference env vars from the shell: ${AZURE_SUBSCRIPTION_ID}.
before_script Validation
Use before_script to validate prerequisites. Exit 1 aborts session creation:
before_script: |
# Check project exists
[ -d "$PROJECT_ROOT" ] || { echo "Project not found"; exit 1; }
for tool in kubectl terraform docker; do
command -v $tool >/dev/null || echo "Warning: $tool not found"
done
kubectl cluster-info >/dev/null 2>&1 || echo "Warning: Cannot reach cluster"
Production Safety Patterns
Protect production environments with read-only access and warnings:
- window_name: k8s-prod
panes:
- shell_command:
- echo "PRODUCTION - READ-ONLY ACCESS"
- echo "DO NOT use: apply, delete, edit, patch"
- kubectl config use-context $K8S_CTX_PRD
- k9s --readonly
CLI Commands
tmuxp load config-name
tmuxp load ./path/to/file.yaml
tmuxp load -y config-name
tmuxp load -d config-name
tmuxp ls
tmuxp freeze session-name
tmuxp convert file.json
tmuxp edit config-name
tmuxp debug-info
Troubleshooting
| Error | Cause | Fix |
|---|
BadSessionName: contains periods | session_name has . (often from ${USER}) | Remove ${USER} prefix or sanitize |
BadSessionName: contains colons | session_name has : | Remove colons from name |
| Session already exists | Duplicate session_name | Kill old: tmux kill-session -t name |
| Commands not executing | Shell compatibility | Test commands manually first |
| Layout broken | Terminal too small for layout | Use predefined layouts or test with tmuxp load -d |
| Env vars not expanding | Wrong syntax | Use ${VAR} not $VAR in YAML values |
Debug: tmuxp -v load config.yaml for verbose output.
References
Workflow: Create New Config
- Identify the project type (dev, infra, monitoring, mixed)
- Choose a template from
templates/
- Set session_name (no periods/colons), start_directory, environment vars
- Design windows by function (editor, server, logs, k8s, etc.)
- Pick layouts matching each window's purpose
- Add before_script validation if the project has external dependencies
- Add production safety guards for any prod-access windows
- Test:
tmuxp load -d config.yaml then tmux attach -t session-name
Gotchas
- Session names with periods break the unix-socket path:
${USER} containing . (e.g. first.last) produces BadSessionName because tmux uses the name in /tmp/tmux-UID/ socket path. Use a static name or ${USER//\./-} sanitization.
before_script runs in a fresh shell, not your interactive zsh: Aliases, functions, and .zshrc-sourced env vars are absent. command -v works but myalias does not. Source ~/.zshrc explicitly if you depend on it.
shell_command_before runs in EVERY pane of the window: Heavy commands (sourcing 500ms+ of zsh config, activating venvs) multiply latency — a 4-pane window adds ~2s to session load. Use per-pane shell_command instead when only one pane needs it.
tmuxp freeze captures live state, not intent: Output includes the random working directories, history-expanded commands, and the literal pane sizes — review and clean before committing. Frozen YAML is a starting point, not a finished config.
- Env var expansion happens at YAML load, not pane start:
environment: FOO: ${BAR} resolves $BAR from the shell that invoked tmuxp load. If $BAR is unset there, it stays empty even if a later pane defines it.
focus: true on multiple panes silently picks the last one: No error, no warning — the file just looks misconfigured at runtime. Validate with grep -c "focus: true" per window before debugging.