use std::process::ExitCode;
use locode_core::Status;
pub fn write_json_line(value: &impl serde::Serialize) {
use std::io::Write;
let line = serde_json::to_string(value).unwrap_or_else(|e| {
format!(r#"{{"type":"error","message":"failed to serialize output: {e}"}}"#)
});
let mut stdout = std::io::stdout().lock();
let _ = writeln!(stdout, "{line}");
let _ = stdout.flush();
}
pub fn write_text(text: &str) {
use std::io::Write;
let mut stdout = std::io::stdout().lock();
let _ = writeln!(stdout, "{text}");
let _ = stdout.flush();
}
pub fn error_line(message: &str) {
use std::io::Write;
let _ = writeln!(std::io::stderr().lock(), "error: {message}");
}
pub fn warning_line(message: &str) {
use std::io::Write;
let _ = writeln!(std::io::stderr().lock(), "warning: {message}");
}
pub fn exit_code(status: Status) -> ExitCode {
match status {
Status::Completed | Status::MaxTurns | Status::Cancelled => ExitCode::SUCCESS,
_ => ExitCode::from(1),
}
}
pub const RESTRICTED_MODE_NOTICE: &str = "--restricted is incomplete: file access is limited to the working directory \
and every tool call asks for approval, but answers cannot be saved yet, so \
the same call asks again each time. Omit the flag to run without either.";
pub const UNRESTRICTED_MODE_NOTICE: &str = "running without approval prompts, and with file access outside the working \
directory; pass --restricted to limit both.";
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn exit_codes_map_all_statuses() {
assert_eq!(exit_code(Status::Completed), ExitCode::SUCCESS);
assert_eq!(exit_code(Status::MaxTurns), ExitCode::SUCCESS);
assert_eq!(exit_code(Status::Cancelled), ExitCode::SUCCESS);
assert_eq!(exit_code(Status::ModelError), ExitCode::from(1));
assert_eq!(exit_code(Status::Error), ExitCode::from(1));
}
}