Panes that keep running, and talk to each other.
keepane is a terminal multiplexer. The programs in its panes keep running after the terminal connection closes, and panes can pass messages to each other through inboxes, on one computer or across two you have paired. The usual tmux keys, commands and config file keep working, h j k l included, and PowerShell, cmd and WSL run inside panes with every keystroke intact.
Send work between panes
Give a pane a name and a work mode, and send it messages: a shell runs them at its prompt, an agent gets them when it is free. C-b v shows every pane and its inbox.


keepane list-agents prints the same. (The agents are stand-ins that write real transcripts.)
- Every message says where it came from in one line of JSON. A chain of messages is one task, with how long each step waited and took; one that goes round more than eight times is refused.
- Agents such as Claude Code use it through MCP: send and reply, wait for an answer within their turn, make panes of their own to work in.
keepane setupsets up the hook and the registration for Claude Code, Codex, Gemini CLI, Cursor CLI or opencode, so the agent is handed its next message when a turn ends; a message for an agent that never says it is free tells you which setup it lacks. - A pane's work mode is changed in that pane, so nothing running in one pane turns another into a shell that runs what it is sent. What happens is kept in an event log for 30 days.
- Each agent a pane runs (Claude Code, Codex, pi) shows its model, what it has cost, how full its context is, its tokens, CPU and memory: in the dashboard, on its card on the phone, in
keepane list-agentsand in#{agent_cost}-style variables. keepane reads the transcripts the agents write; cost is priced by LiteLLM's public list (API list prices), oragent-cost off.
Panes on another computer
Two computers on one network, or both on Tailscale, pair once, the way ssh-copy-id works.
From then on a pane on one sends messages and commands to a pane on the other, and the answer comes back
to the pane that asked.
# on the laptop: pair with the desktop, whose keepane web printed this address
keepane link add http://192.168.1.20:7681/#k=...
# a message for the agent pane there
keepane send-message --to 192.168.1.20:7681/%agent "review the diff"
# what that machine runs, and a look at its pane (if it allows it)
keepane link info 192.168.1.20:7681
keepane link capture 192.168.1.20:7681/%agent
- A pane is addressed as
host:port/%nameorhost:port/$1:@3.%7. The answer to a message goes back by pane id, so it still arrives after the pane that asked has been moved. - Each machine has its own key pair. Pairing uses the other side's phone code once; after that every request and every answer is signed, with the time and a one-off number, so an old one cannot be sent again. A machine is known by its key, not its address.
- What comes from another machine goes to agent and normal panes only. Letting it run as shell commands, read a pane's screen, or start panes here (
keepane link start, one of this machine'sagent-commands) is allowed per machine withkeepane link allow, and only from outside keepane: an agent in a pane cannot grant it to itself. - Agents get it through MCP too:
list_links,link_info,read_screen, andsend_messageto an address on another machine.
Close the terminal, the programs keep running
C-b d detaches and the programs keep running in the background. keepane attach
picks the session up again, from any terminal window.
keepane resume
brings back the panes, their names and folders, and what they showed.


- Sessions survive a reboot too. Each one is saved to its own file whenever its layout changes, and
keepane resumebrings back the windows, the pane layout, and each pane's command and directory. - The file also keeps what each pane printed:
save-historystores the last 500 lines by default, or the whole scrollback withall, colours included. A resumed pane shows its old output instead of an empty prompt. keepane list-savedshows what can be restored, andkeepane resume workrestores just that session.
What ran, when, and how long
C-b C-t writes each command's start time, duration and result at the end of its line. What panes print is kept a day at a time, and C-b / opens any day.


- The time goes in the blank end of the line. The pane keeps its width and nothing is added to what the program printed. On the phone, When each command ran, in the view menu, puts the times in a column of their own.
- What scrolls off a pane is written to a file for that pane and day, kept for 30 days, with a line of times before each command. In the pager, [ and ] jump from command to command and / searches.
- Closed the wrong pane or window? It is kept for 10 seconds with its program still running, and C-b u puts it back where it was.
- C-b y copies what the last command printed, and nothing else: a failing test's output, ready for an issue or an agent.
The job that finished while you were elsewhere
monitor-activity marks a window you are not looking at with # when it prints,
! on a bell, and ~ when it has been silent too long. C-b M-n jumps to the
next marked window.
list-windows; a command that fails leaves its pane and its exit code behind.
- With
remain-on-exit, a pane stays open after its program exits and shows[cmd exited with 3], so a crash at 3am is still there in the morning.respawn-panestarts the program again in the same place. pipe-pane "$input | Add-Content build.log"sends everything a pane prints to a command, and tells you if that command falls behind.- Scripts can wait on each other:
keepane wait-for readyblocks until another client runskeepane wait-for -S ready, and-Land-Uwork as a lock.
Panes, the way you already know
C-b % splits left and right, C-b " top and bottom. Move with the vim keys or the arrows, and keep pressing: movement and resizing repeat without the prefix.


- Every pane is a ConPTY, so PSReadLine chords, IME input and full-screen programs behave as they do outside keepane.
- The mouse works: click a pane to focus it, drag a border to resize it, drag across text to copy it to the system clipboard.
- C-b S or
:set sync(Tab completes the name) sends every key to every pane in the window.split-window -N 3adds three panes at once and tiles them.
Full screen, a list, or a menu
C-b z blows the current pane up to the whole window and back. C-b w opens a chart of every session, window and pane: h j k l to move, a to open all of it, v for a tree or a plain list, digits to jump, Enter to go. C-b > puts the pane commands in a menu, so nothing has to be remembered.





- C-b Space cycles through five layouts: even columns, even rows, a main pane beside or above the rest, and a tiled grid. C-b E evens out the panes next to the current one.
- Unsure of a key? Press C-b and wait: after half a second a panel says what the keys do, by group, read from your own bindings. The key then works as ever.
- C-b q draws a number on every pane; press the number to jump there.
- Zooming grows the pane itself, each of its corners heading for the window's, and unzooming shrinks it back; when the focus moves to another pane or window, a frame flies there. Programs are resized once, so nothing waits for it;
set -g animation offturns it off. A zoomed window stays zoomed as you move between its panes, until C-b z. - In copy mode, / searches forward and ? backward, n and N repeat the search, and the match is scrolled to the middle of the screen.
display-popupruns a program in a box over the window and closes the box when the program exits. It is handy for a quickgit logwithout touching the layout.
Your panes, on your phone
Start keepane web before you walk away from a long build. It prints a QR code; scan it on
the same Wi-Fi and the phone's browser lists every pane, shows any of them as it appears on screen,
and lets you type into it. Nothing to install on the phone.
- keepane sends the screen again whenever it changes, colours included, and you can scroll up through what already went by. The list carries each window's alert marks (# printed, ! bell, ~ silent), so a finished job shows up without opening it. What you type in the box goes to the pane as you type it, and Enter is the Enter (or, in the view menu, the box waits for Enter).
- A row above the text box has the keys a phone keyboard lacks: Ctrl, Alt, Shift (held for the next key: Shift then → is Shift+Right), Esc, Tab, the arrows, with Ctrl+C and Enter kept in view at its end, and Shift+Tab, y, n, 1, 2, 3 and a few more under the ⋯ beside the box. The ⋯ menu in the pane's bar, or a right click (a long press on a phone) on a pane in the list, splits the pane, opens a window, renames, shows the inbox or closes the pane. On a shell or ai pane, the envelope beside the box sends it as a message into the pane's inbox instead.
- Each pane shows under its name: a dot for free or busy, how many messages wait in its inbox, and the last thing it printed. Fit to this screen, in the view menu, sizes a pane to the phone for a full-screen program, and gives it back when you leave. The same menu finds text in the output, copies the screen's text and sizes the text (a pinch does too); tap a command's time to copy what it printed.
- When a pane is done (a long command ended, an agent finished its turn) the page says so: a banner to tap, a sound, a buzz. For a locked phone, keepane posts to ntfy, Feishu, WeCom, DingTalk, Slack or Discord (
done-webhook), or runs a hook of yours. - The same page works in a computer's browser, with the list on the left and the pane on the right. The page has its own light and dark look and speaks Chinese or English (the system's, or picked), and from it you can switch the terminal's theme too (Tokyo Night or Tokyo Day), which changes it on the computer as well. The top right shows the delay to the computer, and full screen leaves only the pane's screen and the input box.
- Commands run on the computer. The phone can read panes, type into them and use that menu, nothing more;
--read-onlyleaves out the typing. - It is off until you start it; the keepane server then serves it in the background until
keepane web stop, andkeepane web statusshows who is connected. The QR code carries a new 128-bit key each start. It is plain HTTP, which is fine on a home network; from outside, go through Tailscale or a similar private network.
Your .tmux.conf, imported once
The same command names on the command line, in the : prompt and in the config file. keepane import-config brings what it can use from your tmux config into its own, once, the rest commented out with why.
set -g prefix C-a
set -g default-shell wsl # pwsh (default), powershell, wsl, cmd, or a path
set -g mouse on
set -g repeat-time 500 # how long a `bind -r` key keeps working
set -g monitor-activity on # mark a background window that prints
set -g remain-on-exit on # keep a pane whose program died
bind -r h select-pane -L # -r: press h h h after one prefix
bind | split-window -h
bind -n M-Right next-window # -n: no prefix at all
set -g status-right "#{pane_current_path} %H:%M"
- A command name can be cut to any unambiguous prefix (
keepane att,keepane splitw -h), and so can an option name:set syncmeansset synchronize-panes,set mon-act onmeansset monitor-activity on, and an on/off option given no value flips. keepane send-keys(tmux's-Xcopy-mode commands included),keepane capture-pane -p -eandkeepane split-windowdrive a session from a script. Run inside a pane, they need no socket name.- A plugin is a directory with a
<name>.keepanefile of commands plus scripts in any language, loaded withset -g @plugin name. Hooks fire on new windows, splits, pane exits and attaches.
Git branch, CPU and memory on the status line
The default status line shows your git branch, the pane's directory, CPU and memory use, and the battery if there is one. keepane reads these itself once a second without starting any helper process. You can replace the line with your own or turn it off.
[work] 0:editor* 1:build 2:logs master | ~\Documents\dfine\keepane | CPU 9% MEM 65% | 11:45
#{git_branch},#{cpu_percentage},#{ram_percentage},#{battery_percentage},#{pane_current_path_short}and#{pane_pid_command}(the program running in the pane right now) can go anywhere instatus-right.set -g status offhides the line.- When two terminals attach at different sizes,
window-sizedecides which one sizes the session. The smaller terminal sees part of the window and pans with Shift + arrows. - A right click pastes. At the : prompt, Tab completes commands, flags, targets and option names, and
keepane completion powershell(orbash,zsh,fish) gives your shell the same completions. keepane updateinstalls a new release, andkeepane restart-servermoves every running session to it with history and directories. Attached terminals reconnect on their own.
Install
Linux and macOS
A .tar.gz for each (static on Linux; Apple silicon and Intel). Unpack it and put keepane on your PATH.
Get itHomebrew
macOS and Linux, from the release's own builds; brew upgrade keepane takes a new version.
brew install newdee/tap/keepane
Windows installer
The .msi puts keepane in Program Files, on the system PATH, and in "Apps & features".
Get itScoop
The manifest in the repository installs the zip and follows releases.
scoop install https://raw.githubusercontent.com/newdee/keepane/master/packaging/scoop/keepane.json
From source
cargo install --git \
https://github.com/newdee/keepane --locked