cli_engine/lib.rs
1//! Build consistent, domain-oriented CLIs with a small amount of Rust.
2//!
3//! `cli_engine` provides the shared pieces that most CLI tools need:
4//! command registration, authentication provider routing, authorization hooks,
5//! audit and activity hooks, structured output, output schemas, guides, search,
6//! command tree rendering, and authenticated HTTP transport helpers.
7//!
8//! The intended shape is:
9//!
10//! 1. Each team owns one or more [`Module`] values.
11//! 2. A module registers noun-based [`GroupSpec`] groups.
12//! 3. Groups contain verb-like [`CommandSpec`] leaf commands.
13//! 4. Command handlers stay focused on domain behavior while [`Middleware`]
14//! handles authentication, dry-run, audit, activity, output, and errors.
15//!
16//! # Quick Start
17//!
18//! ```no_run
19//! use clap::Arg;
20//! use cli_engine::{
21//! BuildInfo, Cli, CliConfig, CommandSpec, GroupSpec, Module,
22//! RuntimeCommandSpec, RuntimeGroupSpec,
23//! };
24//! use serde_json::json;
25//!
26//! #[tokio::main]
27//! async fn main() -> std::process::ExitCode {
28//! let list = RuntimeCommandSpec::new(
29//! CommandSpec::new("list", "List projects")
30//! .with_system("projects-api")
31//! .with_default_fields("id,name,status")
32//! .with_arg(Arg::new("team").long("team").required(true))
33//! .no_auth(true),
34//! async |_credential, args| {
35//! let team = args
36//! .get("team")
37//! .and_then(|value| value.as_str())
38//! .unwrap_or_default();
39//! Ok(cli_engine::CommandResult::new(json!([
40//! { "id": "p1", "name": "Portal", "status": "active", "team": team }
41//! ])))
42//! },
43//! );
44//!
45//! let module = Module::new("Platform Systems", move |_context| {
46//! RuntimeGroupSpec::new(GroupSpec::new("project", "Manage projects"))
47//! .with_command(list.clone())
48//! });
49//!
50//! let cli = Cli::new(
51//! CliConfig::new("example", "Example cli-engine application", "example")
52//! .with_build(BuildInfo::new(env!("CARGO_PKG_VERSION")))
53//! .with_module(module),
54//! );
55//!
56//! cli.execute().await
57//! }
58//! ```
59//!
60//! Command paths are colon-separated (`project:list`) for policy, audit,
61//! schema, and authorization compatibility with existing CLI ecosystems.
62
63/// Auth provider traits, dispatch, and built-in provider commands.
64pub mod auth;
65/// CLI application assembly and execution.
66pub mod cli;
67/// Command and command-group specifications.
68pub mod command;
69/// Shared error type and error traits.
70pub mod error;
71/// Global framework flags and flag-extraction helpers.
72pub mod flags;
73/// Embedded or file-backed guide parsing.
74pub mod guide;
75/// Cross-cutting command execution middleware.
76pub mod middleware;
77/// Domain module registration helpers.
78pub mod module;
79/// Structured output envelopes, renderers, schemas, and field projection.
80pub mod output;
81/// Search indexing for commands, guides, and extra documents.
82pub mod search;
83/// Command risk tiers used by authentication, authorization, and dry-run.
84pub mod tier;
85/// HTTP transport client and auth injectors.
86pub mod transport;
87/// Command tree data model and human rendering.
88pub mod tree;
89
90pub use auth::{
91 AuthLoginResult, AuthProvider, AuthStatusEntry, CACHE_TTL, Credential, Dispatcher,
92 SingleProvider, StatusEntry, auth_command_group, login_and_build, logout_result, status_result,
93 to_status_entry,
94};
95pub use cli::{
96 ApplyFlags, BuildInfo, Cli, CliConfig, CliRunOutput, ExtraSearchDocs, InitDeps,
97 ModuleHelpEntry, OnShutdown, PreRun, RegisterFlags, ResolveMeta, RootNextActions,
98 build_root_long,
99};
100pub use command::{
101 CommandContext, CommandFuture, CommandHandler, CommandResult, CommandResultMetadata,
102 CommandSpec, GroupSpec, RuntimeCommandSpec, RuntimeGroupSpec, StreamSender,
103 StreamingCommandFuture, StreamingCommandHandler, command_args_from_matches,
104 command_path_from_matches, command_path_from_parts, leaf_matches,
105};
106pub use error::{
107 CliCoreError, DetailedError, ExitCoder, Result, exit_code_for_error, exit_code_for_exit_coder,
108};
109pub use flags::{
110 GlobalFlags, default_output_format, derive_bool_flags, derive_value_flags,
111 extract_command_path, extract_output_format, extract_search_query, global_flags_from_matches,
112 has_true_schema_flag, output_env_var, register_global_flags, resolve_default_output_format,
113};
114pub use guide::{GuideEntry, parse_guides, parse_guides_from_markdown};
115pub use middleware::{
116 ActivityEmitter, ActivityEvent, Auditor, Authorizer, CommandMeta, Middleware, MiddlewareOutput,
117 MiddlewareRequest,
118};
119pub use module::{CommandModule, Module, ModuleContext, ModuleRegister};
120pub use output::{
121 Envelope, ErrorEnvelope, FieldInfo, HumanViewDef, HumanViewFn, HumanViewRegistry,
122 HumanViewRenderer, Metadata, NextAction, NextActionParam, OutputField, OutputFormat,
123 OutputSchema, PaginationMeta, PipelineOpts, RendererFactory, SchemaInfo, SchemaRegistry,
124 TableColumn, apply_pipeline, build_detailed_error_envelope, build_error_envelope, fields_for,
125 fields_from_json_schema, filter_fields, format_help_section, get_global_schema_by_path,
126 global_human_view_registry_snapshot, global_schema_registry_snapshot, is_valid_output_format,
127 json_schema_for, json_schema_info, lookup_global_human_view_columns,
128 lookup_global_human_view_func, parse_fields, register_global_human_view,
129 register_global_human_view_func, register_global_json_schema, register_global_schema,
130 register_global_schema_fields, register_global_schema_info, render, render_data,
131 render_data_format, render_detailed_error, render_detailed_error_format, render_error,
132 render_error_format, render_format, render_human, render_human_with_registry,
133 render_human_with_registry_for_schema, render_human_with_view, render_json, render_toon,
134 write_render,
135};
136pub use search::{SearchDocument, SearchResult};
137pub use tier::Tier;
138pub use tree::{TreeNode, build_tree_from_clap, build_tree_from_parts, render_tree_human};