Skip to main content

outrig_cli/cli/
mod.rs

1//! CLI subcommand entry points. Each subcommand owns its arg struct and its
2//! `execute` function; `bin/outrig.rs` stays a thin dispatch table.
3
4pub 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
23/// Resolve the user's `<session>` argument (which may be a substring) to a
24/// concrete session. CLI policy, not store policy: substring matching is an
25/// ergonomic affordance for the user typing `outrig logs 1419 fs`, but the
26/// store's contract stays "exact id or path."
27///
28/// Tries an exact `get_by_id` first (so the common case is one stat). On miss,
29/// falls back to a `list()` substring match. Zero matches -> not-found error;
30/// multiple -> [`OutrigError::Configuration`] with the candidate ids one per
31/// line.
32pub 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}