Skip to content

Restore

Baidak.D edited this page Aug 18, 2026 · 4 revisions

English · Русский

kitty forgets everything the moment a tab closes: the panes, the directories, and — most painfully — which Claude Code session was running where. restore keeps a snapshot of the open windows in the background and brings them back, both automatically on start and on demand with Cmd+Shift+T.

It is not a kitten — there is no overlay and no UI. It is a kitty watcher: a small module that kitty loads into its own process and calls on events.

Enable

familiar enable --all                       # kittens + terminal config + restore
familiar enable session --restore-session   # just this, next to the session kitten
familiar enable --all --no-restore-session  # everything except this

familiar status prints restore: yes|no. Reload the kitty config (Cmd+Ctrl+,) — or restart kitty — to apply.

What comes back

The layout is serialized by kitty itself, so OS windows, tabs, splits and their proportions, layouts, titles and working directories return as they were. What runs inside each window is decided by familiar:

The window was running What is restored
claude claude --resume <that very session> — the same conversation, already on screen, in the same project directory. The session id comes from Claude Code's own registry of live processes (~/.claude/sessions/<pid>.json), matched to the window through the process tree — so several tabs in one project each come back with their own session.
an interactive program from the safe list — nvim, vim, emacs, helix, nano, htop, top, btop, lazygit, lazydocker, tig, less, bat, man, ranger, yazi, k9s the program itself, with its arguments (nvim src/main.py comes back on that file)
anything else the shell in the right directory, with the scrollback it had printed back above the prompt

Nothing else is re-executed. kitty's own --use-foreground-process would restart any command that happened to be in the window — familiar deliberately does not use it, so a git push or an rm caught by a snapshot never runs a second time.

Programs and scrollback are mutually exclusive on purpose: htop and friends paint over the printed screen with their first frame, so a window that restarts a program does not carry a scrollback dump at all.

Why the hotkey, if it restores on start

Cmd+Shift+T (Cmd+Shift+Е on the Russian layout) opens the last snapshot at any moment. It is not a duplicate of the automatic path:

  • kitty reads the startup session only when the process starts. On macOS closing every window leaves kitty itself running, so the next Cmd+N gives a blank window — the hotkey is what brings the snapshot back there.
  • Closed one tab by accident in the middle of a session? Same thing: press it, rather than restarting the terminal.

Note that it adds the snapshot to what is already open — it does not replace your current windows.

When a snapshot is taken

  • every 45 seconds in the background;
  • when a window is closed — the closing window is still part of kitty's state at that moment, so the tab you just lost is in that snapshot;
  • on quit (Cmd+Q).

Snapshots never overwrite the previous one with an empty state: kitty with no windows left writes nothing.

Where snapshots live

~/.local/state/familiar/restore/ (or $XDG_STATE_HOME), the last ten kept:

snapshots/0007/session.kitty-session   the session file kitty reads
snapshots/0007/sb-w3.txt               scrollback of one window
last -> snapshots/0007                 stable path for startup and the hotkey

The rotation matters: without it, the background timer would overwrite the snapshot that still had your accidentally closed tab a minute later. Older snapshots stay on disk and can be opened by hand:

kitten @ action goto_session ~/.local/state/familiar/restore/snapshots/0006/session.kitty-session

They contain terminal output, so anything that flashed on screen — tokens, keys, private paths — ends up in the files. They are written 0600 inside a 0700 directory, and each dump is capped at the last 2000 lines / 512 KB.

A snapshot whose state is identical to the previous one is not written at all: the background timer reads the windows, compares a digest and stops there. An idle terminal therefore costs no disk writes, and the rotation does not wash out snapshots that are still worth keeping.

familiar disable does not delete any of this — those are your session records. It prints the directory and its size instead, so removing it stays your call:

rm -rf ~/.local/state/familiar/restore

Closing safely

Cmd+Q opens a full-tab confirmation instead of kitty's built-in prompt — that one is drawn over the active window, so in a split it ends up the size of the split, which is easy to miss for something that closes the whole terminal. The screen also lists the Claude Code sessions running right now:

quit — the full-tab confirmation listing the running Claude Code sessions

The buttons are the same ones the kittens use when you close an overlay: ←/→/tab move the focus, enter presses the focused button, and they can be clicked. y quits outright, esc / n / Ctrl+C cancel and put the split layout back. Before leaving it takes a fresh snapshot, so whatever happened since the last background one is still there when you come back.

Cmd+W asks in the pane itself, and says what is running there:

close — the pane confirmation naming the Claude Code session

kitty's own question would have named the first foreground process it found — in a Claude Code pane that is usually caffeinate or an MCP server binary, printed with its full path. Here the pane says which project and which status, a plain program is named without its path (nvim src/main.py), and a pane sitting at a shell prompt still closes in a single press, no question asked. Pressing Cmd+W again does nothing — the key that raised the question does not answer it; esc / n / Ctrl+C and the No button cancel.

Answering Yes takes the whole pane with it. A session opened by the session kitten sits in an overlay over the shell it was called from, so closing just the overlay used to leave that shell behind — an empty pane where the session was. Now the split (or the tab, if it was the last split) goes as well.

Enabled with the terminal config, keys/safety.conf covers the rest: an OS window with more than one tab confirms on close.

Limits

  • Program state does not come back — unsaved nvim buffers, scroll position, the alternate screen, ssh sessions.
  • claude --resume starts on its own on every kitty launch. If that is too eager, familiar enable … --no-restore-session keeps the confirmation bindings and drops the snapshots.
  • Restoring commands rides on kitty's shell integration (enabled by default). With it off, tabs return with a plain shell.
  • If Claude Code's registry has no match for a window, that tab is restored as an ordinary one — familiar never falls back to claude --continue, which could attach the wrong session.

Clone this wiki locally