ubermind_core/
protocol.rs1use crate::types::ServiceStatus;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(tag = "cmd", rename_all = "snake_case")]
6pub enum Request {
7 Start { names: Vec<String> },
8 Stop { names: Vec<String> },
9 Reload { names: Vec<String> },
10 Restart { service: String, process: String },
11 Kill { service: String, process: String },
12 Status,
13 Logs { service: String, process: Option<String>, follow: bool },
14 Ping,
15 Shutdown,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(tag = "type", rename_all = "snake_case")]
20pub enum Response {
21 Ok { message: Option<String> },
22 Status { services: Vec<ServiceStatus> },
23 Log { line: String },
24 Error { message: String },
25 Progress { service: String, message: String },
26 Pong,
27}
28
29pub const SOCKET_NAME: &str = "daemon.sock";
30
31pub fn socket_path() -> std::path::PathBuf {
32 state_dir().join(SOCKET_NAME)
33}
34
35pub fn pid_path() -> std::path::PathBuf {
36 state_dir().join("daemon.pid")
37}
38
39pub fn state_dir() -> std::path::PathBuf {
40 if let Ok(dir) = std::env::var("XDG_STATE_HOME") {
41 std::path::PathBuf::from(dir).join("ubermind")
42 } else if let Some(home) = home_dir() {
43 home.join(".local").join("state").join("ubermind")
44 } else {
45 std::path::PathBuf::from("/tmp/ubermind")
46 }
47}
48
49pub fn config_dir() -> std::path::PathBuf {
50 if let Ok(dir) = std::env::var("XDG_CONFIG_HOME") {
51 std::path::PathBuf::from(dir).join("ubermind")
52 } else if let Some(home) = home_dir() {
53 home.join(".config").join("ubermind")
54 } else {
55 std::path::PathBuf::from("/tmp/ubermind/config")
56 }
57}
58
59fn home_dir() -> Option<std::path::PathBuf> {
60 std::env::var("HOME").ok().map(std::path::PathBuf::from)
61}