Auto-resume: when one Activity-Monitor kill took down every session, recovery shouldn't be manual
A single force-quit in Activity Monitor (the shared `-L dalkkak` tmux server) killed every pane's shell + Claude process at once — the documented SPOF, realized. The conversations survived (transcripts are durable on disk), but recovery was MANUAL: you had to type `claude --resume` in each pane. For a tool meant to be a daily operating system, manual recovery is a real weakness. Fix: the renderer now auto-resumes a pane's previous session on respawn — it already knows pane→transcript from the hook store, so it types `claude --resume <session-id>` into the fresh shell once. Reopen the app → your sessions come back.
The scare
Mid-work, a force-quit in Activity Monitor hit the shared -L dalkkak tmux server — the one process that holds every pane's shell. It died, and with it every pane + the Claude running in each, all at once. This is exactly the single-point-of-failure we'd already written down (one server = one shared fate). It felt catastrophic.
Why it wasn't catastrophic — and why it still wasn't fine
Durable: Claude Code writes each conversation to ~/.claude/projects/.../<id>.jsonl continuously. So the history survived — nothing important was lost. claude --resume reads that transcript and continues.
Not fine: recovery was manual. You had to go pane by pane and type claude --resume, pick the session. The app did nothing automatic. Honest cold verdict at the time: "history is durable; recovery is manual and best-effort" — not the "reopen and everything's back" a daily driver needs.
The fix: renderer-side auto-resume
We already have the missing piece: the Claude Code hooks record a pane → transcript_path mapping (session-events.jsonl, replayed by recover_sessions on mount). The session-id is just the transcript filename. So on a pane respawn:
autoResume(id)(interminalRegistry) waits briefly for the shell prompt + the async pane→transcript mapping, then — if this pane had a prior session — typesclaude --resume <session-id>into the fresh shell once (guarded by a per-pane flag).- A fresh pane (no prior session) gets a normal shell — no resume.
- Done in the renderer on purpose: it leaves
pty.rs(the spawn path that has caused regressions before) untouched. Worst case is a harmlessclaude --resume Xthat errors visibly in the pane, not a broken spawn.
Effect: quit + reopen the app → every pane that had a Claude session picks it back up automatically. The Activity-Monitor scare becomes a near-non-event.
Honest limits (cold)
- This covers the common path (app restart). The mid-session case — a pane's PTY dies while the app keeps running — still needs death-detection + auto-respawn (not built yet).
- An in-flight turn (a response mid-generation when the kill lands) can still be lost — inherent to any process death; no app fully avoids it.
- "Guaranteed recovery" is still not 100% (power-cut last-seconds, in-flight turns). But auto-resume moves us from "manual, best-effort" much closer to "reopen and it's back."
- Blind-built (can't see the running app) + auto-types into the shell — timing (the 800 ms prompt-settle + retries) is the fragile part; needs real-app verification.