saya-cli 0.3.1

Database-aware AI agent for the terminal: full-screen TUI, schema discovery, and bounded read-only SQL over PostgreSQL, MySQL, SQLite, DuckDB, and Snowflake.
use saya_agent::ApprovalPolicy;

pub(crate) struct TerminalApproval {
    policy: ApprovalPolicy,
    can_prompt: bool,
}

impl TerminalApproval {
    pub(crate) fn new(policy: ApprovalPolicy, can_prompt: bool) -> Self {
        Self { policy, can_prompt }
    }
}

#[async_trait::async_trait]
impl saya_agent::ApprovalDecider for TerminalApproval {
    async fn approve(
        &self,
        tool: &saya_agent::ToolDefinition,
        arguments: &serde_json::Value,
    ) -> bool {
        match self.policy {
            ApprovalPolicy::ReadOnly => true,
            ApprovalPolicy::Never => false,
            ApprovalPolicy::Ask if !self.can_prompt => false,
            ApprovalPolicy::Ask => {
                use std::io::{self, IsTerminal, Write};
                if !io::stdin().is_terminal() {
                    return false;
                }
                // Show the exact SQL being approved when we can extract it.
                if let Some(detail) = crate::agent::tools::tool_call_detail(&tool.name, arguments) {
                    eprintln!("  {detail}");
                }
                eprint!("Allow bounded read-only SQL query? [y/N] ");
                let _ = io::stderr().flush();
                let mut answer = String::new();
                io::stdin().read_line(&mut answer).is_ok()
                    && matches!(answer.trim().to_ascii_lowercase().as_str(), "y" | "yes")
            }
        }
    }
}