//! _agents (hidden): list agent names for shell completions (issue #41). //! Prints one name per line; --installed restricts to what can actually be //! launched: installed agents (managed + external), aliases and groups. use super::*; use std::collections::HashSet; /// The completion pool: installed agents (managed + external), aliases and /// groups when installed is true, the whole catalog otherwise. pub fn agent_names(app: &App, installed: bool) -> Vec { let mut names: Vec = Vec::new(); if installed { let probe = crate::probe::detect_externals(app); let mut launchable: HashSet = HashSet::new(); for a in app.catalog.agents() { if app.state.get(&a.name).ok().flatten().is_some() || probe.path_of(&a.name).is_some() { launchable.insert(a.name.clone()); names.push(a.name.clone()); } } for (alias, target) in &app.config.aliases { let is_launchable = app .catalog .resolve(alias) .map(|agent| launchable.contains(&agent.name)) .unwrap_or_else(|| launchable.contains(target)); if is_launchable { names.push(alias.clone()); } } for (group, members) in &app.config.groups { if members.iter().any(|m| launchable.contains(m)) { names.push(format!("group:{group}")); } } } else { names.extend(app.catalog.agents().iter().map(|a| a.name.clone())); } names.sort(); names.dedup(); names } pub fn run(app: &App, installed: bool) -> Result { for n in agent_names(app, installed) { println!("{n}"); } Ok(0) }