use crate::{
config::{EffectiveConfig, Settings},
output::{OutputMode, output_mode},
sessions::Session,
};
use anyhow::Result;
use std::{
io::{self, Write},
path::Path,
};
pub(super) fn run_print_mode(
config: &EffectiveConfig,
instructions: &[crate::instructions::InstructionFile],
skills: &crate::skills::SkillDiscovery,
settings: &Settings,
prompt: &[String],
session: Option<&Session>,
cwd: &Path,
) -> Result<()> {
let prompt = prompt.join(" ");
if prompt.trim().is_empty() {
anyhow::bail!("print mode requires a prompt");
}
if !config.auth_state().is_ready() {
let error = config.missing_auth_error();
super::diagnostics::record_error(session, cwd, &error.to_string())?;
return Err(error.into());
}
let stdout = io::stdout();
let mut writer = stdout.lock();
let mode = output_mode(false, !config.no_color, false);
run_print_mode_streaming_with_mode(&mut writer, mode, session, cwd, |session, cwd, sink| {
crate::agent::runner::run_provider_once_streaming(
config,
instructions,
skills,
crate::agent::runner::ProviderRunOptions {
settings: Some(settings.clone()),
prompt: &prompt,
session,
cwd,
output_sink: Some(sink),
selected_primary_agent: None,
cancellation: None,
session_title_notifier: None,
invocation_mode: crate::output::InvocationMode::Print,
disabled_tools: None,
disabled_subagent_profiles: None,
subagent_profile_discovery: None,
mcp: None,
},
)
})
.map(|_| ())
}
#[cfg(test)]
pub(super) fn run_print_mode_streaming_with_runner<W: Write>(
writer: &mut W,
session: Option<&Session>,
cwd: &Path,
runner: impl FnOnce(
Option<&Session>,
&Path,
&mut dyn crate::agent::AgentOutputSink,
) -> Result<crate::agent::AgentRunOutput>,
) -> Result<crate::agent::AgentRunOutput> {
run_print_mode_streaming_with_mode(writer, OutputMode::Plain, session, cwd, runner)
}
pub(super) fn run_print_mode_streaming_with_mode<W: Write>(
writer: &mut W,
mode: OutputMode,
session: Option<&Session>,
cwd: &Path,
runner: impl FnOnce(
Option<&Session>,
&Path,
&mut dyn crate::agent::AgentOutputSink,
) -> Result<crate::agent::AgentRunOutput>,
) -> Result<crate::agent::AgentRunOutput> {
let mut sink = super::CliOutputSink::with_mode(writer, mode);
let result =
run_print_mode_with_runner(session, cwd, |session, cwd| runner(session, cwd, &mut sink));
sink.finish_line()?;
result
}
pub(super) fn run_print_mode_with_runner(
session: Option<&Session>,
cwd: &Path,
runner: impl FnOnce(Option<&Session>, &Path) -> Result<crate::agent::AgentRunOutput>,
) -> Result<crate::agent::AgentRunOutput> {
match runner(session, cwd) {
Ok(output) => Ok(output),
Err(error) => {
super::diagnostics::record_error(session, cwd, &error.to_string())?;
Err(error)
}
}
}