The problem
If you run Claude Code in a browser-based terminal (like Cockpit), your session lives inside a WebSocket connection. When that connection drops — browser tab closed, laptop lid shut, phone screen locked, network hiccup — everything dies. Claude stops mid-task. Your context is gone. You start over.
Cockpit compounds this with a 15-minute idle session timeout. If Claude is thinking quietly — running tools, processing files — and you're not clicking around in the Cockpit UI, your session gets terminated automatically, taking Claude with it.
The solution
tmux is a terminal multiplexer that runs on the server, not in your browser. Your Claude session runs inside tmux. The browser terminal just shows you a view of it — like a window into a room that exists independently of whether you're looking.
Without tmux
Claude process is a child of the browser terminal. Close the tab → kill the process. One device, one session, no recovery.
With tmux
Claude runs inside a server-side tmux session. Close the tab, switch devices, lose network — tmux keeps running. Reconnect and attach.
Setup
Configure tmux
Create ~/.tmux.conf on your server. This sets up mouse support, better scrollback, a readable status bar, and a built-in help popup at Ctrl+B H.
Full config available in the GitHub repository.
Auto-attach on terminal open
Add this to ~/.bashrc. It detects when you're in a Cockpit terminal (XDG_SESSION_TYPE=web) and immediately attaches to (or creates) a tmux session named main.
SSH instead of Cockpit? Use SSH_TTY instead of XDG_SESSION_TYPE. Replace the condition with [ -n "$SSH_TTY" ] — this fires only on interactive SSH logins, not on automated ssh host "command" calls.
Fix the Cockpit idle timeout
By default, Cockpit terminates idle web sessions after 15 minutes — exactly long enough to time out while Claude is working quietly. Disable it:
Then restart Cockpit: sudo systemctl restart cockpit.service
Key bindings
All tmux commands start with the prefix Ctrl+B — press and release it, then press the next key. Ctrl+B H shows this as a popup in your terminal.
| Ctrl+B then C | New window |
| Ctrl+B then , | Rename current window |
| Ctrl+B then W | List all windows (interactive) |
| Ctrl+B then 1–9 | Switch to window by number |
| Ctrl+B then N / P | Next / previous window |
| Ctrl+B then % | Split left/right |
| Ctrl+B then " | Split top/bottom |
| Ctrl+B then ↑↓←→ | Move between panes |
| Ctrl+B then Z | Zoom pane to full screen (toggle) |
| Ctrl+B then [ | Enter scroll mode (use arrows/PgUp, Q to exit) |
| Ctrl+B then D | Detach — session keeps running |
| Ctrl+B then H | Help popup (from this config) |
| Ctrl+B then ? | Full built-in keybinding list |
Suggested window layout
Name your windows so the status bar tells you what's running at a glance. Use Ctrl+B , to rename.
1: claude
Your active Claude Code session. This is where you work.
2: logs
journalctl -f or tail -f on scheduler or app logs.
3: shell
Free shell for quick commands, file checks, or running builds.
Coexisting with scheduled Claude sessions
If you run automated Claude sessions (cron-based check-ins, email processing, transcript analysis), they can conflict with your interactive session — competing for CPU and trying to process the same data at the same time.
Add this function to your scheduler to detect an active interactive session and skip the automated wake:
The pane_current_command tmux format string returns the name of the running process — no need to parse ps aux.
Getting notified when a session needs input
tmux can highlight a tab when the process in it goes quiet — a reliable signal that something has finished and is waiting for you. This uses monitor-silence, which fires after a window has produced no output for a set number of seconds.
Add these lines to your ~/.tmux.conf:
The monitor-silence 20 value is seconds. Bump it up if it fires too often during normal processing pauses.
Why silence, not activity? monitor-activity fires on every byte of output — too noisy for Claude sessions that stream continuously. monitor-silence fires only when output stops, which is a much better proxy for "waiting for you." While a session is running it outputs constantly; when it hits a prompt or finishes, it goes quiet.
Common pitfalls
The first session after setup won't be in tmux
The .bashrc change only applies to new terminal sessions opened after saving the file. Close your current terminal tab and open a fresh one to get tmux.
display-popup requires tmux 3.2+
Check your version with tmux -V. If you're on an older version, remove the bind H display-popup ... block from .tmux.conf and use Ctrl+B ? for help instead.
Name your windows
Use Ctrl+B , to name each window. The status bar shows all window names at once — without names, you'll end up with a row of identical bash entries.
tmux survives, but the server has to stay on
Sessions persist across browser disconnects, not server reboots. A Pi or always-on server works perfectly for this; a laptop that gets shut down does not.
Related skills
Claude that keeps working after you close the tab
Three config changes. Runs on any headless Linux server with tmux and Cockpit.
View on GitHub