v2.8.1 — Session Recovery Stability Hotfix
@alphabeen 이 v2.8.0 출시 직후 보고한 세 가지 회귀 — 시간이 갈수록 wmux 가 사용 불가 상태로 빠지던 critical, recovered pane 출력이 깨지던 high, 매 시작마다 generic 에러 토스트가 뜨던 medium — 을 한 릴리스에 묶어 수정한다. v2.8.0 사용자는 즉시 업그레이드 권장 — 자동 마이그레이션이 누적된 sessions.json 을 첫 실행 시 정리한다.
What's fixed
🧨 Critical: 세션 누적으로 인한 brick 상태
v2.8.0 의 세션 영속화가 (1) 복구 횟수 상한이 없고 (2) 비명시 종료 세션이 영원히 남아 4–5 회 재시작이면 MAX_SESSIONS=50 소진. UI 에서 Ctrl+T 도 안 먹히고 generic "알 수 없는 오류" 토스트 도배 → 자가복구 불가능 상태에 빠지던 문제.
- Suspended 7-day TTL: 7 일 이상 inactive 한 suspended 도 prune. v2.8.0 의 누적된
sessions.json도 첫 v2.8.1 실행 시 자동 정리. - Recovery soft cap 40: 복구 후보를
lastActivity내림차순 상위 40 개만 PTY 재생성. hard cap 50 에 도달해도 항상 신규 pane 헤드룸 10 슬롯 보장. - Actionable error message: cap 도달 시 generic "알 수 없는 오류" 대신
Cannot create new terminal: 50 active sessions already running. Close some panes (or restart wmux) and try again..
⚠️ High: 복구된 pane 출력 interleave
저장 시점 PTY cols/rows 와 새 renderer geometry 가 어긋나 같은 줄에 두 paint 의 문자가 interleave 되던 문제 (예: Accessing workspace: → Accessingwworkspace:).
- Deferred output mode: recovery 경로의 createSession 이
deferOutput: true로 시작 → bridge muted → 첫 resize 후 100 ms unmute. ConPTY 가 옛 geometry 에서 큐잉했던 출력은 drain & 폐기. - 저장된 scrollback 은 ring buffer 직접 pre-fill 이라 보존됨.
🟡 Medium: 시작 시 generic 에러 토스트 폭주
main 의 daemon connect 가 비동기로 도는 동안 renderer 가 IPC 호출 → handler swap 무등록 윈도우에 떨어진 호출이 No handler registered 로 실패 → "알 수 없는 오류가 발생했습니다." 토스트 5–10 회 도배.
- main 이 단일 IPC handler
daemon:get-ready-state를 swap cycle 바깥에 등록. - preload 의
daemon.whenReady()가ipcRenderer.invoke사용 — renderer reload (crash recovery) 이후에도 정상 응답 (codex P2 fix). AppLayout첫 reconcile 이daemon.whenReady()await 후pty.list/pty.reconnect.
Additional stability fixes
같은 hotfix branch 에서 발견·수정한 추가 4 건:
- Split 후 빈 pane placeholder 영구 잔존 — AppLayout auto-PTY effect 의 deps 가
activeWorkspace.id만이라 split 으로 추가된 새 leaf 가 trigger 안 됐던 문제. - 한글 IME 상태에서 Ctrl+D / Ctrl+Shift+D 미작동 — Hangul 레이아웃의
e.key === 'ㅇ' / 'Process'미스매치. 두 곳에e.code === 'KeyD'폴백 추가. - 분할 pane 키보드/마우스로 못 닫음 —
Ctrl+Wcascade +SurfaceTabsstrip 무조건 렌더 +Ctrl+Shift+Q추가 + i18n 4 locale 라벨 정리. - Reconnect 후 출력 두 줄 중복 —
pty.handler의daemonClient.on('session:data', ...)listener 누적 → per-session listener map 으로 분리.
Migration
자동. 첫 v2.8.1 실행 시 StateWriter.load 가 7 일 이상 묵힌 suspended 세션을 prune. 추가 액션 불필요. v2.8.0 에서 이미 brick 된 사용자도 업그레이드 후 정상 복구 (alphabeen 가이드 수동 파일 삭제 절차 더 이상 필요 없음).
외부 MCP 통합 측에 변경 없음 — 모든 변경은 daemon 내부 + main↔renderer IPC 가드.
Reviews & Tests
/plan-eng-reviewCLEAR (4 architecture decisions resolved)/codex reviewcaught one P2 (event-based whenReady deadlocks on renderer reload). Fixed via invoke-style query.- 929 tests passing (+18 vs v2.8.0)
- Bug 1 dynamic-verified via bundled-daemon subprocess (50-session brick scenario reproduced & resolved)
- Bug 2/3 GUI-verified via CDP probe + visual observation
Closes #22.
🤖 Generated with Claude Code — team mode
Full Changelog: v2.8.0...v2.8.1
What's Changed
- fix(v2.8.1): session recovery hotfix (closes #22) by @openwong2kim in #24
Full Changelog: v2.8.0...v2.8.1