# ── START / ATTACH ──────────────────────────────────── tmux # new unnamed session tmux new -s agents # new named session "agents" tmux attach -t agents # attach to session "agents" tmux a # attach to most recent session tmux ls # list all sessions # ── INSIDE TMUX: PREFIX KEY ─────────────────────────── # Default prefix: Ctrl-b (we'll change to Ctrl-a in config) # Every tmux command: PREFIX then the key C-b d → detach (session keeps running!) C-b c → create new window C-b " → split pane horizontally (top/bottom) C-b % → split pane vertically (left/right) C-b arrow → move between panes C-b z → zoom pane to full window (toggle) C-b [ → enter scroll/copy mode (q to exit) C-b ? → show all keybindings C-b : → command prompt (type any tmux command) # ── POWERFUL COMBOS RIGHT NOW ───────────────────────── C-b s → interactive session tree (arrow keys + enter) C-b w → interactive window tree C-b $ → rename current session C-b , → rename current window
Run claude --agent research-task inside tmux. Disconnect, travel, reconnect. Agent is still running. Without tmux: SSH drops → agent dies → you start over.
Split into a 4×2 grid. Watch all 8 LLM agents simultaneously. One pane per agent: see their output, status, errors — all without switching contexts.
tmux new-session -d + send-keys lets you write shell scripts that build entire workspace layouts. One script → 8 panes, 3 sessions, all agents running.
tmux new-session -s agents # new session named agents tmux new-session -s workers -d # new session, detached (background) tmux attach-session -t agents # attach to agents tmux switch-client -t devenv # switch to another session tmux kill-session -t agents # destroy session + all its windows tmux kill-server # nuke everything tmux list-sessions # ls alias: tmux ls tmux rename-session -t old new # rename from outside # Attach or create (the professional entry point): tmux attach -t agents || tmux new -s agents
tmux new -s agents not tmux. With names: you can attach to the right session by name, script session creation, and glance at tmux ls to understand your workspace instantly. Unnamed sessions are for beginners.
# Session groups: two clients viewing same windows # Use case: pair programming, monitoring from two terminals # Create first session: tmux new-session -s main # Create second session, join the group: tmux new-session -s monitor -t main # Now both sessions share windows but can independently: # - Be focused on different windows # - Have different sizes (useful: big monitor + laptop) # Changes in one appear in the other in real time
# Create named window in a session: tmux new-window -t agents -n "workers" # Create window and run a command in it: tmux new-window -t agents -n "logs" -c ~/projects # Move window from one session to another: tmux move-window -s agents:2 -t monitor # Link window (mirror it across sessions): tmux link-window -s agents:0 -t monitor:0 # Kill a specific window without being inside it: tmux kill-window -t agents:workers # Swap two windows: tmux swap-window -s agents:1 -t agents:3 # Reorder all windows (renumber from 0): tmux move-window -r
# Split pane from CLI (great for scripts): tmux split-window -h # split horizontal tmux split-window -v -p 30 # split vertical, new pane 30% tall tmux split-window -h -c ~/src # split, start in directory # Move pane to another window: tmux join-pane -s agents:1.0 -t agents:2 # Resize precisely: tmux resize-pane -t 0 -x 80 # set pane 0 to exactly 80 cols tmux resize-pane -Z # toggle zoom (same as C-b z) # Apply a layout by name: tmux select-layout tiled tmux select-layout main-vertical
# Enable vi keys in copy mode: set-window-option -g mode-keys vi # vi-style selection and copy: bind-key -T copy-mode-vi v send-keys -X begin-selection bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle # Mouse: click to select, double-click word, drag to select: set -g mouse on # System clipboard integration (macOS): bind-key -T copy-mode-vi y \ send-keys -X copy-pipe-and-cancel "pbcopy" # System clipboard integration (Linux/X11): bind-key -T copy-mode-vi y \ send-keys -X copy-pipe-and-cancel "xclip -selection clipboard" # System clipboard integration (Linux/Wayland): bind-key -T copy-mode-vi y \ send-keys -X copy-pipe-and-cancel "wl-copy" # Increase scrollback buffer (default is only 2000 lines!): set -g history-limit 50000
history-limit 50000 or even higher. At 50k lines of terminal output per pane, 8 agent panes = 400k lines in RAM — totally fine on modern hardware. Your agent's 3-hour log output needs to be searchable.
# From inside tmux command prompt (C-b :) # or from shell with tmux prefix: tmux show-options -g # all global options tmux show-options -g prefix # current prefix key tmux show-window-options -g # window-specific options tmux show-environment # tmux environment variables tmux display-message '#{session_name}' # current session name tmux display-message '#{window_index}' # current window index tmux display-message '#{pane_current_command}' # running command tmux display-message '#{pane_pid}' # PID of shell in pane # List all format variables: tmux display-message -a | less # 200+ variables available
# Pattern: one session per project or concern # tmux ls output of a mature workspace: $ tmux ls agents: 3 windows (created Mon Apr 5 09:00:26 2026) devenv: 2 windows (created Mon Apr 5 08:45:01 2026) (attached) monitor: 1 window (created Mon Apr 5 08:45:55 2026) infra: 4 windows (created Sun Apr 4 22:15:00 2026) # Switch between sessions instantly: # C-b s → interactive tree # C-b ( → previous session # C-b ) → next session # C-b L → last used session # C-b :switch-client -t agents → by name # Quick-switch with fzf (add to shell .zshrc/.bashrc): alias ts='tmux switch-client -t $(tmux ls -F "#{session_name}" | fzf)' alias ta='tmux attach -t $(tmux ls -F "#{session_name}" | fzf)' # The "attach or create" pattern — put in a shell alias: function t() { if [ -z "$1" ]; then tmux attach 2>/dev/null || tmux new-session -s main else tmux attach -t "$1" 2>/dev/null || tmux new-session -s "$1" fi } # Usage: t → attach to most recent # t agents → attach or create "agents"
tmux-resurrect (saves/restores session layout) + tmux-continuum (auto-saves every N minutes). The Plugins section covers this. This is critical for long-running agent pipelines.
# Set environment variable visible to all panes in session: tmux set-environment -t agents OPENAI_API_KEY sk-proj-... tmux set-environment -g LOG_LEVEL debug # global (all sessions) # Remove a variable: tmux set-environment -r OPENAI_API_KEY # Show session environment: tmux show-environment -t agents # Access in shell (new panes inherit at creation time): $ echo $OPENAI_API_KEY # works in new panes # Lock a session (password-protect it): tmux lock-session -t sensitive # Set a session-specific working directory: tmux new-session -s agents -c ~/projects/agents # All new windows/panes in "agents" start in ~/projects/agents
setw synchronize-panes on. Everything you type goes to ALL panes simultaneously. Use case: deploy the same command to 8 agent processes, run tests in parallel across environments, broadcast a stop signal to all running workers. Toggle off when done.
# Toggle from command prompt: C-b : setw synchronize-panes on C-b : setw synchronize-panes off # Add a keybinding to .tmux.conf (toggle with C-b S): bind S setw synchronize-panes \; \ display-message "sync: #{?pane_synchronized,ON,OFF}" # Practical use: stop all 8 LLM agents at once # 1. Enter sync mode # 2. Type: Ctrl+C # 3. All 8 agents receive SIGINT simultaneously # Send-keys to all panes WITHOUT sync mode (scripted): for pane in $(tmux list-panes -t agents:workers -F '#{pane_index}'); do tmux send-keys -t agents:workers.$pane "git pull && ./restart.sh" Enter done
# Monitor for activity (alert when any output appears): C-b : setw monitor-activity on # Window tab flashes when background pane has new output # Perfect for: long-running jobs you need to catch # Monitor for silence (alert when output stops): C-b : setw monitor-silence 30 # Alert if pane has no output for 30 seconds # Perfect for: detecting hung/deadlocked agents # In .tmux.conf — visual + audible alert: set -g visual-activity on set -g visual-bell on set -g bell-action any # alert on any window bell # Pipe pane output to a file (live stream to log): tmux pipe-pane -t agents:0.0 "cat >> /tmp/agent-0.log" # Stop piping: tmux pipe-pane -t agents:0.0 # empty command stops it
# Problem: C-b arrow is slow (two keystrokes). # Solution: use Alt+arrow without prefix. # Add to .tmux.conf: bind -n M-Left select-pane -L # Alt+← select left pane bind -n M-Right select-pane -R bind -n M-Up select-pane -U bind -n M-Down select-pane -D # Even better: vim-tmux-navigator plugin makes # Ctrl+h/j/k/l work across vim splits AND tmux panes seamlessly. # (See Plugins section) # Resize panes without prefix (Shift+Alt+arrow): bind -n M-S-Left resize-pane -L 5 bind -n M-S-Right resize-pane -R 5 bind -n M-S-Up resize-pane -U 5 bind -n M-S-Down resize-pane -D 5 # Jump to a specific pane by number (instant): C-b q → numbers appear, type the number within 1s # Display pane addresses for scripting: tmux list-panes -t agents:0 -F "#{pane_index}: #{pane_current_command} PID=#{pane_pid}"
# Replace confusing " and % with more intuitive bindings: bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}" # C-b | → split vertical (visual: | = vertical line) # C-b - → split horizontal (visual: - = horizontal line) # "pane_current_path": new pane opens in same directory! # This is the #1 most useful pane config change. # Also propagate directory on new windows: bind c new-window -c "#{pane_current_path}"
# send-keys sends keystrokes to a pane as if you typed them. # Target format: session:window.pane # session:window → pane 0 of that window (default) # session:window.N → specific pane N # Basic: run a command in a specific pane tmux send-keys -t agents:0.0 "python agent.py --task research" Enter # Send a key without a command: tmux send-keys -t agents:0.0 "" C-c # send Ctrl+C to pane tmux send-keys -t agents:0.0 q Enter # type q then Enter # Send to ALL panes in a window: for pane in $(tmux list-panes -t agents:workers -F '#{pane_index}'); do tmux send-keys -t "agents:workers.$pane" "echo pane $pane ready" Enter done # Don't execute yet (no Enter) — populate then review: tmux send-keys -t agents:0.0 "python dangerous_thing.py" # User sees the command, presses Enter themselves # Read output from a pane (capture pane content): tmux capture-pane -t agents:0.0 -p # last screenful tmux capture-pane -t agents:0.0 -p -S -3000 # last 3000 lines tmux capture-pane -t agents:0.0 -p -e # include escape codes # Write pane content to file: tmux capture-pane -t agents:0.0 -pS -10000 > agent-output.txt
#!/bin/bash # Spawn a full 8-agent workspace with monitoring in one shot. # Usage: ./agents.sh [task_description] SESSION="agents" TASK="${1:-default-research-task}" # Kill existing session if running: tmux kill-session -t "$SESSION" 2>/dev/null # ── WINDOW 0: ORCHESTRATOR ──────────────────────────── tmux new-session -d -s "$SESSION" -n "orchestrator" -x 220 -y 50 tmux send-keys -t "$SESSION:orchestrator" \ "cd ~/agents && python orchestrator.py --task '$TASK'" Enter # ── WINDOW 1: WORKERS (4 agents in a 2x2 grid) ──────── tmux new-window -t "$SESSION" -n "workers" # Split into 4 panes: tmux split-window -t "$SESSION:workers" -h # pane 0 + pane 1 tmux split-window -t "$SESSION:workers.0" -v # pane 0 + pane 2 tmux split-window -t "$SESSION:workers.1" -v # pane 1 + pane 3 tmux select-layout -t "$SESSION:workers" tiled # Start agent in each pane: for i in 0 1 2 3; do tmux send-keys -t "$SESSION:workers.$i" \ "python agent_worker.py --id $i --task '$TASK'" Enter done # ── WINDOW 2: LOGS + MONITOR ────────────────────────── tmux new-window -t "$SESSION" -n "monitor" tmux split-window -t "$SESSION:monitor" -h -p 40 # Left pane: live log aggregation tmux send-keys -t "$SESSION:monitor.0" \ "tail -f /var/log/agents/*.log | grep -v DEBUG" Enter # Right pane: system resources tmux send-keys -t "$SESSION:monitor.1" \ "htop -d 5" Enter # ── FOCUS AND ATTACH ────────────────────────────────── tmux select-window -t "$SESSION:orchestrator" tmux attach-session -t "$SESSION"
name: agents root: ~/projects/agents socket_name: agents # isolated tmux server socket windows: - orchestrator: layout: main-vertical panes: - python orchestrator.py - tail -f logs/orchestrator.log - workers: layout: tiled panes: - python worker.py --id 0 - python worker.py --id 1 - python worker.py --id 2 - python worker.py --id 3 - monitor: layout: even-horizontal panes: - htop - tail -f logs/combined.log - shell: # empty pane for ad-hoc commands
# Install: gem install tmuxinator # Ruby gem pip install tmuxinator # or Python port # Commands: tmuxinator start agents # start workspace tmuxinator stop agents # stop workspace tmuxinator edit agents # edit YAML config tmuxinator new agents # create new config tmuxinator list # list all configs tmuxinator copy agents dev # copy a config tmuxinator doctor # check dependencies # With arguments (interpolated in YAML): tmuxinator start agents task="research openai o3" # In YAML: <%= @args[:task] %> # Shell alias for instant access: alias mux='tmuxinator' alias ma='tmuxinator start agents'
↑ 8 agents running in a 4×2 tiled layout. synchronize-panes for broadcast commands. capture-pane to harvest outputs programmatically.
import subprocess, json, time, sys from dataclasses import dataclass def tmux(*args) -> str: """Run any tmux command, return stdout.""" result = subprocess.run( ["tmux"] + list(args), capture_output=True, text=True ) return result.stdout.strip() class AgentCluster: def __init__(self, session: str, n_workers: int = 8): self.session = session self.n = n_workers def spawn(self, task: str): # Kill existing session tmux("kill-session", "-t", self.session) # Create session with first worker window tmux("new-session", "-d", "-s", self.session, "-n", "workers", "-x", "220", "-y", "50") # Create N-1 additional panes for i in range(1, self.n): tmux("split-window", "-t", f"{self.session}:workers", "-h" if i % 2 == 1 else "-v") tmux("select-layout", "-t", f"{self.session}:workers", "tiled") # Start agent in each pane for i in range(self.n): tmux("send-keys", "-t", f"{self.session}:workers.{i}", f"python agent.py --id {i} --task '{task}'", "Enter") def is_done(self, pane: int) -> bool: """Check if agent pane has exited.""" out = tmux("display-message", "-t", f"{self.session}:workers.{pane}", "-p", "#{pane_dead}") return out.strip() == "1" def get_output(self, pane: int) -> str: """Capture pane output for result collection.""" return tmux("capture-pane", "-t", f"{self.session}:workers.{pane}", "-p", "-S", "-10000") def wait_all(self, poll_interval: float = 5.0): while True: done = [self.is_done(i) for i in range(self.n)] if all(done): break time.sleep(poll_interval) def broadcast(self, cmd: str): """Send command to all agents simultaneously.""" for i in range(self.n): tmux("send-keys", "-t", f"{self.session}:workers.{i}", cmd, "Enter") # Usage: cluster = AgentCluster("agents", n_workers=8) cluster.spawn(task="Analyze 2026 AI landscape") cluster.wait_all() outputs = [cluster.get_output(i) for i in range(8)]
#!/bin/bash # A pane that shows live status of all agent panes. # Run in a separate tmux pane as your control panel. SESSION="agents" WINDOW="workers" while true; do clear echo "═══ AGENT STATUS $(date '+%H:%M:%S') ═══" echo for pane in $(tmux list-panes -t "$SESSION:$WINDOW" \ -F "#{pane_index}"); do # Get pane metadata: dead=$(tmux display-message -t "$SESSION:$WINDOW.$pane" \ -p "#{pane_dead}") cmd=$(tmux display-message -t "$SESSION:$WINDOW.$pane" \ -p "#{pane_current_command}") pid=$(tmux display-message -t "$SESSION:$WINDOW.$pane" \ -p "#{pane_pid}") # Get last line of output: last=$(tmux capture-pane -t "$SESSION:$WINDOW.$pane" -p \ | grep -v '^$' | tail -1) if [ "$dead" = "1" ]; then status="[DONE] " else status="[RUN] ⚡" fi printf "pane %d %s %s\n" "$pane" "$status" "${last:0:60}" done sleep 3 done
tmux capture-pane -t SESSION:WINDOW.PANE -p -S -N captures the last N lines of a pane's output as text. This is how you harvest agent outputs, check for error strings, build status dashboards, and implement polling loops — all from outside the pane, without interrupting the running agent.
# ── PREFIX ──────────────────────────────────────────── # Remap prefix from C-b to C-a (like GNU Screen, more ergonomic) unbind C-b set-option -g prefix C-a bind-key C-a send-prefix # C-a C-a sends literal C-a to terminal # ── GENERAL ──────────────────────────────────────────── set -g default-terminal "tmux-256color" set -ag terminal-overrides ",xterm-256color:RGB" # true color set -g history-limit 50000 # scrollback lines per pane set -g base-index 1 # windows start at 1 (not 0) setw -g pane-base-index 1 # panes start at 1 set -g renumber-windows on # auto-renumber on window close set -g mouse on # enable mouse (click, drag, scroll) set -sg escape-time 0 # zero delay for vim Escape key set -g focus-events on # pass focus events to apps (vim autoread) set -g display-time 3000 # status messages visible 3s set -g status-interval 5 # refresh status bar every 5s set -g automatic-rename on # auto-rename windows to running command set -g automatic-rename-format "#{pane_current_command}" # ── SPLITS (intuitive | and -) ───────────────────────── bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}" bind c new-window -c "#{pane_current_path}" unbind '"' # remove old horizontal split unbind % # remove old vertical split # ── PANE NAVIGATION (Alt+arrow, no prefix needed) ────── bind -n M-Left select-pane -L bind -n M-Right select-pane -R bind -n M-Up select-pane -U bind -n M-Down select-pane -D # ── PANE RESIZE (prefix + Ctrl+arrow) ────────────────── bind -r C-Left resize-pane -L 5 bind -r C-Right resize-pane -R 5 bind -r C-Up resize-pane -U 5 bind -r C-Down resize-pane -D 5 # ── WINDOW SWITCHING (prefix + Shift+arrow) ──────────── bind -n S-Left previous-window bind -n S-Right next-window
# ── COPY MODE (vi keys) ──────────────────────────────── setw -g mode-keys vi bind-key -T copy-mode-vi v send-keys -X begin-selection bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel bind-key -T copy-mode-vi Y send-keys -X copy-end-of-line # System clipboard (pick ONE for your OS): # macOS: bind-key -T copy-mode-vi y \ send-keys -X copy-pipe-and-cancel "pbcopy" # Linux X11: # send-keys -X copy-pipe-and-cancel "xclip -selection clipboard" # Linux Wayland: # send-keys -X copy-pipe-and-cancel "wl-copy" # ── UTILITIES ────────────────────────────────────────── bind r source-file ~/.tmux.conf \; display-message "Config reloaded!" bind S setw synchronize-panes \; \ display-message "sync: #{?pane_synchronized,ON,OFF}" bind K confirm-before -p "Kill session? (y/n)" kill-session bind-key / copy-mode \; send-keys "?" # quick backward search # ── STATUS BAR ───────────────────────────────────────── set -g status-position bottom set -g status-style "bg=colour234 fg=colour136" set -g status-left-length 40 set -g status-right-length 80 set -g status-left \ "#[bg=colour64 fg=colour232 bold] #{session_name} \ #[bg=colour234 fg=colour64]" set -g status-right \ "#[fg=colour136] %a %d %b #[fg=colour64 bold] %H:%M \ #[fg=colour232 bg=colour64 bold] #h " setw -g window-status-format " #I:#W " setw -g window-status-current-format \ "#[bg=colour136 fg=colour232 bold] #I:#W " # ── PANE BORDERS ─────────────────────────────────────── set -g pane-border-style "fg=colour238" set -g pane-active-border-style "fg=colour64" # ── PLUGINS (TPM) ────────────────────────────────────── set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-sensible' set -g @plugin 'tmux-plugins/tmux-resurrect' set -g @plugin 'tmux-plugins/tmux-continuum' set -g @plugin 'christoomey/vim-tmux-navigator' set -g @continuum-restore 'on' set -g @continuum-save-interval '10' run '~/.tmux/plugins/tpm/tpm'
# Session: #{session_name} #{session_windows} #{session_attached} # Window: #{window_name} #{window_index} #{window_flags} (flags: *=active, -=last) # Pane: #{pane_index} #{pane_current_command} #{pane_pid} #{pane_width}x#{pane_height} # Host: #{host} #{host_short} # System: #{load_average} (via tmux-cpu plugin) # Time: #[fg=colour64]%H:%M#[default] (strftime format) # Conditional: #{?pane_synchronized,SYNC ON,} (? = ternary)
# Install TPM: git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm # In .tmux.conf — declare plugins BEFORE run line: set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-sensible' # sane defaults # ... more plugins ... run '~/.tmux/plugins/tpm/tpm' # MUST BE LAST LINE # Inside tmux after editing .tmux.conf: prefix + I → Install plugins (capital I) prefix + U → Update all plugins prefix + M-u → Remove unneeded plugins # Then reload config: prefix + r → source ~/.tmux.conf
| Plugin | What it does |
|---|---|
| tmux-sensible | Sane defaults every tmux user wants. The baseline. Always install first. |
| tmux-resurrect | Save and restore sessions across reboots. Saves panes, windows, sessions, and running programs. Critical for long agent runs. |
| tmux-continuum | Automatic periodic save (every N minutes). Works with resurrect. Set-and-forget persistence. |
| vim-tmux-navigator | Ctrl+h/j/k/l navigates between vim splits AND tmux panes seamlessly. Eliminates the C-b prefix for navigation. |
| tmux-fzf | Fuzzy search sessions, windows, panes, commands. Type prefix+F and fuzzy-find anything. |
| tmux-yank | Copy to system clipboard from copy-mode. Handles macOS/Linux/WSL automatically. |
| tmux-cpu | CPU/memory stats in status bar: #{cpu_percentage} #{ram_percentage} |
| tmux-battery | Battery level in status bar. Adds #{battery_percentage}. |
| tmux-open | Open URLs and files under cursor. Highlight a URL, press O, it opens in browser. |
| tmux-sessionist | Enhanced session management: move pane to new session, merge sessions. |
# In .tmux.conf: set -g @plugin 'tmux-plugins/tmux-resurrect' set -g @plugin 'tmux-plugins/tmux-continuum' # Resurrect: what to save set -g @resurrect-capture-pane-contents 'on' # save pane output too set -g @resurrect-strategy-vim 'session' # restore vim sessions set -g @resurrect-strategy-nvim 'session' # restore neovim sessions set -g @resurrect-processes 'ssh psql python3 node' # restore these processes # Continuum: auto-save interval set -g @continuum-restore 'on' # auto-restore on tmux start set -g @continuum-save-interval '10' # save every 10 minutes # Manual save/restore: prefix + C-s → save session prefix + C-r → restore session # Where sessions are saved: ls ~/.tmux/resurrect/ # last.symlink + timestamped saves # For agent workloads: continuum saves every 10min. # System reboots: run tmux, prefix + C-r → entire agent # workspace back exactly as you left it.
# ~/scripts/tmux-agent-status.sh # Shows live agent count in tmux status bar #!/bin/bash SESSION="agents" WINDOW="workers" total=$(tmux list-panes -t "$SESSION:$WINDOW" 2>/dev/null | wc -l) if [ "$total" = "0" ]; then echo "no agents"; exit fi running=$(tmux list-panes -t "$SESSION:$WINDOW" \ -F "#{pane_dead}" 2>/dev/null | grep -c "^0$") done=$(( total - running )) echo "⚡${running}/${total} agents" # In .tmux.conf status-right: # set -g status-right "#(~/scripts/tmux-agent-status.sh) | %H:%M" # set -g status-interval 5 ← refresh every 5s
tmux capture-pane outputs, check process counts, read files — all refreshed on status-interval. Your status bar becomes a live agent dashboard showing running count, error state, and last update time — without an extra monitoring tool.
# Session: devenv # window 0: editor (nvim with vim-tmux-navigator) # window 1: shell (zsh + starship prompt) # window 2: git (lazygit) # Session: agents # window 0: orchestrator (LLM pipeline controller) # window 1: workers (8 LLM agents tiled 4x2) # window 2: monitor (htop + log tail) # window 3: results (DuckDB querying agent outputs) # Session: infra # window 0: k8s (k9s — kubernetes TUI) # window 1: db (pgcli / mycli REPL) # window 2: kafka (kcat consumer watching topics) # window 3: flink (Flink SQL REPL) # All sessions: auto-restored by tmux-continuum on boot. # Status bar: shows active agents, time, host. # Navigation: C-a s → jump anywhere in <2 keystrokes. # Everything is persistent, scriptable, reproducible. # This is the CLI-first 2026 workspace. $ tmux ls devenv: 3 windows (created Mon Apr 5 08:45:01 2026) (attached) agents: 4 windows (created Mon Apr 5 09:00:26 2026) ⚡6/8 running infra: 4 windows (created Sun Apr 4 22:15:00 2026)