Skip to main content

lash_core/
monitor.rs

1use std::collections::BTreeMap;
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6const fn default_monitor_timeout_ms() -> u64 {
7    300_000
8}
9
10pub const MAX_MONITOR_TIMEOUT_MS: u64 = 3_600_000;
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
13#[serde(rename_all = "snake_case")]
14pub enum MonitorArmOn {
15    #[default]
16    Manual,
17    SessionStart,
18}
19
20#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
21#[serde(rename_all = "snake_case")]
22pub enum MonitorWakePolicy {
23    Notify,
24    #[default]
25    QueueTurn,
26}
27
28#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
29pub struct MonitorSpec {
30    pub id: String,
31    pub command: String,
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub cwd: Option<String>,
34    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
35    pub env: BTreeMap<String, String>,
36    #[serde(default)]
37    pub persistent: bool,
38    #[serde(default = "default_monitor_timeout_ms")]
39    pub timeout_ms: u64,
40    #[serde(default)]
41    pub arm_on: MonitorArmOn,
42    #[serde(default)]
43    pub wake_policy: MonitorWakePolicy,
44    #[serde(default)]
45    pub restart_on_restore: bool,
46}
47
48#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
49#[serde(rename_all = "snake_case")]
50pub enum MonitorRunState {
51    #[default]
52    Idle,
53    Running,
54    Stopped,
55    Exited,
56    Failed,
57}
58
59#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
60pub struct MonitorStatus {
61    pub spec: MonitorSpec,
62    #[serde(default)]
63    pub armed: bool,
64    #[serde(default)]
65    pub state: MonitorRunState,
66    #[serde(default, skip_serializing_if = "Option::is_none")]
67    pub last_event: Option<String>,
68    #[serde(default, skip_serializing_if = "Option::is_none")]
69    pub last_error: Option<String>,
70    #[serde(default, skip_serializing_if = "Option::is_none")]
71    pub last_exit_status: Option<i32>,
72    #[serde(default)]
73    pub event_count: usize,
74}
75
76#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
77pub struct MonitorEvent {
78    pub sequence: u64,
79    pub monitor_id: String,
80    pub message: String,
81    #[serde(default, skip_serializing_if = "Option::is_none")]
82    pub queue_turn_input: Option<String>,
83}
84
85#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
86pub struct MonitorSnapshot {
87    #[serde(default)]
88    pub revision: u64,
89    #[serde(default)]
90    pub active_count: usize,
91    #[serde(default)]
92    pub monitors: Vec<MonitorStatus>,
93}
94
95#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
96pub struct MonitorUpdateBatch {
97    #[serde(default)]
98    pub revision: u64,
99    #[serde(default)]
100    pub active_count: usize,
101    #[serde(default)]
102    pub events: Vec<MonitorEvent>,
103}