Design
How it works
The daemon, the per-session shim, SQLite, and what survives each kind of failure.
In this guide
Guide
On this page
The daemon
One daemon process per machine owns every session. Your app, the CLI, and MCP clients all talk to it over the unix socket, HTTP/WebSocket, or MCP — never directly to a terminal. That is what lets your app crash without taking a session down: the session was never inside your app's process.
Per-session shims
Each session has its own small helper process — the shim — that owns the PTY master and the child process underneath it. The daemon connects to the shim over a local socket, says how far into its output it has already read, and gets everything since, then live output as it happens.
When the daemon restarts, it reconnects to the still-running shim, catches up on whatever output it missed while it was down, and the session itself never stopped. dpty stop leaves every session's shim running by default; dpty stop --sessions stops them too.
SQLite
Everything durable — sessions, scrollback, typed commands, events — is written to SQLite in ~/.durable-pty/dpty.db (override with DPTY_HOME). Up to 16 MB of output is kept per session. Typed commands are not recorded while a session's terminal has echo off (password prompts) or a full-screen app is in control. Session environment — PATH, HOME, locale, agent API variables, plus anything passed with -e — is stored too, so recovery can relaunch with the same environment; --env-all stores everything instead of the defaults.
Recovery
| Event | What happens |
|---|---|
| Your app / browser crashes | Nothing happens to the session. Reattach by id, name or label; you get the current screen, then live output. |
| Daemon crashes or restarts | If a session's shim is still running, the daemon reattaches and catches up on missed output — nothing lost. If the shim is also gone, the session is marked lost, then relaunched per its restart policy, same id, history kept. |
| Machine reboots or you log out | Every process dies, shims included — nothing can prevent that. Sessions and their history survive in SQLite and are restored the next time the daemon starts. |
| A session crash-loops | Capped at 5 automatic restarts per 60 seconds, then dpty gives up and records it as restart-loop. |
Limits
Not for Windows
macOS and Linux only.
A reboot still ends running processes
The shim survives a daemon restart, not a machine reboot or logout. The OS kills everything then.
History and resume remain
Scrollback, typed commands and events are in SQLite before anything crashes, so the record survives even when the process does not.
Agent resume is best-effort
claude and codex are resumed by session id with the original prompt dropped. Other agents need --resume-cmd or the tag-agent hook.