agent_procs/cli/
status.rs1use 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 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}