1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
6#[serde(rename_all = "snake_case")]
7pub enum WatchBackend {
8 Launchd,
9 SystemdUser,
10 Unsupported,
11}
12
13#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
14#[serde(rename_all = "snake_case")]
15pub enum WatchMode {
16 Native,
17 Polling,
18 Foreground,
19 Disabled,
20}
21
22#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
23#[serde(rename_all = "snake_case")]
24pub enum WatchHealth {
25 Ok,
26 Warning,
27 Error,
28}
29
30#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
31#[serde(rename_all = "snake_case")]
32pub enum WatchRuntimeState {
33 Starting,
34 Idle,
35 RefreshingKeyword,
36 RefreshingSemantic,
37 Checking,
38 BackingOff,
39 Stopping,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
43#[serde(tag = "kind", rename_all = "snake_case")]
44pub enum WatchSemanticState {
45 None,
46 Pending {
47 pending_chunks: usize,
48 },
49 Unavailable {
50 pending_chunks: usize,
51 reason: String,
52 },
53 Blocked {
54 space: String,
55 reason: String,
56 fix: String,
57 },
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
61pub struct WatchServiceStatus {
62 pub enabled: bool,
63 pub running: bool,
64 pub backend: WatchBackend,
65 pub pid: Option<u32>,
66 pub issue: Option<String>,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
70pub struct WatchStatusResponse {
71 pub service: WatchServiceStatus,
72 pub runtime: Option<WatchRuntimeStatus>,
73 pub log_file: PathBuf,
74 pub state_file: PathBuf,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
78pub struct WatchRuntimeStatus {
79 pub mode: WatchMode,
80 pub health: WatchHealth,
81 pub state: WatchRuntimeState,
82 pub pid: u32,
83 pub started_at: String,
84 pub updated_at: String,
85 pub watched_collections: usize,
86 pub dirty_collections: usize,
87 pub semantic_pending_collections: usize,
88 pub semantic_unavailable_collections: usize,
89 pub semantic_blocked_spaces: Vec<WatchSpaceBlock>,
90 pub collections: Vec<WatchCollectionStatus>,
91 pub last_keyword_refresh: Option<WatchRefreshSummary>,
92 pub last_semantic_refresh: Option<WatchRefreshSummary>,
93 pub last_safety_scan: Option<String>,
94 pub last_catalog_refresh: Option<String>,
95 pub last_error: Option<String>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
99pub struct WatchCollectionStatus {
100 pub space: String,
101 pub collection: String,
102 pub path: PathBuf,
103 pub dirty: bool,
104 pub semantic: WatchSemanticState,
105 pub last_event_at: Option<String>,
106 pub last_keyword_refresh: Option<String>,
107 pub last_semantic_refresh: Option<String>,
108 pub last_error: Option<String>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
112pub struct WatchSpaceBlock {
113 pub space: String,
114 pub reason: String,
115 pub fix: String,
116 pub set_at: String,
117 pub backoff_until: String,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
121pub struct WatchRefreshSummary {
122 pub space: String,
123 pub collection: String,
124 pub started_at: String,
125 pub finished_at: String,
126 pub elapsed_ms: u64,
127 pub scanned_docs: usize,
128 pub changed_docs: usize,
129 pub embedded_chunks: usize,
130}