Skip to main content

lean_ctx/core/addons/
mod.rs

1//! Addon ecosystem: community extensions for lean-ctx (#858).
2//!
3//! An **addon** packages an external MCP server (+ metadata) behind a small
4//! [`lean-ctx-addon.toml`](manifest) manifest, so a third-party tool plugs into
5//! lean-ctx's MCP gateway with a single `lean-ctx addon add` — no fork, no
6//! recompile. Addons are user-global and reuse the gateway trust model
7//! (`[gateway]` is global-only and opt-in; see [`crate::core::mcp_catalog`]).
8//!
9//! Layers:
10//! - [`manifest`] — the `lean-ctx-addon.toml` contract (also the registry entry shape).
11//! - [`registry`] — the curated catalog (bundled, with optional user override).
12//! - [`store`]    — what is installed locally (`<data_dir>/addons/installed.json`).
13//! - [`install`]  — wires an addon into the gateway and records it in the store.
14//! - [`bootstrap`] — `[install]` block executor: provisions an addon's upstream
15//!   package via a pinned package manager (uv/pip/cargo/npm/brew/dotnet) on `add`,
16//!   uninstalls it on `remove` (#1105, Phase 2). Never goes through a shell.
17//! - [`pack_env`] — expands `{pack_dir:@ns/name}` in an addon's `[mcp.env]`
18//!   to the on-disk location of a declared `kind=skills` dependency (#727).
19//! - [`scaffold`] — `addon init` starter manifest generator (DX, P4).
20//!
21//! Security (#863, P1):
22//! - [`capabilities`] — the declared `[capabilities]` permission model that
23//!   drives the per-addon sandbox + env allowlist + install consent.
24//! - [`trust`]    — trust tier (`verified`) + static risk assessment of the wiring.
25//! - [`audit`]    — capability-coherence + malware heuristics + the verified/paid
26//!   gate (#403): does the declared `[capabilities]` match the wiring, and is the
27//!   wiring free of malicious patterns?
28//! - [`commerce`] — sellable-addon model (`[pricing]`) + the mandatory paid
29//!   listing gate (Track B): no addon is sold without clearing the audit.
30//! - [`binhash`]  — SHA-256 binary pinning for stdio addons (refuse a swapped
31//!   executable at spawn).
32//! - [`policy`]   — the global-only `[addons]` install policy floor + the gate.
33//! - [`signing`]  — Ed25519 signing for the user-override registry.
34//! - [`revocation`] — central kill-switch that blocks a revoked addon from
35//!   running (install, catalog build, every proxy call).
36//! - [`integrity`] — install-time wiring hash + local re-verify (the lockfile).
37//! - [`meter`]    — per-addon / per-tool usage metering (analytics + billing base, P5).
38//! - [`sandbox`]  — per-addon OS sandbox for spawned stdio servers.
39//! - [`runtime`]  — redaction + audit of untrusted addon tool output.
40//!
41//! Grammar addons (#690) are a separate, smaller concept living alongside
42//! this module rather than inside it — a long-tail tree-sitter grammar is a
43//! `cdylib` `dlopen`'d directly into lean-ctx's own process, not an MCP
44//! server, so none of the subprocess/gateway-shaped layers above apply:
45//! - [`grammar_manifest`] — the grammar-addon manifest (language, extensions,
46//!   per-platform dylib + mandatory SHA-256 pin, tree-sitter ABI version).
47//! - [`grammar_registry`] — its bundled/local-override catalog, reusing only
48//!   [`signing`] and [`binhash`] from the MCP addon machinery.
49//! - `grammar_install` (internal) — zero-config fetch (#690, Phase 1d): downloads a
50//!   missing pinned dylib on first use, silent on any failure (offline,
51//!   network error, hash mismatch) so it degrades to the regex-signature
52//!   fallback exactly like "not installed" — no `addon add` consent step,
53//!   since a grammar addon is a parsing fallback, not a spawned process.
54
55pub mod artifact_install;
56pub mod audit;
57pub mod binhash;
58pub mod bootstrap;
59pub mod capabilities;
60pub mod commerce;
61pub mod env_scrub;
62// Grammar addons only matter to a build that can dlopen a Language into a
63// tree-sitter parser at all — dead weight in the no-tree-sitter slim build
64// (#663), so gated the same way `core::signatures_ts` is.
65#[cfg(feature = "tree-sitter")]
66pub(crate) mod grammar_install;
67#[cfg(feature = "tree-sitter")]
68pub mod grammar_manifest;
69#[cfg(feature = "tree-sitter")]
70pub mod grammar_registry;
71pub mod health;
72pub mod install;
73pub mod integrity;
74pub mod manifest;
75pub mod meter;
76pub mod ort_provision;
77pub mod pack_env;
78pub mod policy;
79pub mod publish;
80pub mod registry;
81pub mod registry_snapshot;
82pub mod revocation;
83pub mod runtime;
84pub mod sandbox;
85pub mod scaffold;
86pub mod signing;
87pub mod store;
88pub mod trust;
89
90pub use artifact_install::{ArtifactAsset, current_target_triple};
91pub use audit::{AuditReport, AuditVerdict};
92pub use bootstrap::{AddonInstall, BootstrapStatus, InstallReceipt, Manager};
93pub use capabilities::{AddonCapabilities, FilesystemAccess, NetworkAccess};
94pub use commerce::{AddonPricing, PaidGate, PricingModel, paid_listing_gate};
95#[cfg(feature = "tree-sitter")]
96pub use grammar_manifest::{GrammarAsset, GrammarManifest};
97pub use health::ProbeReport;
98pub use manifest::{AddonManifest, AddonMcp, AddonMeta};
99pub use policy::{AddonPolicy, AddonsConfig};
100pub use sandbox::SandboxMode;
101pub use store::{InstalledAddon, InstalledStore};
102pub use trust::{RiskFinding, RiskLevel, TrustTier};