You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every live terminal is a node-pty child of the orchestrator server process. Any server restart — nodemon picking up a code change, updating to a new version, a crash — kills all running Claude/Codex sessions. Conversations survive on disk (transcripts), but live TUIs are lost and restoration is manual. Separately, after a full reboot the recovery flow works but is not as robust as it should be (stale/duplicated lastConversationId entries were observed in session-recovery data on 2026-07-19).
Direction A — survive server restarts (the "hot reload" ask)
Decouple PTY ownership from the app server:
tmux-backed sessions (recommended): spawn each session inside a per-session tmux session (tmux new-session -d -s <sessionId>); the server attaches via tmux control mode (tmux -CC) or pipe-pane for output. On server restart, sessions keep running under the tmux server; the orchestrator re-attaches instead of respawning. Bonus: native scrollback survives too.
Alternative: a minimal long-lived pty-broker daemon (owns node-pty processes, unix-socket IPC to the app server). Same effect, more code to maintain; tmux gives it for free.
Scope note: nodemon should restart only the app server, never the tmux server; sessionManager's spawn/write/resize/kill paths route through the broker/tmux layer.
Direction B — survive reboots (resume hardening)
Nothing survives power-off except transcripts, so resume is the mechanism — make it excellent:
One-click / auto "restore all": relaunch each recovered terminal in its cwd with claude --resume <lastConversationId> (fall back to --continue when the id is missing/stale).
Fix conversation-id capture: several sessions shared identical stale ids (visual-novels work2/7/8, kpop-idol-empire, roblox-game-kit) — the detector is attributing the wrong transcript in some flows.
True process freezing (CRIU checkpoint/restore) — impractical under WSL2 and pointless for agents holding live API streams; those connections can never be thawed. Transcript + resume is the correct persistence model; A+B make it feel seamless.
Problem
Every live terminal is a node-pty child of the orchestrator server process. Any server restart — nodemon picking up a code change, updating to a new version, a crash — kills all running Claude/Codex sessions. Conversations survive on disk (transcripts), but live TUIs are lost and restoration is manual. Separately, after a full reboot the recovery flow works but is not as robust as it should be (stale/duplicated
lastConversationIdentries were observed in session-recovery data on 2026-07-19).Direction A — survive server restarts (the "hot reload" ask)
Decouple PTY ownership from the app server:
tmux new-session -d -s <sessionId>); the server attaches via tmux control mode (tmux -CC) or pipe-pane for output. On server restart, sessions keep running under the tmux server; the orchestrator re-attaches instead of respawning. Bonus: native scrollback survives too.Direction B — survive reboots (resume hardening)
Nothing survives power-off except transcripts, so resume is the mechanism — make it excellent:
claude --resume <lastConversationId>(fall back to--continuewhen the id is missing/stale)./api/sessions/:id/logon restore (shipped in PR fix: recompute terminal layout on mobile breakpoint changes #997) so restored terminals don't come back blank.Explicit non-goal
True process freezing (CRIU checkpoint/restore) — impractical under WSL2 and pointless for agents holding live API streams; those connections can never be thawed. Transcript + resume is the correct persistence model; A+B make it feel seamless.