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 base-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`/`reveal_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
88// The one atomic file installation every writer in this crate goes through.
89mod atomic_file;
90mod formatting;
91mod lint;
92mod output;
93mod protocol;
94mod redaction;
95mod validation;
96
97#[cfg(feature = "cli")]
98pub use cli::{
99 CliEmitter, CliEmitterError, LogFilters, build_cli_version, cli_parse_log_filters,
100 cli_parse_output, cli_render_version, write_raw, write_raw_exit,
101};
102#[cfg(feature = "cli")]
103pub use cli_afdata::{
104 build_afdata_cli, cli_error_event, cli_help_event, cli_invocation_invalid_event,
105 cli_output_setup_failed_event, cli_output_write_failed_event, cli_version_event,
106 render_cli_reference,
107};
108#[cfg(feature = "cli")]
109pub use cli_spec::{
110 ArgSpec, ArgSyntax, ArgValueType, BoundCliSpec, BoundInvocation, BoundOutcome, BuiltCliSpec,
111 CliError, CliErrorRule, CliHelpV2, CliOutcome, CliShape, CliSpec, CliSpecError, CliValue,
112 Combination, CommandSpec, ExitCodeSpec, FixedValue, HostScheme, OutputLifecycle, OutputPlan,
113 OutputSpec, ResolvedDocs, ResolvedHelp, ResolvedInvocation, ResolvedVersion, SourceError,
114 SourceScheme, SourceSet, SyntheticInvocation, ValueSource,
115};
116pub use error_catalog::{ErrorCatalog, ErrorCatalogError, ErrorSpec};
117pub use formatting::render;
118pub use lint::{
119 LintFinding, LintOptions, LintSeverity, RedactionCanaryError, assert_no_lint_findings,
120 assert_no_lint_findings_with_options, assert_redaction_canary_absent, assert_strict_event,
121 lint_value,
122};
123pub use output::OutputFormat;
124#[cfg(feature = "cli")]
125pub use output::OutputTo;
126pub use protocol::{
127 BuildError, DecodedError, DecodedEvent, DecodedLog, DecodedProgress, DecodedResult,
128 ErrorBuilder, Event, EventDecodeError, LogBuilder, LogLevel, ProgressBuilder,
129 ProtocolViolation, ResultBuilder, build_cli_error, decode_protocol_event, json_error, json_log,
130 json_progress, json_result, validate_protocol_event, validate_protocol_stream,
131};
132pub use redaction::{
133 OutputOptions, PlainStyle, RedactionPolicy, Redactor, redact_argv, redact_url_secrets,
134 redact_urls_in_text, redacted_value,
135};
136pub use validation::{
137 is_valid_bcp47, is_valid_rfc3339, is_valid_rfc3339_date, is_valid_rfc3339_time,
138 normalize_utc_offset,
139};
140
141#[cfg(test)]
142pub(crate) use formatting::{extract_currency_code, format_bytes_human, format_with_commas};
143
144#[cfg(test)]
145mod tests;