Skip to main content

agent_procs/cli/
status.rs

1use crate::protocol::{Request, Response};
2use std::fmt::Write;
3
4pub async fn execute(session: &str, json: bool) -> i32 {
5    let req = Request::Status;
6    crate::cli::request_and_handle(session, &req, false, |resp| match resp {
7        Response::Status { processes } => {
8            if json {
9                match serde_json::to_string_pretty(&processes) {
10                    Ok(json) => println!("{}", json),
11                    Err(e) => {
12                        eprintln!("error: failed to serialize status: {}", e);
13                        return Some(1);
14                    }
15                }
16            } else {
17                let has_urls = processes.iter().any(|p| p.url.is_some());
18                let has_restarts = processes
19                    .iter()
20                    .any(|p| p.restart_policy.is_some() || p.restart_count.is_some());
21                let has_watch = processes.iter().any(|p| p.watched == Some(true));
22
23                // Build header
24                let mut header =
25                    format!("{:<12} {:<8} {:<10} {:<6}", "NAME", "PID", "STATE", "EXIT");
26                if has_restarts {
27                    let _ = write!(header, " {:<10}", "RESTARTS");
28                }
29                if has_watch {
30                    let _ = write!(header, " {:<6}", "WATCH");
31                }
32                if has_urls {
33                    let _ = write!(header, " {:<30}", "URL");
34                }
35                let _ = write!(header, " UPTIME");
36                println!("{}", header);
37
38                for p in &processes {
39                    let state = p.state.to_string();
40                    let exit = p.exit_code.map_or("-".into(), |c| c.to_string());
41                    let uptime = p.uptime_secs.map_or("-".into(), format_uptime);
42
43                    let mut line = format!("{:<12} {:<8} {:<10} {:<6}", p.name, p.pid, state, exit);
44
45                    if has_restarts {
46                        let restarts = match (p.restart_count, p.max_restarts) {
47                            (Some(c), Some(m)) => format!("{}/{}", c, m),
48                            (Some(c), None) => c.to_string(),
49                            _ => "-".into(),
50                        };
51                        let _ = write!(line, " {:<10}", restarts);
52                    }
53                    if has_watch {
54                        let watch = if p.watched == Some(true) { "*" } else { "-" };
55                        let _ = write!(line, " {:<6}", watch);
56                    }
57                    if has_urls {
58                        let url = p.url.as_deref().unwrap_or("-");
59                        let _ = write!(line, " {:<30}", url);
60                    }
61                    let _ = write!(line, " {}", uptime);
62                    println!("{}", line);
63                }
64            }
65            Some(0)
66        }
67        _ => None,
68    })
69    .await
70}
71
72fn format_uptime(secs: u64) -> String {
73    if secs < 60 {
74        format!("{}s", secs)
75    } else if secs < 3600 {
76        format!("{}m{}s", secs / 60, secs % 60)
77    } else {
78        format!("{}h{}m", secs / 3600, (secs % 3600) / 60)
79    }
80}