1use crate::output_fmt;
2use crate::types::Output;
3use agent_first_data::{OutputFormat, OutputTo};
4use serde_json::Value;
5use std::sync::OnceLock;
6
7static OUTPUT_TO: OnceLock<OutputTo> = OnceLock::new();
8
9pub fn set_output_to(value: OutputTo) {
18 let _ = OUTPUT_TO.set(value);
19}
20
21pub fn output_to() -> OutputTo {
22 OUTPUT_TO.get().copied().unwrap_or(OutputTo::Split)
23}
24
25pub fn emit_cli_error(
26 msg: &str,
27 hint: Option<&str>,
28 format: OutputFormat,
29) -> Result<(), agent_first_data::CliEmitterError> {
30 emit_coded_error(
31 crate::protocol::error_code::INVALID_REQUEST,
32 msg,
33 hint,
34 format,
35 )
36}
37
38pub fn emit_coded_error(
43 code: &str,
44 msg: &str,
45 hint: Option<&str>,
46 format: OutputFormat,
47) -> Result<(), agent_first_data::CliEmitterError> {
48 let mut emitter =
49 agent_first_data::CliEmitter::from_output_to(output_to(), format).with_strict_protocol();
50 let event = agent_first_data::json_error(code, msg)
51 .hint_if_some(hint)
52 .build()
53 .map_err(agent_first_data::CliEmitterError::Build)?;
54 emitter.emit(event)
55}
56
57pub fn emit_event(
58 event: agent_first_data::Event,
59 format: OutputFormat,
60) -> Result<(), agent_first_data::CliEmitterError> {
61 let mut emitter =
62 agent_first_data::CliEmitter::from_output_to(output_to(), format).with_strict_protocol();
63 emitter.emit(event)
64}
65
66pub fn emit_value(
67 value: Value,
68 format: OutputFormat,
69) -> Result<(), agent_first_data::CliEmitterError> {
70 let mut emitter =
71 agent_first_data::CliEmitter::from_output_to(output_to(), format).with_strict_protocol();
72 emitter.emit_validated_value(value)
73}
74
75pub fn emit_output(
76 out: &Output,
77 format: OutputFormat,
78) -> Result<(), agent_first_data::CliEmitterError> {
79 output_fmt::emit_process_output(out, format, output_to())
80}
81
82pub fn write_result_text(text: &str) -> std::io::Result<()> {
85 agent_first_data::write_raw(text, output_to())
86}