1pub mod app;
5pub mod build;
6pub mod clean;
7pub mod design_prompt;
8pub mod discard;
9pub mod env_arg;
10pub mod logs;
11pub mod ls;
12pub mod mcp;
13pub mod mcp_self;
14pub mod run;
15pub mod session_setup;
16pub mod volume_arg;
17
18use std::path::PathBuf;
19
20use crate::error::{OutrigError, Result};
21use crate::session::{Session, SessionId, SessionStore};
22
23pub fn resolve_session_arg(store: &SessionStore, query: &str) -> Result<(PathBuf, Session)> {
33 let exact = SessionId(query.to_string());
34 if let Ok(out) = store.get_by_id(&exact) {
35 return Ok(out);
36 }
37 let mut matches: Vec<Session> = store
38 .list()?
39 .into_iter()
40 .filter(|s| s.id.as_str().contains(query))
41 .collect();
42 match matches.len() {
43 0 => Err(OutrigError::Configuration(format!("no session matching {query:?}")).into()),
44 1 => {
45 let s = matches.pop().expect("len == 1");
46 Ok((s.session_dir.clone(), s))
47 }
48 _ => {
49 let mut msg = format!("ambiguous session {query:?}; candidates:");
50 for s in &matches {
51 msg.push_str("\n ");
52 msg.push_str(s.id.as_str());
53 }
54 Err(OutrigError::Configuration(msg).into())
55 }
56 }
57}