Skip to main content

qli_ext/
lib.rs

1//! Extension discovery, dispatch, and guardrails for the qli CLI.
2//!
3//! [`discovery`] walks XDG + PATH and builds the group/extension table.
4//! [`dispatch::run`] wraps the child spawn in the guard sequence: banner →
5//! [`guard::check_requires_env`] → [`guard::run_confirm`] → secrets →
6//! [`audit`] start → spawn → audit finish/interrupted. Manifests
7//! ([`manifest`]) describe each group; secret resolution is pluggable via
8//! [`secrets::SecretsResolver`].
9//!
10//! ## Diagnostic policy (fail fast, fail loud)
11//!
12//! Every error has one obvious surface — never silently swallowed. Four
13//! tiers, picked by *user impact*, not by *code locality*:
14//!
15//! 1. **Process-fatal** — bubbled up as `anyhow::Error` from `main`, printed
16//!    `error: {msg}` (exit 1). For startup failures and unrecoverable binary
17//!    conditions.
18//! 2. **Dispatch-fatal** — typed [`dispatch::DispatchError`] variants that
19//!    abort one dispatched extension with full context. Surfaced through
20//!    `anyhow` so the user sees `error: failed to run X: Y`.
21//! 3. **Must-see warning** — `eprintln!("warning: ...")`. Never goes through
22//!    `tracing` (which `-q` can silence). Used when behavior visibly
23//!    degrades: discovery skipped a group, a signal handler couldn't
24//!    install, an audit-finish write failed.
25//! 4. **Trace** — `tracing` info/debug/trace. Routine progress only;
26//!    silenceable. Use it when a later operation will fail loudly with full
27//!    context if this trace event mattered.
28//!
29//! Rule of thumb: if you write `.ok()` on a `Result` whose failure changes
30//! user-visible behavior, you've picked the wrong tier — promote to 3 or 2.
31//! Validation belongs at the **earliest boundary** (parse-time over
32//! exec-time) so the error points at the source, not the symptom.
33
34pub mod audit;
35pub mod defaults;
36pub mod discovery;
37pub mod dispatch;
38pub mod guard;
39pub mod manifest;
40pub mod secrets;
41
42pub use defaults::{materialize_to, MaterializeError, MaterializeStats, DEFAULTS};
43pub use discovery::{discover, Discovery, Extension, ExtensionOrigin, Group};
44pub use dispatch::{DispatchError, DispatchOptions, DispatchSignals};
45pub use guard::{tty_confirm, ConfirmPrompt, GuardError, TtyConfirm};
46pub use manifest::{Manifest, ManifestError, SecretProvider, SecretSpec, CURRENT_SCHEMA_VERSION};
47pub use secrets::{
48    ProductionResolver, ResolvedSecret, SecretsError, SecretsResolver, TestResolver,
49};