argot_cmd/lib.rs
1//! # argot
2//!
3//! An agent-first command interface framework for Rust.
4//!
5//! argot makes it easy to define structured CLI commands that are equally
6//! useful for human operators and AI agents. Every command carries rich
7//! metadata — summaries, descriptions, typed arguments, flags, examples, and
8//! best-practice guidance — that can be serialized to JSON or rendered as
9//! Markdown for consumption by an LLM tool-call layer.
10//!
11//! ## Architecture
12//!
13//! The library is built around five cooperating layers:
14//!
15//! 1. **[`model`]** — the data model: [`Command`], [`Argument`], [`Flag`],
16//! [`Example`], and their builders.
17//! 2. **[`resolver`]** — maps a raw string token to a [`Command`] via exact →
18//! prefix → ambiguous resolution.
19//! 3. **[`parser`]** — tokenizes a raw `argv` slice, walks the subcommand tree
20//! using the resolver, then binds flags and positional arguments.
21//! 4. **[`query`]** — [`Registry`] is the central command store; it supports
22//! lookup by canonical name, subcommand path, substring search, and fuzzy
23//! search.
24//! 5. **[`render`]** — three plain-text / Markdown renderers: [`render_help`],
25//! [`render_subcommand_list`], and [`render_markdown`].
26//!
27//! A convenience [`cli`] module provides the [`Cli`] struct, which wires all
28//! five layers together so you can go from `Vec<Command>` to a fully
29//! functional CLI dispatch loop in a few lines.
30//!
31//! ## Quick Start
32//!
33//! ```no_run
34//! use std::sync::Arc;
35//! use argot_cmd::{Command, Flag, Registry, Parser, render_help};
36//!
37//! // 1. Build commands.
38//! let cmd = Command::builder("deploy")
39//! .summary("Deploy the application to an environment")
40//! .flag(
41//! Flag::builder("env")
42//! .description("Target environment")
43//! .takes_value()
44//! .required()
45//! .build()
46//! .unwrap(),
47//! )
48//! .handler(Arc::new(|parsed| {
49//! println!("deploying to {}", parsed.flags["env"]);
50//! Ok(())
51//! }))
52//! .build()
53//! .unwrap();
54//!
55//! // 2. Store in a registry.
56//! let registry = Registry::new(vec![cmd]);
57//!
58//! // 3. Parse raw arguments.
59//! let parser = Parser::new(registry.commands());
60//! let parsed = parser.parse(&["deploy", "--env", "production"]).unwrap();
61//!
62//! // 4. Render help.
63//! let help = render_help(parsed.command);
64//! println!("{}", help);
65//! ```
66//!
67//! ## Feature Flags
68//!
69//! | Feature | Description |
70//! |-----------|-------------|
71//! | `derive` | Enables the `#[derive(ArgotCommand)]` proc-macro from `argot-cmd-derive`. |
72//! | `fuzzy` | Enables [`Registry::fuzzy_search`] via the `fuzzy-matcher` crate. |
73//! | `mcp` | Enables the MCP stdio transport server ([`transport`]). |
74//!
75//! ## Modules
76//!
77//! - [`cli`] — high-level [`Cli`] entry point
78//! - [`model`] — data model and builders
79//! - [`resolver`] — string-to-command resolution
80//! - [`parser`] — `argv` parsing
81//! - [`query`] — command registry and search
82//! - [`render`] — human-readable and Markdown output
83
84#![forbid(unsafe_code)]
85#![warn(missing_docs)]
86
87pub mod cli;
88pub mod input_validation;
89pub mod middleware;
90pub mod model;
91pub mod parser;
92pub mod query;
93pub mod render;
94pub mod resolver;
95
96pub use cli::{Cli, CliError};
97pub use input_validation::{InputValidator, ValidationError};
98pub use middleware::Middleware;
99
100pub use model::{
101 Argument, ArgumentBuilder, BuildError, Command, CommandBuilder, Example, Flag, FlagBuilder,
102 HandlerFn, ParsedCommand,
103};
104
105#[cfg(feature = "async")]
106pub use model::AsyncHandlerFn;
107pub use parser::{ParseError, Parser};
108pub use query::{command_to_json_with_fields, command_to_ndjson, CommandEntry, QueryError, Registry};
109pub use render::{
110 render_ambiguity, render_completion, render_docs, render_help, render_json_schema,
111 render_markdown, render_resolve_error, render_skill_file, render_skill_file_with_frontmatter,
112 render_skill_files, render_skill_files_with_frontmatter, render_subcommand_list,
113 DefaultRenderer, Renderer, SkillFrontmatter, Shell,
114};
115pub use resolver::{ResolveError, Resolver};
116
117/// Trait implemented by types annotated with `#[derive(ArgotCommand)]`.
118///
119/// Call `T::command()` to obtain a fully-built [`Command`] from the struct's
120/// `#[argot(...)]` attributes.
121///
122/// # Examples
123///
124/// ```
125/// # #[cfg(feature = "derive")] {
126/// use argot_cmd::ArgotCommand;
127///
128/// #[derive(argot_cmd::ArgotCommand)]
129/// #[argot(summary = "Greet the world")]
130/// struct Greet;
131///
132/// let cmd = Greet::command();
133/// assert_eq!(cmd.canonical, "greet");
134/// # }
135/// ```
136pub trait ArgotCommand {
137 /// Return the [`Command`] described by this type's `#[argot(...)]`
138 /// attributes.
139 fn command() -> Command;
140}
141
142#[cfg(feature = "derive")]
143pub use argot_cmd_derive::ArgotCommand;
144
145/// MCP (Model Context Protocol) stdio transport server.
146///
147/// Enable with the `mcp` feature flag. Exposes the command registry as MCP
148/// tools over a newline-delimited JSON-RPC 2.0 stream.
149#[cfg(feature = "mcp")]
150pub mod transport;
151#[cfg(feature = "mcp")]
152pub use transport::McpServer;