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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! A canonical install / uninstall / self-heal lifecycle for the Claude Code
//! plugin a Rust binary ships, so a `setup` subcommand replaces the user typing
//! `/plugin marketplace add` + `/plugin install`. The same plugin tree can fan
//! out to 24 other coding agents (codex, gemini, opencode, cursor, goose, …),
//! each behind a cargo feature.
//!
//! For Claude Code the lifecycle orchestrates the `claude` CLI (≥ 2.1.196) as its
//! transaction boundary; it never forges Claude Code's on-disk registry state.
//! Non-Claude backends need no CLI at all: each translates the plugin's components
//! (MCP servers, hooks, commands, agents) into that tool's own config files via
//! atomic read-modify-write merges that leave the user's entries untouched, and
//! only runs when the tool is detected on the machine.
//!
//! The derive-driven example stays `ignore`: the macro reads a `plugin.json` tree
//! and the emitted guard needs `AGENTGEAR_GUARD`, neither of which a doctest has. A
//! compiled example of the derive-free value types follows below.
//!
//! ```ignore
//! use agentgear::{PluginHost, Scope, Source};
//!
//! #[derive(PluginHost)]
//! #[plugin(name = "claudix", agents = ["claude", "codex", "gemini"])]
//! struct ClaudixHost;
//!
//! ClaudixHost::install(Scope::User, Source::Embedded)?; // all detected agents
//! ClaudixHost::install_into(Scope::User, Source::Embedded, &["gemini"])?; // one
//! ClaudixHost::self_heal()?; // SessionStart entrypoint
//! ```
//!
//! The value types need no derive, so this block is a real, compiled doctest. It
//! builds a [`Source`]/[`Scope`], then reads an [`Outcome`] and an [`AgentReport`]'s
//! per-agent results.
//!
//! ```
//! use agentgear::{AgentReport, AgentResult, AgentStatus, Outcome, Scope, Source};
//!
//! let _source = Source::Path("./plugin".into());
//! let _scope = Scope::Project { path: ".".into() };
//!
//! let outcome = Outcome::Updated { from: Some("0.1.0".into()), to: "0.2.0".into() };
//! let line = match outcome {
//! Outcome::Installed => "installed".to_string(),
//! Outcome::Updated { from, to } => format!("updated {from:?} -> {to}"),
//! other => other.to_string(),
//! };
//! assert_eq!(line, "updated Some(\"0.1.0\") -> 0.2.0");
//!
//! let result = AgentResult { agent: "claude", status: AgentStatus::Converged(Outcome::Installed) };
//! assert!(matches!(result.status, AgentStatus::Converged(_)));
//!
//! // AgentReport is #[non_exhaustive]; only a lifecycle call builds one, so this
//! // reader is compile-checked against the live signatures without an instance.
//! fn summarize(report: &AgentReport) -> bool {
//! for entry in &report.results {
//! let _ = (entry.agent, &entry.status);
//! }
//! let _merged: Outcome = report.merged();
//! report.is_healthy()
//! }
//! let _ = summarize as fn(&AgentReport) -> bool;
//! ```
//!
//! The host also authors a one-line `build.rs`:
//! `fn main() { agentgear::build::assert_plugin_version(); }`.
//!
//! Two runnable hosts live in the repo's `examples/`: `hello-mcp` (the minimal
//! Claude-only host) and `kitchen-sink` (every component type across seven
//! harnesses, with hermetic lifecycle tests).
//!
//! # Feature flags
//!
//! `default = ["derive", "claude", "embed"]`: the [`PluginHost`] derive macro, the
//! Claude Code backend, and baking the plugin tree into the binary as a compressed
//! blob so `setup` works offline. Turning `embed` off (paired with `embed = false`
//! on the derive) ships a zero-embed binary for a host that installs from a GitHub
//! or path [`Source`] instead.
//!
//! Every other coding agent is its own feature, named by its backend id;
//! `all-agents` enables all 24 at once. Only four pull an extra dependency:
//!
//! | feature (= backend id) | extra dependency |
//! |---|---|
//! | `codex`, `kimi` | `toml_edit` (toml config) |
//! | `omp`, `goose` | `serde_norway` (yaml config) |
//! | `opencode`, `gemini`, `cursor`, `cline`, `devin`, `qwen-code`, `copilot-cli`, `vscode-copilot`, `jetbrains-copilot`, `kiro`, `zed`, `openclaw`, `kilo`, `antigravity`, `antigravity-cli`, `pi`, `amp`, `crush`, `droid`, `augment` | none |
//!
//! Backends are selected per host binary with the derive's `agents = [...]` list;
//! [`backend_for`] resolves an id to its [`AgentBackend`] when a host wants its own
//! picker UI. Design rationale lives in `docs/design.md`.
// The IR + parser is consumed by the non-CC backends + doctor in pass B;
// `allow(dead_code)` until those calls land.
// The derive's compile-time listed-agent-vs-enabled-feature check reads these;
// hidden because nothing else should (the module doc has the full story).
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use PluginHost;
/// A ready-to-glob prelude for host binaries.