Last time I built claude-sessions: one picker to resume any Claude Code session across projects. But a machine crash takes more than Claude with it — it takes your whole terminal
macOS window restoration exists, but it fails this job twice:
claude
sessions don't come back.A snapshot daemon plus an explicit restore — no auto-restore, ever.
Every 5 minutes, a launchd job walks every iTerm window and tab via AppleScript, and for each tab resolves the tty → the processes on it (ps
) → the working directory (lsof -d cwd
) → and whether a claude
process is running there, including which session: from its --resume
argument, from the transcript file it holds open, or from the newest transcript for that directory. The result is a small JSON file.
Snapshots accumulate as history — the last 100 distinct states, consecutive duplicates skipped, and an empty terminal never overwrites anything.
After a crash:
claude-sessions --restore-crash # newest snapshot
claude-sessions --restore-pick # or: fzf through history, pick the right one
Every tab comes back — as tabs of the window you're standing in — cd
'd to its old directory, with claude --resume <session-id>
rerun wherever Claude was live. Intentional quit? Just don't run it. You are the crash detector; that's the feature.
~/.claude/bin
→ iCloud), the timer dies with Operation not permitted
— macOS TCC silently denies background jobs access to ~/Library/Mobile Documents
. Point the plist at a local copy.Script, launchd template, and docs:
A cross-project session picker for Claude Code CLI.
Your machine crashes with seven Claude Code sessions open across five repos. claude --resume
only lists sessions for the directory you run it from — so recovery means remembering every repo you were in, cd
-ing into each one, and picking from a list, seven times.
claude-sessions
instead lists every session from every project in one fzf picker, newest first. Hit Enter and the session opens in a new iTerm tab (or tmux window) running claude --resume <id>
in the right directory — while the picker stays open for the next one.
enter open session in a new tab (picker stays open)
ctrl-a hide/show agent-teammate sessions (⛭)
ctrl-r refresh the list
esc quit
Each line shows the session's age, project directory, git branch (when not main/master), and its opening message. A preview pane shows the last few user/assistant exchanges of the…