Skip to main content

termesh_core/
message.rs

1//! Typed application messages — the one channel the main loop wakes on (ARCHITECTURE.md §7.1).
2//!
3//! Every off-loop producer funnels into this enum: the terminal input pump, the
4//! filesystem worker, and the PTY, search, task, git, LSP, and ACP streams. The loop
5//! blocks on the *channel*, never on any single source, which is what lets a file-watch
6//! event repaint the tree without the user touching the keyboard (ADR-0005 §1).
7//!
8//! Backend-agnostic on purpose: crossterm types are translated in `app` before they get
9//! here, so `core` stays free of any terminal backend.
10
11use crate::agent::AgentEvent;
12use crate::fs::FsEvent;
13use crate::git::GitEvent;
14use crate::input::KeyChord;
15use crate::terminal::PtyEvent;
16use crate::SearchEvent;
17use crate::{LspEvent, LspServerId};
18
19/// A message from an off-loop producer to the single owner of application state.
20///
21/// Exhaustive on purpose: adding a producer should break every loop that has not
22/// decided what to do about it.
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum AppMessage {
25    /// A resolved key chord from the terminal input pump.
26    Input(KeyChord),
27    /// The terminal was resized. Ratatui re-measures on the next draw, so this carries
28    /// no dimensions — it exists to wake the loop so that draw happens.
29    Resize,
30    /// A result from the filesystem worker: a directory listing, a failure, or a
31    /// watch notification. The reason the loop can no longer block on the keyboard.
32    Fs(FsEvent),
33    /// A streamed workspace-search update.
34    Search(SearchEvent),
35    /// A result from the serialized Git worker.
36    Git(GitEvent),
37    /// A language-server event tagged with the session that produced it.
38    Lsp(LspServerId, LspEvent),
39    /// Output or lifecycle state from the PTY worker.
40    Pty(PtyEvent),
41    /// Something the agent produced — streamed text, an edit proposal, a permission
42    /// request.
43    ///
44    /// The agent worker feeds this channel exactly as the filesystem worker does, so the
45    /// scripted agent and the real ACP client reach the model through the same function.
46    /// A fake that took a different path would be testing a route the product never uses.
47    Agent(AgentEvent),
48}