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}