parasite

Architecture

Crate Diagram

┌──────────────────────────────────────────────────────────────┐
│                    parasite-client                            │
│  TUI (ratatui) │ Components │ Dispatch │ SSH/Editor/Code     │
├──────────────────────────────────────────────────────────────┤
│                    parasite-core                              │
│  Protocol │ Config │ Scripts │ Crypto │ Auth │ Discovery     │
├──────────────────────────────────────────────────────────────┤
│                    parasite-agent                             │
│  Server │ Session │ PTY │ File Operations                    │
└──────────────────────────────────────────────────────────────┘

Both client and agent depend on parasite-core. The client and agent never depend on each other directly — they communicate over TLS using the shared protocol.

Data Flow

Connection Lifecycle

Client                          Agent
  │                               │
  ├── TCP connect ───────────────>│
  ├── TLS handshake ─────────────>│
  ├── HandshakeRequest { token } ─>│
  │<── HandshakeResponse { ok } ──┤
  │                               │
  │  ┌── Message loop ──────────┐ │
  │  │ ShellOpen/Data/Resize    │ │
  │  │ DirList/Create/Delete    │ │
  │  │ SystemInfoRequest        │ │
  │  │ Ping/Pong                │ │
  │  └─────────────────────────┘  │

Client Internal Flow

Terminal Events ──> EventHandler ──> App::handle_event()
                                         │
                                    Action dispatched
                                         │
                                    dispatch_action()
                                    ┌────┴─────────────┐
                                    │ connection.rs     │
                                    │ shell.rs          │
                                    │ editor.rs         │
                                    │ code.rs           │
                                    │ file_browser.rs   │
                                    │ operations.rs     │
                                    │ network.rs        │
                                    └──────────────────┘
                                         │
                                    Component::render()
                                         │
                                    Terminal Output

Key Patterns

Action-Based Architecture

All state changes flow through the Action enum. Terminal events, network messages, and timer callbacks all produce Action values that are sent through an MPSC channel and processed by the main dispatch loop.

// Terminal key press → Action
fn handle_key_event(&mut self, key: KeyEvent) -> Option<Action>;

// Network message → Action
Action::SessionNetworkMessage { session_id, msg }

// Timer/background task → Action
Action::EditorReady { sub_id, local_path, sync_name }

Component Trait

UI components implement a shared trait for consistent lifecycle:

pub trait Component {
    fn handle_key_event(&mut self, key: KeyEvent) -> Option<Action>;
    fn handle_action(&mut self, action: &Action);
    fn render(&mut self, frame: &mut Frame, area: Rect);
}

Implementations: DashboardView, FileBrowserView, ShellView, StatusBar, CommandPalette.

Session Hierarchy

App
├── AgentSession (connection to remote-1)
│   ├── SubSession: Shell #1
│   ├── SubSession: Editor (mutagen sync)
│   └── SubSession: VS Code
├── AgentSession (connection to remote-2)
│   └── SubSession: Shell #1
└── (more sessions...)

Each AgentSession holds an Arc<AgentConnection> for sending messages. Sub-sessions share the connection but have independent PTY/shell state.

Message Serialization

Messages are serialized with bincode and framed with a 4-byte length prefix:

┌──────────┬────────────────────┐
│ len: u32 │ bincode payload    │
└──────────┴────────────────────┘

Maximum message size: 16 MB (MAX_MESSAGE_SIZE).