# `2.5.0` PTY Shell Sessions ## Goal Add persistent interactive shells so an agent can inhabit a workspace instead of only submitting one-shot `workspace exec` calls. ## Public API Changes - CLI: - `pyro workspace shell open` - `pyro workspace shell read` - `pyro workspace shell write` - `pyro workspace shell signal` - `pyro workspace shell close` - SDK: - `open_shell` - `read_shell` - `write_shell` - `signal_shell` - `close_shell` - MCP: - `shell_open` - `shell_read` - `shell_write` - `shell_signal` - `shell_close` Core shell identity: - `workspace_id` - `shell_id` - PTY size - working directory - running/stopped state ## Implementation Boundaries - Shells are persistent PTY sessions attached to one workspace. - Output buffering is append-only with cursor-based reads so callers can poll incrementally. - Shell sessions survive separate CLI/SDK/MCP calls and are cleaned up by `workspace delete`. - Keep `workspace exec` as the non-interactive path; do not merge the two models. ## Non-Goals - no terminal UI beyond structured shell I/O - no service lifecycle changes in this milestone - no export/diff/snapshot/reset changes yet ## Acceptance Scenarios - open a shell, write commands, read output in chunks, send SIGINT, then close - reopen a new shell in the same workspace after closing the first one - delete a workspace with an open shell and confirm the shell is cleaned up ## Required Repo Updates - shell-focused example in CLI, SDK, and MCP docs - help text that explains shell vs exec clearly - real Firecracker smoke for open -> write -> read -> signal -> close