1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4use chrono::{DateTime, Utc};
5
6use crate::{Lifecycle, LostEvidence, VersionInfo};
7
8#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
9pub struct KillByPidRequest {
10 pub pid: u32,
11 pub signal: i32,
12 pub grace_secs: u64,
13}
14
15#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
16pub struct KillByPidResponse {
17 pub pid: u32,
18 pub signal: i32,
19 pub killed_after_grace: bool,
20}
21
22#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
23pub struct StatusFilter {
24 pub session_id: Option<Uuid>,
25 #[serde(default, skip_serializing_if = "Vec::is_empty")]
26 pub session_ids: Vec<Uuid>,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub updated_since: Option<DateTime<Utc>>,
29 pub runtime: Option<String>,
30 pub state: Option<String>,
31}
32
33impl StatusFilter {
34 pub const fn empty() -> Self {
35 Self {
36 session_id: None,
37 session_ids: Vec::new(),
38 updated_since: None,
39 runtime: None,
40 state: None,
41 }
42 }
43
44 pub fn requested_session_ids(&self) -> Vec<Uuid> {
45 let mut ids = self.session_ids.clone();
46 if let Some(session_id) = self.session_id
47 && !ids.contains(&session_id)
48 {
49 ids.push(session_id);
50 }
51 ids
52 }
53}
54
55impl Default for StatusFilter {
56 fn default() -> Self {
57 Self::empty()
58 }
59}
60
61#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
62pub struct StatusResponse {
63 pub lifecycles: Vec<Lifecycle>,
64}
65
66#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
67pub struct WatcherCounts {
68 pub kqueue_watchers: usize,
69 pub shim_sockets: usize,
70}
71
72#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
73pub struct LifecycleCounts {
74 pub forking: u64,
75 pub running: u64,
76 pub exited: u64,
77 pub lost: u64,
78}
79
80#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
81pub struct MigrationState {
82 pub applied: usize,
83 pub total: usize,
84 pub applied_descriptions: Vec<String>,
85 pub pending_descriptions: Vec<String>,
86}
87
88#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
89pub struct RecentLostEvent {
90 pub session_id: Uuid,
91 pub evidence: LostEvidence,
92 pub occurred_at: DateTime<Utc>,
93}
94
95#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
96pub struct LauncherStatus {
97 pub runtime: String,
98 pub command: Option<String>,
99 pub error: Option<String>,
100}
101
102#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
103pub struct TmuxStatus {
104 pub available: bool,
105 pub version: Option<String>,
106 pub error: Option<String>,
107}
108
109#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
114pub struct DoctorResponse {
115 pub version: VersionInfo,
116 pub socket_path: String,
117 pub uptime_secs: u64,
118 pub sqlite: MigrationState,
119 pub lifecycles: LifecycleCounts,
120 pub watchers: WatcherCounts,
121 pub launchers: Vec<LauncherStatus>,
122 pub tmux: TmuxStatus,
123 pub last_probe_sweep: Option<DateTime<Utc>>,
124 pub recent_lost: Vec<RecentLostEvent>,
125}