aico/commands/
session_cmds.rs1use crate::exceptions::AicoError;
2use crate::fs::atomic_write_json;
3use crate::models::{SessionView, default_timestamp};
4use crate::session::Session;
5use std::fs;
6
7pub fn list() -> Result<(), AicoError> {
8 let session = Session::load_active()?;
9 let sessions_dir = session.sessions_dir();
10
11 if !sessions_dir.exists() {
12 return Err(AicoError::Session("Sessions directory not found.".into()));
13 }
14
15 let active_name = session
17 .view_path
18 .file_stem()
19 .and_then(|s| s.to_str())
20 .unwrap_or("unknown");
21
22 let mut views: Vec<_> = fs::read_dir(sessions_dir)?
23 .filter_map(Result::ok) .map(|e| e.path())
25 .filter(|p| p.extension().is_some_and(|e| e == "json"))
26 .filter_map(|p| p.file_stem().map(|s| s.to_string_lossy().into_owned()))
27 .collect();
28
29 views.sort();
30
31 if views.is_empty() {
32 println!("No session views found.");
33 return Ok(());
34 }
35
36 println!("Available sessions:");
37 for name in views {
38 if name == active_name {
39 println!(" - {} (active)", name);
40 } else {
41 println!(" - {}", name);
42 }
43 }
44
45 Ok(())
46}
47
48pub fn switch(name: String) -> Result<(), AicoError> {
49 let session = Session::load_active()?;
50 let target_path = session.get_view_path(&name);
51
52 if !target_path.exists() {
53 return Err(AicoError::InvalidInput(format!(
54 "Session view '{}' not found at {}.",
55 name,
56 target_path.display()
57 )));
58 }
59
60 session.switch_to_view(&target_path)?;
61 println!("Switched active session to: {}", name);
62 Ok(())
63}
64
65pub fn new_session(name: String, model: Option<String>) -> Result<(), AicoError> {
66 let session = Session::load_active()?;
67 let new_view_path = session.get_view_path(&name);
68
69 if new_view_path.exists() {
70 return Err(AicoError::InvalidInput(format!(
71 "A session view named '{}' already exists.",
72 name
73 )));
74 }
75
76 let new_model = model.unwrap_or_else(|| session.view.model.clone());
77
78 let view = SessionView {
79 model: new_model.clone(),
80 context_files: vec![],
81 message_indices: vec![],
82 history_start_pair: 0,
83 excluded_pairs: vec![],
84 created_at: default_timestamp(),
85 };
86
87 atomic_write_json(&new_view_path, &view)?;
88
89 session.switch_to_view(&new_view_path)?;
90 println!(
91 "Created new empty session '{}' with model '{}' and switched to it.",
92 name, new_model
93 );
94
95 Ok(())
96}