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}