Skip to main content

virtuoso_cli/commands/
session.rs

1use crate::config::Config;
2use crate::error::{Result, VirtuosoError};
3use crate::models::SessionInfo;
4use crate::output::OutputFormat;
5use crate::transport::tunnel::SSHClient;
6use serde_json::{json, Value};
7
8pub fn list(format: OutputFormat) -> Result<Value> {
9    // In remote mode, sync session files from remote host first.
10    // Best effort: failures are silent so local cache still works.
11    if let Ok(cfg) = Config::from_env() {
12        if cfg.is_remote() {
13            if let Ok(client) = SSHClient::from_env(cfg.keep_remote_files) {
14                let _ = SessionInfo::sync_from_remote(&client.runner);
15            }
16        }
17    }
18
19    let mut sessions = SessionInfo::list()
20        .map_err(|e| VirtuosoError::Execution(format!("failed to read sessions: {e}")))?;
21
22    let sessions_dir = SessionInfo::sessions_dir();
23    sessions.retain(|s| {
24        if s.is_alive() {
25            true
26        } else {
27            let _ = std::fs::remove_file(sessions_dir.join(format!("{}.json", s.id)));
28            false
29        }
30    });
31
32    if format == OutputFormat::Json {
33        return Ok(json!({
34            "status": "success",
35            "count": sessions.len(),
36            "sessions": sessions.iter().map(|s| json!({
37                "id": s.id,
38                "port": s.port,
39                "pid": s.pid,
40                "host": s.host,
41                "user": s.user,
42                "created": s.created,
43            })).collect::<Vec<_>>(),
44        }));
45    }
46
47    if sessions.is_empty() {
48        println!("No active Virtuoso sessions found.");
49        println!("Start Virtuoso and run RBStart() in CIW to register a session.");
50        return Ok(json!({"status": "success", "count": 0}));
51    }
52
53    println!(
54        "{:<20} {:>6}  {:>7}  {:<12}  CREATED",
55        "SESSION ID", "PORT", "PID", "HOST"
56    );
57    println!("{}", "-".repeat(72));
58    for s in &sessions {
59        println!(
60            "{:<20} {:>6}  {:>7}  {:<12}  {}",
61            s.id, s.port, s.pid, s.host, s.created
62        );
63    }
64
65    Ok(json!({"status": "success", "count": sessions.len()}))
66}
67
68pub fn show(id: &str, _format: OutputFormat) -> Result<Value> {
69    let s = SessionInfo::load(id)
70        .map_err(|e| VirtuosoError::NotFound(format!("session '{id}' not found: {e}")))?;
71
72    Ok(json!({
73        "status": "success",
74        "session": {
75            "id": s.id,
76            "port": s.port,
77            "pid": s.pid,
78            "host": s.host,
79            "user": s.user,
80            "created": s.created,
81            "alive": s.is_alive(),
82        }
83    }))
84}