From 114a3b31cb2e64c29498bf2f7361e567636cbda5 Mon Sep 17 00:00:00 2001 From: Robert Mcgregor <38837341+exitcode0@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:12:15 +1000 Subject: [PATCH] feat(cli): add `path` & `limit` to `session list` command (#4878) --- crates/goose-cli/src/cli.rs | 22 +++++++++++------- crates/goose-cli/src/commands/schedule.rs | 4 ++-- crates/goose-cli/src/commands/session.rs | 28 ++++++++++++++++++----- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/crates/goose-cli/src/cli.rs b/crates/goose-cli/src/cli.rs index 185e6856..ad5cc983 100644 --- a/crates/goose-cli/src/cli.rs +++ b/crates/goose-cli/src/cli.rs @@ -98,9 +98,6 @@ fn parse_key_val(s: &str) -> Result<(String, String), String> { enum SessionCommand { #[command(about = "List all available sessions")] List { - #[arg(short, long, help = "List all available sessions")] - verbose: bool, - #[arg( short, long, @@ -115,6 +112,16 @@ enum SessionCommand { long_help = "Sort sessions by date in ascending order (oldest first). Default is descending order (newest first)." )] ascending: bool, + + #[arg( + short = 'p', + long = "working_dir", + help = "Filter sessions by working directory" + )] + working_dir: Option, + + #[arg(short = 'l', long = "limit", help = "Limit the number of results")] + limit: Option, }, #[command(about = "Remove sessions. Runs interactively if no ID or regex is provided.")] Remove { @@ -182,11 +189,9 @@ enum SchedulerCommand { /// ID of the schedule #[arg(long, help = "ID of the schedule")] // Explicitly make it --id id: String, - /// Maximum number of sessions to return #[arg(long, help = "Maximum number of sessions to return")] - limit: Option, + limit: Option, }, - /// Run a scheduled job immediately #[command(about = "Run a scheduled job immediately")] RunNow { /// ID of the schedule to run @@ -795,11 +800,12 @@ pub async fn cli() -> Result<()> { }) => { return match command { Some(SessionCommand::List { - verbose, format, ascending, + working_dir, + limit, }) => { - handle_session_list(verbose, format, ascending).await?; + handle_session_list(format, ascending, working_dir, limit).await?; Ok(()) } Some(SessionCommand::Remove { id, regex }) => { diff --git a/crates/goose-cli/src/commands/schedule.rs b/crates/goose-cli/src/commands/schedule.rs index 7f092734..c2784530 100644 --- a/crates/goose-cli/src/commands/schedule.rs +++ b/crates/goose-cli/src/commands/schedule.rs @@ -203,14 +203,14 @@ pub async fn handle_schedule_remove(id: String) -> Result<()> { } } -pub async fn handle_schedule_sessions(id: String, limit: Option) -> Result<()> { +pub async fn handle_schedule_sessions(id: String, limit: Option) -> Result<()> { let scheduler_storage_path = get_default_scheduler_storage_path().context("Failed to get scheduler storage path")?; let scheduler = SchedulerFactory::create(scheduler_storage_path) .await .context("Failed to initialize scheduler")?; - match scheduler.sessions(&id, limit.unwrap_or(50) as usize).await { + match scheduler.sessions(&id, limit.unwrap_or(50)).await { Ok(sessions) => { if sessions.is_empty() { println!("No sessions found for schedule ID '{}'.", id); diff --git a/crates/goose-cli/src/commands/session.rs b/crates/goose-cli/src/commands/session.rs index fa8e13f7..21d412ae 100644 --- a/crates/goose-cli/src/commands/session.rs +++ b/crates/goose-cli/src/commands/session.rs @@ -114,14 +114,34 @@ pub async fn handle_session_remove(id: Option, regex_string: Option Result<()> { +pub async fn handle_session_list( + format: String, + ascending: bool, + working_dir: Option, + limit: Option, +) -> Result<()> { let mut sessions = SessionManager::list_sessions().await?; + + if let Some(ref pat) = working_dir { + let pat_lower = pat.to_string_lossy().to_lowercase(); + sessions.retain(|s| { + s.working_dir + .to_string_lossy() + .to_lowercase() + .contains(&pat_lower) + }); + } + if ascending { sessions.sort_by(|a, b| a.updated_at.cmp(&b.updated_at)); } else { sessions.sort_by(|a, b| b.updated_at.cmp(&a.updated_at)); } + if let Some(n) = limit { + sessions.truncate(n); + } + match format.as_str() { "json" => { println!("{}", serde_json::to_string(&sessions)?); @@ -138,11 +158,7 @@ pub async fn handle_session_list(verbose: bool, format: String, ascending: bool) "{} - {} - {}", session.id, session.description, session.updated_at ); - if verbose { - println!(" {}", output); - } else { - println!("{}", output); - } + println!("{}", output); } } }