Persistence and Restore
What Daintree persists across a restart and how it comes back: panel layout, terminal scrollback serialization and its limits, the restore banner, typed drafts, where it is all stored, and how to turn it off.
What survives a restart
Daintree saves workspace state to disk and restores it the next time you open the project. This happens on its own; there is nothing to turn on.
Per terminal
- Scroll buffer: serialized to disk and replayed on reopen.
- Panel arrangement: which panels are open, where they sit in the grid, and their sizes.
- Custom panel names: a name you set by double-clicking a tab title or through Rename in the context menu comes back, and keeps precedence over whatever title the terminal or agent would otherwise set.
- Typed but unsent drafts: see below.
- Launch environment: the environment the panel was launched with, so a restored agent comes back on the same provider.
Per project and per app
- Active worktree, and which terminal had focus in each worktree
- Sidebar width, window position, size, and maximized or fullscreen state
- Portal tabs, links, default target, and width
- Per-panel resize ratios
- Focus mode state (see Terminals & Panels)
Scroll buffer serialization
Each terminal's scroll buffer is serialized with xterm's serializer and written to a .restore file. The file carries a version header and the <cols>x<rows> grid it was captured at, so the replay is parsed at the geometry it was written for rather than reflowed against whatever the panel happens to be now.
When a snapshot is taken depends on what's running in the terminal:
- Plain terminals debounce: Daintree waits five seconds after output settles, then writes.
- Agent panes skip the debounce entirely and write on agent-state settles instead (waiting, completed, exited), throttled to at most one write every two seconds, with a final flush when the terminal is killed. An agent's meaningful moments are its state transitions, not a gap in output.
Terminals under 1,000 lines serialize synchronously. Larger buffers use an async path that yields to the event loop, so serializing a full agent buffer doesn't stall the PTY host during an active run.
The restore banner
When a terminal is reopened, its .restore file is replayed and a dim separator marks the top of the restored content. The timestamp is the snapshot's own, formatted YYYY-MM-DD HH:MM:
─── Session restored · <timestamp> ───, a normal restore.─── Restored · <timestamp> · previous session was in a full-screen app ───: the terminal was in a full-screen program such asvimorhtopwhen the snapshot was taken.─── Session hibernated · <timestamp> · auto-suspended to save resources ───: the project's memory was reclaimed while it was in the background, by Free memory or by idle auto-close. The scrollback is still replayed; the banner tells you why the process behind it is gone.
Serialization limits
Daintree keeps up to 5 MB of serialized scroll buffer per terminal. At roughly 250 bytes per line including ANSI color codes, that is around 20,000 lines, comfortably above an agent terminal's 10,000-line ceiling in ordinary output, but not by the margin the number suggests. Densely colored output (a full-color diff, verbose logging with escape sequences) pushes well past 250 bytes a line and can bring a long agent buffer within reach of the cap.
For the scrollback line limits themselves, and where to change them, see Terminals & Panels.
Drafts
Text you've typed into a terminal's input but not sent survives a window close. Drafts are flushed when the view tears down and persisted with the project's state, using the same merge-safe delta contract as the layout: each window sends what it changed against its own last-acknowledged baseline, so two windows open on the same project merge rather than overwrite each other.
Scratch workspaces
A scratch workspace persists and restores its panel grid the same way a project does. Scratches get a state directory in the same namespace as projects (a scratch id can never collide with a project id), so they inherit the whole atomic-write, quarantine and recovery machinery rather than a parallel, less-tested version of it. Terminals in a scratch are journaled under the scratch id, so their sessions are resumable too.
Storage and eviction
Daintree manages the terminal-sessions/ directory inside its app data directory on its own:
- 30-day TTL: session files older than 30 days are deleted on startup.
- 100 MB total cap: if the directory exceeds 100 MB, the oldest files are evicted first.
- Orphan cleanup: files for terminals that no longer exist are removed on startup, along with any leftover temporary files from an interrupted write.
- Panel removal: deleting a terminal panel removes its
.restorefile. For agent panels that happens after the 20-second trash window closes, not the moment you close the panel.
Disabling persistence
To turn terminal session persistence off entirely, set DAINTREE_TERMINAL_SESSION_PERSISTENCE=0 before launching Daintree. Only the literal value 0 disables it: any other value leaves persistence on. This is a developer escape hatch, not a regular setting.