magi-code 0.64.0

Repository-aware CLI coding agent for terminal work
Documentation
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)
        }
    }
}