"""Keep-alive PTY sessions for dashboard terminals. A PTY process outlives the WebSocket that created it: a single drain task always reads the PTY into a bounded RingBuffer and forwards to the attached socket when present. Reconnecting with the same opaque token replays the buffer and resumes live. See docs/superpowers/specs/2026-06-20-pty-keepalive-reattach-design.md. """ from __future__ import annotations class RingBuffer: """Keeps only the most recent ``capacity`` bytes appended to it.""" def __init__(self, capacity: int) -> None: self._cap = capacity self._buf = bytearray() self._truncated = False def append(self, data: bytes) -> None: self._buf.extend(data) overflow = len(self._buf) - self._cap if overflow > 0: del self._buf[:overflow] self._truncated = True def snapshot(self) -> bytes: return bytes(self._buf) @property def truncated(self) -> bool: return self._truncated