Sessions and restarts
Closing the window doesn't end your work. Your shells and agents run in a background process, the session host, and the window only draws them. Close it, crash it or relaunch it, and every shell, agent, editor and scrollback keeps running; the next window you open picks them up where they are.
A session is the saved picture of a workspace: its tabs, splits, each pane's directory, each agent's resume command, sticky notes and the left bar's tree. Launching terminal-delight with no arguments takes the most recent session nobody else is using, and prefers a running host with no window attached.
If the host itself goes down, you still get your layout back. Terminal Delight reopens each pane in its directory and types the agent's resume command, such as claude --resume <id>, so every conversation continues. What doesn't come back is anything that only lived in memory: the scrollback, and programs like vim that can't resume.
TD_SESSION=work terminal-delight opens a named session. TD_SCRATCH=1 opens a throwaway window that never saves.
Story explains the host and the window with a television. Technical has the files, the rules for which session opens, and what is guarded.
The television and the station
Think of an old television on a sideboard. When you switch it off, the programmes don't stop. They keep broadcasting from the station, and when you switch the set back on you're watching whatever is on now, not the moment you left.
Most terminals are a television that is also the station. Close the window and the shows stop, because the shells lived inside the window. Your agent was halfway through a change, your build was running, and a server was tailing its logs, and all of it goes dark together.
Terminal Delight splits the two. The session host is the station: a small background process that owns every shell and agent in a session and keeps them running. The window is the set, drawing what the host sends it. You can close the set, kick its plug out, or swap it for a newer model, and the station keeps broadcasting. The next window tunes in to the same channel and you're back in the middle of every programme, scrollback and all. When nothing has been watching and nothing has happened for about twelve hours, the station takes a last picture of the schedule and closes for the night.
The station also keeps a schedule on paper: the session file. It lists every channel, where each one was filming (the pane's directory) and which episode each show was on (the agent's resume command). That paper is what saves you when the station itself burns down. A new station reads the schedule, rebuilds every channel, and starts each show from its last episode. The live programmes are lost: a film that was mid-scene, or a vim session with unsaved edits, only ever existed on the air. Every conversation with an agent comes back, because an agent can pick up from its own transcript.
One more rule keeps the schedule honest: only the station writes it. A set that has lost its station stops writing, so it can't overwrite a good schedule with a picture of a dead one. A save that would wipe out more than half your panes or tabs is refused unless you closed them yourself.
So you are left holding the real terms. The session host owns the terminals, the window is its client, the session file is the layout and resume recipe it writes, and the floor is the recovery from that file when the host is gone.
Sessions
A session has a stable name Terminal Delight owns, like 1, 2 or work, and its file is ~/.config/terminal-delight/sessions/<name>.toml (or under $XDG_CONFIG_HOME). The name is cleaned to letters, digits, - and _, up to 64 characters; default is used where nothing names one. Since 2026-09-10 the session host is on by default.1
Which session a launch opens#
$TD_SESSION, if set, wins over everything, even if that session doesn't exist yet.- A running host with no window attached.
- The most recently saved session with no host, preferring one last saved on the same Hyprland workspace, then one with more than a single pane.
- Otherwise, a new session.
A host someone is already watching is left alone; a second launch gets a different session. Two windows can share one session only if you name it, and then the most recent to attach takes each pane.
What the file records#
| Level | Keys |
|---|---|
| Window | the active tab, window bounds, scale, theme, lang, the left bar's projects, groups and width, MCP policy, and closed for panes held in the bay |
| Tab | name, color, text_color, group, project, level, and the split tree |
| Pane | cwd, resume, name, logo, appearance, the sticky note, the document it shows, and the host's pane_id |
Older files still load, and a file from before the left bar opens as an unfiled list of tasks. Writes are atomic, and the directory and files are owner-only (0700 and 0600). Before each write the previous file is copied to sessions/backups/<name>/, keeping the last ten. To go back to one, copy it over the session file; a running host notices and carries on from it.
How a resume command is chosen#
For each agent pane Terminal Delight reads the foreground process's working directory and writes a resume command:
| Agent | With a known conversation | Without |
|---|---|---|
| Claude Code | claude --resume <id> | claude --continue |
| Codex | codex resume <id> | codex resume --last |
--permission-mode, --model, --effort and --dangerously-skip-permissions are carried over. The conversation id comes from what the process declares, then from a transcript started at the same moment, then from the newest conversation in that directory, which is skipped when two agents share a directory. For an exact answer across /clear, /resume and compaction, install the ledger hook with scripts/install-recovery-hook.sh. terminal-delight probe <pid> prints what would be resumed for any shell, as JSON.
What comes back#
| Window closed or crashed | Host gone | |
|---|---|---|
| Tabs, layout, names, colours, the tree | yes | yes |
| Each pane's directory | yes | yes |
| Agent conversations | yes, still running | yes, resumed |
| Scrollback | yes | no |
Programs that can't resume (vim, htop, a build) | yes, still running | no |
| Sticky notes, documents, logos | yes | yes |
A reattached window matches each saved pane to the live terminal by its id, and then by the resume command it is running. If a saved layout names one conversation twice, the first pane keeps it and the second opens a fresh shell with the note DUPLICATE TAB, so an agent is never started twice.
Guards#
- Only the host writes the session file. A window whose host has gone stops saving, so it can't overwrite a good file with an empty one.
- A save that loses more than half the panes (of four or more) or tabs (of three or more) is refused unless you closed them yourself.
- The host saves every 30 seconds while a window is attached and every five minutes while none is, and it exits after about twelve hours with no window and no output, saving first.
- A host holds 64 terminals at most. Only closing a pane ends its shell; a window disconnecting ends nothing.
- Another user's process can't talk to your host: the connection is refused on its user id before a byte is read.
Kinds of window#
- a session window
- Owns a session and saves it. Its title is
terminal-delight — <name>, or plainterminal-delightfordefault. - a scratch window
TD_SCRATCH=1, or a pane torn off into its own window. One fresh terminal, never restores, never saves; it borrows the latest session's theme. Titleterminal-delight — scratch.- a window without a host
TD_NO_SESSIOND=1. The window owns its terminals, as in older builds, and holds the session with a file lock.
Inside a hosted pane the host sets TD_SESSION, TD_PANE_ID and TD_TAG, which agents use to find their own pane. See Environment flags.
Files#
| Path | Is |
|---|---|
sessions/<name>.toml | The session. |
sessions/backups/<name>/ | The last ten versions. |
sessions/<name>.host.lock | Which host serves it. |
$XDG_RUNTIME_DIR/terminal-delight/session-<name>.sock | The host's socket, with .log, .tag and .window beside it. |
Not yet#
- Replacing the host, for example after an upgrade, still ends every terminal in that session. A handover that keeps them is planned.
- There is no command to list or stop hosts; a host exits when idle or when its process is ended.
What would prove this wrong#
Kill the window, not the host, and relaunch. If a single shell, agent or scrollback is missing, the split has failed. The project's survival test does exactly this twenty times in a row, and on 2026-09-11 it lost nothing.2
Sources
- Session files, adoption and locks: instance.rs; the host: host.rs and the session host protocol; resume commands: session.rs.
- The measurements, including 0 losses over 20 window kills: the client-server plan's status, and the harness td-survival-test.sh.