oss

tmux-ide is an open-source project by Prototyper.View source(opens in a new tab)

tmux-ide home

Move to tmux-ide's own tmux

tmux-ide servers upgrade restarts a tmux server on tmux-ide's own tmux and restores its sessions. How it works, and recovery after a kill-server.


tmux-ide servers upgrade moves a running tmux server onto tmux-ide's own tmux. It saves a snapshot of every session, checks the snapshot, asks you, restarts the server and rebuilds your sessions on the new one. Use it when tmux-ide doctor reports "stock tmux: reduced features" or "older tmux-ide tmux".

Restarting a tmux server ends every program in it. The command brings back the layout and your agents' conversations, never the running processes. Read what it lists before you answer.

Run it

tmux-ide servers upgrade

The command first prints what it is about to end. The first line names the machine and the server's socket:

This ends 4 sessions and 3 agents on spark-04ad (/tmp/tmux-1000/default).
The server runs stock tmux 3.5a (/usr/bin/tmux).
tmux-ide's own tmux (3.7c) has every feature. Moving restarts the server.

These sessions close and come back:
  api  3 windows, 7 panes
  web  1 window, 2 panes
  ...

Agents (3):
  api:0.1  claude  working  /work/api  resumes its conversation
  api:0.2  codex   idle     /work/api  resumes its conversation
  web:0.1  gemini  idle     /work/web  ends; no saved conversation id
1 agent is mid-turn. Its current turn will be lost.

Snapshot saved: ~/.tmux-ide/upgrades/2026-11-10T09-12-03-120Z/snapshot.json
Restart the server and restore? [y/N]

The answer defaults to No. Nothing has stopped at this point.

FlagWhat it does
--dry-runPrint the plan and stop. Nothing is stopped.
--jsonPrint one JSON result. Without --yes it is a dry run.
--yesSkip the question. Refused while something may be an agent at work (see below).
--end-running-agentsWith --yes, end those agents and programs too.
--no-resume-agentsDo not reopen agent conversations after the restart.
--socket-path PATHUpgrade the server on this socket.
--socket-name NAMEUpgrade the server started with tmux -L NAME. Not together with --socket-path.
--ssh HOSTRun the same command on HOST, against that machine's server and tmux.

Without either flag, the command upgrades the server named by TMUX_IDE_TMUX_SOCKET_PATH or TMUX_IDE_TMUX_SOCKET_NAME (as tmux-ide doctor reads them), else the server your shell runs in, else tmux's default socket.

What happens, step by step

  1. The command finds the server and asks it for its socket, process id and version. If the server already runs tmux-ide's own tmux, it says so and stops.
  2. It checks tmux-ide's own tmux on a throwaway server in a temporary folder. If that tmux is missing or lacks features, it stops.
  3. It writes a new snapshot to ~/.tmux-ide/upgrades/<time>/snapshot.json, reads it back and compares it with a fresh listing of the server. Every session, window and pane must be in it, with a layout per window and a folder per pane. Otherwise it stops and names what is missing.
  4. It prints the plan and asks.
  5. It lists the server once more. If a session, window or pane changed while you read the plan, it takes a new snapshot and asks again.
  6. It prints the snapshot's path and the exact tmux-ide restore --from … line that rebuilds from it. This happens in every mode, --yes and --json included, before anything is ended.
  7. It starts a background process that does the rest, and prints its log path. The background process has no terminal, so closing the terminal, Ctrl-C, a hangup or a dropped --ssh connection does not stop it. The command waits for its result and prints it; if you stop the wait, the restart carries on and logs to ~/.tmux-ide/upgrades/<time>/log.
  8. The background process checks that the server is still the same one and that the snapshot still covers it. Then it ends that exact server. tmux checks the process id and start time itself, so a newer server on the same socket is never ended.
  9. It starts the new server with tmux-ide's own tmux and your usual tmux config, then rebuilds every session from the snapshot.
  10. It checks the new server reports full features and has the same sessions, windows and panes. A server whose features can't be read counts as a failure.

Sessions that come from a workspace config are rebuilt from the snapshot too, so their configured commands do not run again.

When --yes alone is refused

The command can't tell what every pane is doing, so --yes alone refuses to end anything that may be an agent at work. It refuses, and stops nothing, when any of these is true:

  • An agent pane reports working or blocked. A working or blocked report older than 10 minutes counts as no report.
  • An agent pane sent no state report, or its last idle or done report is more than an hour old. The agent may have started a turn its hooks never reported.
  • A pane runs a program that is neither a shell nor an agent tmux-ide recognises: a dev server, an editor, or an agent it can't name. The plan lists these under "These programs stop".
  • A pane in a session that is not restored (a name starting with _ or zz-) runs an agent or a program. tmux-ide's own hidden sessions, whose names start with _tmux-ide, don't count.

The pane the command runs in never counts: running the command is your consent for it.

At the prompt, the plan shows the same lists and the answer still defaults to No. Wait until the agents are idle, or pass --yes --end-running-agents.

When something fails

What failsWhat happens
No server, or no tmux-ide tmux on this machineExits 1. Nothing is stopped.
The snapshot can't be written, read or checkedExits 1 and names the problem. Nothing is stopped.
You answer NoExits 0. Nothing is stopped.
The server won't endExits 1 with the snapshot path and the restore line. The old server keeps running.
Another server answers on the socket after the endRebuilds the sessions into that server, skipping names it already has.
The background process does not report backExits 1 with its log path and the restore line.
tmux-ide's tmux can't start the new serverRestores your sessions on the old tmux when it can, says so and exits 1.
One session fails to rebuildRebuilds the rest, names the failed one and exits 1. The snapshot stays; retry with tmux-ide restore --from <file>.
The new server lacks features, or they can't be readKeeps the sessions, reports it and exits 1.

Running it from inside the server

If your terminal runs inside the server you upgrade, ending the server closes your terminal too. The command finds this out from $TMUX or, when $TMUX is unset or points elsewhere, from its own process tree. It then does not wait for the background process and tells you where it logs:

This terminal runs inside that server and closes in a moment. Reopen tmux-ide
or run `tmux attach` in a few seconds. Log: ~/.tmux-ide/upgrades/<time>/log

The background process does the same checks as always before it ends anything. Keep the pane open until the server restarts: if the pane that ran the command closes first, the snapshot no longer covers the server, and the background process stops without ending anything.

What comes back and what doesn't

Comes back: sessions, windows and their names, split layouts, the active window, each pane's folder, pane titles, adopted tmux chrome, and agent conversations that tmux-ide captured an id for (see Restore and resume).

Does not come back:

  • Running programs: dev servers, SSH connections, editors (unsaved changes are lost), REPLs, watch, builds.
  • Shell state: variables, aliases and functions set by hand, an activated virtualenv, background jobs.
  • Scrollback.
  • Options set with set-option at runtime that are not in your tmux config.
  • Extra flags an agent was started with. A Claude Code pane comes back as claude --resume <id>; flags such as --dangerously-skip-permissions are not repeated.

Keep a plain tmux from starting the old server

tmux-ide's own commands start a new server with tmux-ide's tmux. A plain tmux typed in a shell runs whatever tmux is first on your PATH, often Homebrew's or the system's. If that starts the server, you are back on reduced features.

Since this release, when no tmux server is running, every tmux-ide command starts it with tmux-ide's own tmux, even when another tmux is first on your PATH. A server that already runs keeps the tmux on your PATH as its client. To keep using another tmux for everything, name it:

export TMUX_IDE_TMUX_BIN=/opt/homebrew/bin/tmux

tmux-ide doctor shows what a plain tmux runs on the "plain tmux in your shell" row. tmux-ide installs no shim and never shadows your tmux. If you want a plain tmux to start tmux-ide's tmux, start the server from tmux-ide (tmux-ide, tmux-ide restore or tmux-ide servers upgrade) before you type tmux. Once a server runs, any tmux client talks to it.

Recover after an upgrade

If the upgrade exits 1 after the server ended, your snapshot is still on disk. Rebuild from it:

tmux-ide restore --from ~/.tmux-ide/upgrades/<time>/snapshot.json --resume-agents

Sessions that are already running are skipped, so you can run it more than once. Preview first with --dry-run. Unlike the upgrade, a plain tmux-ide restore --from relaunches sessions that belong to a project with a workspace config from that config, which runs its configured commands again. Other sessions are rebuilt from the snapshot.

Recover after an accidental kill-server

tmux kill-server, a crash or a reboot ends every session. The steps below bring back the layout and the agent conversations.

  1. Check how old the snapshot is. tmux-ide doctor shows the age on the "crash snapshot" row, and a dry run prints its time:

    tmux-ide restore --dry-run

    The snapshot is written only while the chrome updater runs, that is while at least one session is adopted. A server started by a script or a plain tmux has no updater, and the snapshot can be days old.

  2. Rebuild from it, with the agents' conversations:

    tmux-ide restore --resume-agents
  3. Reopen agents the snapshot missed. Claude Code keeps every conversation on disk, per folder, in ~/.claude/projects/. Open a pane in the agent's folder and pick the conversation:

    cd /path/to/the/agent/folder
    claude --resume

    claude --resume with no id lists that folder's recent conversations. To find them by hand, look in the folder's own directory under ~/.claude/projects/. Its name is the folder's path with every character that is not a letter or digit replaced by -:

    cd /path/to/the/agent/folder
    ls -t ~/.claude/projects/$(pwd | sed 's/[^A-Za-z0-9]/-/g')/*.jsonl | head

    Each file name, without .jsonl, is a conversation id for claude --resume <id>. The newest file is the most recent conversation. Codex keeps its sessions in ~/.codex/sessions/, and codex resume lists them.

  4. Adopt the sessions so the snapshot stays current:

    tmux-ide adopt --all

To end a server on purpose, use tmux-ide servers upgrade or end single sessions, not tmux kill-server.

See also