()
| 224 | } |
| 225 | |
| 226 | pub async fn list_external_clients() -> Result<()> { |
| 227 | let service = create_client_service().await?; |
| 228 | let infos = service |
| 229 | .list_clients() |
| 230 | .await |
| 231 | .map_err(|error| anyhow!(error.to_string()))?; |
| 232 | let configured = infos |
| 233 | .into_iter() |
| 234 | .map(|info| (info.id.clone(), info)) |
| 235 | .collect::<BTreeMap<_, _>>(); |
| 236 | |
| 237 | println!("External ACP agents"); |
| 238 | println!(); |
| 239 | for client in [ |
| 240 | ExternalAcpClient::Opencode, |
| 241 | ExternalAcpClient::ClaudeCode, |
| 242 | ExternalAcpClient::Codex, |
| 243 | ] { |
| 244 | if let Some(info) = configured.get(client.id()) { |
| 245 | print_client_info(info); |
| 246 | } else { |
| 247 | let preset = client.config(); |
| 248 | println!( |
| 249 | "- {}: not configured ({})", |
| 250 | client.id(), |
| 251 | render_command(&preset.command, &preset.args) |
| 252 | ); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | for info in configured.values() { |
| 257 | if !matches!(info.id.as_str(), "opencode" | "claude-code" | "codex") { |
| 258 | print_client_info(info); |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | println!(); |
| 263 | println!("Enable a built-in client with `bitfun-cli acp clients enable opencode`."); |
| 264 | println!("Run a prompt with `bitfun-cli acp run opencode \"your task\"`."); |
| 265 | Ok(()) |
| 266 | } |
| 267 | |
| 268 | pub async fn doctor_external_clients() -> Result<bool> { |
| 269 | let service = create_client_service().await?; |
no test coverage detected