agent_first_data/lib.rs
1//! Agent-First Data (AFDATA) output formatting and protocol templates.
2//!
3//! Public APIs, grouped by concern (see each item's own docs for details;
4//! the full symbol list is the crate root's own rustdoc index, not repeated
5//! here — it drifts out of sync with a hand-maintained count otherwise):
6//! - Protocol v1 builders: [`json_result`], [`json_error`], [`json_progress`], [`json_log`]
7//! (each returns a builder; call `.build()`)
8//! - Protocol reader: [`decode_protocol_event`] parses and strict-validates one protocol
9//! line into a typed [`DecodedEvent`]
10//! - Redaction: [`redacted_value`] / [`Redactor::value`] (JSON values), [`redact_url_secrets`] /
11//! [`Redactor::url`] (URL strings), [`redact_urls_in_text`] / [`Redactor::urls_in_text`]
12//! (explicit prose URL spans), [`redact_argv`] / [`Redactor::argv`] (command lines) —
13//! `Redactor` carries custom `secret_names`/`url_names`/`policy`
14//! - Output rendering: [`render`] — the single `value × format × options → String` entry point
15//! for JSON, YAML, and plain (logfmt) output
16//! - Parse utilities: [`normalize_utc_offset`], [`is_valid_rfc3339_date`],
17//! [`is_valid_rfc3339_time`], [`is_valid_rfc3339`], [`is_valid_bcp47`]
18//! - Closed-world CLI compiler: [`CliSpec`], [`CommandSpec`], [`ArgSpec`],
19//! [`Combination`], and [`OutputSpec`] generate parsing, typed
20//! [`ResolvedInvocation`] values, output plans, and help-v2 from one registry.
21//! - Established CLI utilities: [`cli_parse_output`], [`cli_parse_log_filters`]
22//! (returns [`LogFilters`]), [`CliEmitter`], and [`write_raw`].
23//! - Domain errors and validation: [`ErrorSpec`] / [`ErrorCatalog`] declare
24//! stable public errors; [`lint_value`] and the `assert_*` helpers validate
25//! real serialized values in tests.
26//! - Documents: [`document::Document`] provides source-preserving in-memory
27//! edits and typed [`document::Document::decode`]; [`document::DocumentFile`]
28//! adds capped reads, safe first creation, atomic commits, and
29//! [`document::DocumentFile::edit_and_validate`].
30//! - (feature `skill`): [`skill::validate_skill`] / [`skill::validate_skill_named`] — strict
31//! Agent Skills `SKILL.md` front-matter validation
32//! - (feature `skill-admin`): [`skill::run_skill_admin`] — install/uninstall/status a spore's
33//! embedded Agent Skill across Codex, Claude Code, opencode, and Hermes; returns a typed
34//! [`skill::SkillReport`]
35//! - (feature `tracing`): [`afdata_tracing::AfdataLayer`] is a composable AFDATA
36//! logging layer with injectable writers and a nested-value
37//! [`afdata_tracing::StructuredLogHandle`]; [`afdata_tracing::try_init`] is
38//! the global-subscriber convenience entry point.
39//!
40//! The shared cross-language contract (which of these exist, under what name, in each of
41//! Rust/Python/TypeScript/Go) is tracked in `spec/api-surface.json` and cross-checked by
42//! `scripts/validate_api_surface.py`.
43
44#[cfg(feature = "tracing")]
45pub mod afdata_tracing;
46
47#[cfg(feature = "stream-redirect")]
48pub mod stream_redirect;
49
50#[cfg(feature = "skill-admin")]
51#[path = "skill.rs"]
52mod skill_admin;
53
54#[cfg(feature = "skill")]
55#[path = "skill_validation.rs"]
56pub mod skill;
57
58/// Format-independent document values (dot-path access, typed coercion, and
59/// pluggable JSON/TOML/YAML/dotenv/INI backends, plus a read-only Markdown
60/// block reader).
61pub mod document;
62
63/// Reading a value that named where it is — an environment variable, an
64/// address inside a config file, a stream, a terminal prompt — and the policy
65/// that separates a printable value from a credential. The grammar itself is
66/// [`cli_spec::SourceSet`]; what may be done with the result is carried by the
67/// return type, [`value_source::SecretString`].
68#[cfg(feature = "cli")]
69pub mod value_source;
70
71mod error_catalog;
72
73// The closed-world CLI compiler: spec types, build gates, argv resolution, and
74// the help-v2 model. Nothing else in this crate may reference it — only the
75// adapter below does — which `cargo build --no-default-features` proves.
76#[cfg(feature = "cli")]
77mod cli_spec;
78
79// The AFDATA CLI surface: output format parsing, the emitter, and version
80// payloads.
81#[cfg(feature = "cli")]
82mod cli;
83
84// The one place the compiler and AFDATA meet.
85#[cfg(feature = "cli")]
86mod cli_afdata;
87
88mod formatting;
89mod lint;
90mod output;
91mod protocol;
92mod redaction;
93mod validation;
94
95#[cfg(feature = "cli")]
96pub use cli::{
97 CliEmitter, CliEmitterError, LogFilters, build_cli_version, cli_parse_log_filters,
98 cli_parse_output, cli_render_version, write_raw,
99};
100#[cfg(feature = "cli")]
101pub use cli_afdata::{
102 build_afdata_cli, cli_error_event, cli_help_event, cli_invocation_invalid_event,
103 cli_version_event, render_cli_reference,
104};
105#[cfg(feature = "cli")]
106pub use cli_spec::{
107 ArgSpec, ArgSyntax, ArgValueType, BoundCliSpec, BoundInvocation, BoundOutcome, BuiltCliSpec,
108 CliError, CliErrorRule, CliHelpV2, CliOutcome, CliShape, CliSpec, CliSpecError, CliValue,
109 Combination, CommandSpec, ExitCodeSpec, FixedValue, HostScheme, OutputLifecycle, OutputPlan,
110 OutputSpec, ResolvedDocs, ResolvedHelp, ResolvedInvocation, ResolvedVersion, SourceError,
111 SourceScheme, SourceSet, SyntheticInvocation, ValueSource,
112};
113pub use error_catalog::{ErrorCatalog, ErrorCatalogError, ErrorSpec};
114pub use formatting::render;
115pub use lint::{
116 LintFinding, LintOptions, LintSeverity, RedactionCanaryError, assert_no_lint_findings,
117 assert_no_lint_findings_with_options, assert_redaction_canary_absent, assert_strict_event,
118 lint_value,
119};
120pub use output::OutputFormat;
121#[cfg(feature = "cli")]
122pub use output::OutputTo;
123pub use protocol::{
124 BuildError, DecodedError, DecodedEvent, DecodedLog, DecodedProgress, DecodedResult,
125 ErrorBuilder, Event, EventDecodeError, LogBuilder, LogLevel, ProgressBuilder,
126 ProtocolViolation, ResultBuilder, build_cli_error, decode_protocol_event, json_error, json_log,
127 json_progress, json_result, validate_protocol_event, validate_protocol_stream,
128};
129pub use redaction::{
130 OutputOptions, PlainStyle, RedactionPolicy, Redactor, redact_argv, redact_url_secrets,
131 redact_urls_in_text, redacted_value,
132};
133pub use validation::{
134 is_valid_bcp47, is_valid_rfc3339, is_valid_rfc3339_date, is_valid_rfc3339_time,
135 normalize_utc_offset,
136};
137
138#[cfg(test)]
139pub(crate) use formatting::{extract_currency_code, format_bytes_human, format_with_commas};
140
141#[cfg(test)]
142mod tests;