1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! External agents — detect installed agentic CLIs and treat them
//! as agents available through CAR.
//!
//! This is the **third kind of agent** in CAR's taxonomy, sibling to:
//!
//! - **Lifecycle agents** (`car_registry::supervisor`) — long-lived
//! child processes the daemon babysits.
//! - **In-process runners** (`car_multi::AgentRunner`) — caller-
//! implemented model loops invoked per task.
//!
//! External agents are **caller-installed CLIs spawned per task** —
//! `claude`, `codex`, `gemini`, etc. The daemon discovers them at
//! boot (and on demand) but does not own their lifecycle. They run
//! only when explicitly selected.
//!
//! See `docs/proposals/external-agent-detection.md` for the
//! architectural rationale.
//!
//! ## Phase 1 scope (this crate, today)
//!
//! - **Detection.** [`detect`] scans `$PATH` for known adapter
//! binaries, probes version + auth state, returns a stable
//! [`ExternalAgentSpec`] list.
//!
//! - **No invocation yet.** The per-task adapter that speaks the
//! JSON stdio protocol lands in Phase 2 alongside the
//! `agents.invoke_external` JSON-RPC method.
//!
//! ## Example
//!
//! ```no_run
//! # async fn run() {
//! let specs = car_external_agents::detect().await;
//! for spec in &specs {
//! println!(
//! "{} at {} (auth: {:?})",
//! spec.display_name,
//! spec.binary_path.display(),
//! spec.auth_kind
//! );
//! }
//! # }
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;