use mixtape_core::permission::{AuthorizationResponse, Grant, Scope};
use std::io::{stdout, BufRead, Write};
#[derive(Debug, Clone)]
pub struct PermissionRequest {
pub tool_name: String,
pub tool_use_id: String,
pub params_hash: String,
pub formatted_display: Option<String>,
}
pub trait ApprovalPrompter: Send + Sync {
fn prompt(&self, request: &PermissionRequest) -> AuthorizationResponse;
fn name(&self) -> &'static str;
}
pub struct SimplePrompter;
impl ApprovalPrompter for SimplePrompter {
fn name(&self) -> &'static str {
"SimplePrompter"
}
fn prompt(&self, _request: &PermissionRequest) -> AuthorizationResponse {
println!("│");
println!(
"│ \x1b[33mApprove?\x1b[0m \x1b[2m(y)es (n)o (t)rust tool (e)xact match\x1b[0m"
);
loop {
print!("│ > ");
let _ = stdout().flush();
let input = read_input();
let input = input.trim().to_lowercase();
match input.as_str() {
"y" | "yes" => {
return AuthorizationResponse::Once;
}
"e" | "exact" => {
let grant = Grant::exact(&_request.tool_name, &_request.params_hash)
.with_scope(Scope::Session);
return AuthorizationResponse::Trust { grant };
}
"t" | "tool" | "trust" => {
let grant = Grant::tool(&_request.tool_name).with_scope(Scope::Session);
return AuthorizationResponse::Trust { grant };
}
"n" | "no" | "deny" => {
return AuthorizationResponse::Deny { reason: None };
}
"" => continue,
_ => {
println!("│ \x1b[31mUse y/n/t/e\x1b[0m");
}
}
}
}
}
pub type DefaultPrompter = SimplePrompter;
pub fn read_input() -> String {
let stdin = std::io::stdin();
let mut line = String::new();
let _ = stdin.lock().read_line(&mut line);
line
}
pub fn print_confirmation(message: &str) {
println!(" \x1b[32m✓\x1b[0m {}", message);
}
pub fn prompt_for_approval(request: &PermissionRequest) -> AuthorizationResponse {
SimplePrompter.prompt(request)
}