Skip to main content

agcli/
lib.rs

1#![allow(clippy::pedantic)]
2//! Agent-native CLI primitives for Rust.
3//!
4//! This crate enforces an agent-first response model:
5//! - JSON envelopes for every command
6//! - HATEOAS `next_actions` for follow-up affordances
7//! - self-documenting command tree from root/help
8//! - NDJSON streaming helpers with terminal result/error events
9//! - context-safe truncation helpers for large output
10//!
11//! # Example
12//!
13//! ```ignore
14//! use agcli::{AgentCli, Command, CommandOutput, ExecutionContext, NextAction};
15//! use serde_json::json;
16//!
17//! #[tokio::main]
18//! async fn main() {
19//!     let cli = AgentCli::new("ops", "Agent-native operations CLI")
20//!         .command(
21//!             Command::new("status", "System health")
22//!                 .usage("ops status")
23//!                 .handler(|_req, _ctx| Box::pin(async move {
24//!                     Ok(CommandOutput::new(json!({ "healthy": true })).next_action(
25//!                         NextAction::new("ops status", "Re-check health"),
26//!                     ))
27//!                 })),
28//!         );
29//!
30//!     let mut ctx = ExecutionContext::default();
31//!     let run = cli.run_argv_with_context(["ops", "status"], &mut ctx).await;
32//!     assert_eq!(run.exit_code(), 0);
33//! }
34//! ```
35
36mod audit;
37mod cli;
38mod doctor;
39mod envelope;
40mod project;
41mod skill;
42mod stream;
43mod truncate;
44
45pub use audit::{AuditFinding, AuditReport, AuditSeverity};
46pub use cli::{
47    AgentCli, Command, CommandError, CommandOutput, CommandRequest, Execution, ExecutionContext,
48    Invocation, ParseInvocationError, parse_invocation, parse_invocation_with_bool_flags,
49    read_stdin, reserved_flag_names,
50};
51pub use doctor::{Check, CheckResult, CheckStatus};
52pub use envelope::{
53    ActionParam, Envelope, ErrorBody, ErrorEnvelope, ExitCode, NextAction, SuccessEnvelope,
54};
55pub use stream::{FlushPolicy, LogLevel, NdjsonEmitter, StepStatus, StreamEmitError, StreamEvent};
56pub use truncate::{TruncatedEntries, truncate_lines_with_file};