//! Wire message types exchanged between an attached client and the //! daemon over the `Connection`/framing layer (`conn.rs`, `frame.rs`). //! //! Flow: client input events are captured as `KeyAction`/`ClientRequest` //! and sent to the daemon → the daemon applies them to its `AppStateRest` //! and replies with `DaemonFrame` variants (a flattened `StatePayload` //! for redraw, streamed tokens, system notes, or a close signal). //! //! Why: `StatePayload`/`MessageEntry`/`ToastEntry` are deliberately flat, //! serializable projections of daemon-side state so the client can //! redraw its TUI without sharing any in-process state with the daemon. use serde::{Deserialize, Serialize}; /// Wire-serializable subset of `crossterm::event::KeyCode`, sent from /// an attached client to the daemon over IPC. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum KeyAction { Char(char), Enter, Escape, Backspace, Delete, Tab, Up, Down, Left, Right, Home, End, PageUp, PageDown, Function(u8), } /// Messages an attached client sends to the daemon: input events, a /// full-line submit, terminal resize, and connection lifecycle. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ClientRequest { Tick, KeyPress { key: KeyAction, ctrl: bool, alt: bool, shift: bool, }, Submit(String), Resize(u16, u16), Close, } /// Flattened chat message sent from daemon to client for transcript display. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MessageEntry { pub role: String, pub content: String, pub timestamp: i64, } /// Flattened toast notification sent from daemon to client for rendering. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ToastEntry { pub kind: String, pub message: String, pub created_at: i64, pub lifetime_ms: u64, } /// Snapshot of daemon-side `AppStateRest` sent to the client after every /// action, enough for the client to redraw its TUI without shared state. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StatePayload { pub session_id: String, pub messages: Vec, pub edit_count: u32, pub message_count: usize, pub overlay: Option, pub toasts: Vec, pub dirty: bool, pub input_buffer: String, pub input_cursor: usize, } /// Messages the daemon sends back to an attached client. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum DaemonFrame { StateUpdate(Box), StreamToken(String), SystemNote { kind: String, message: String }, Closed, }