use std::env;
use std::path::PathBuf;
use crate::copilot_models::preferred_default;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PermissionPolicy {
#[default]
DenyAll,
AutoApprove,
}
pub const DEFAULT_MAX_HISTORY_TURNS: usize = 20;
#[derive(Debug, Clone)]
pub struct CopilotHeadlessConfig {
pub cli_path: Option<PathBuf>,
pub model: String,
pub github_token: Option<String>,
pub permission_policy: PermissionPolicy,
pub max_history_turns: usize,
pub mcp_tool_calling: bool,
}
impl CopilotHeadlessConfig {
#[must_use]
pub fn from_env() -> Self {
let cli_path = env::var("COPILOT_CLI_PATH").ok().map(PathBuf::from);
let model =
env::var("COPILOT_HEADLESS_MODEL").unwrap_or_else(|_| preferred_default().to_owned());
let github_token = env::var("COPILOT_GITHUB_TOKEN")
.or_else(|_| env::var("GH_TOKEN"))
.or_else(|_| env::var("GITHUB_TOKEN"))
.ok();
let permission_policy = match env::var("COPILOT_HEADLESS_PERMISSION_POLICY")
.unwrap_or_default()
.to_lowercase()
.as_str()
{
"auto_approve" | "autoapprove" | "approve" => PermissionPolicy::AutoApprove,
_ => PermissionPolicy::DenyAll,
};
let max_history_turns = env::var("COPILOT_HEADLESS_MAX_HISTORY_TURNS")
.ok()
.and_then(|v| v.parse::<usize>().ok())
.unwrap_or(DEFAULT_MAX_HISTORY_TURNS);
let mcp_tool_calling = env::var("COPILOT_HEADLESS_MCP_TOOL_CALLING")
.is_ok_and(|v| matches!(v.to_lowercase().as_str(), "1" | "true" | "yes"));
Self {
cli_path,
model,
github_token,
permission_policy,
max_history_turns,
mcp_tool_calling,
}
}
}
impl Default for CopilotHeadlessConfig {
fn default() -> Self {
Self {
cli_path: None,
model: preferred_default().to_owned(),
github_token: None,
permission_policy: PermissionPolicy::default(),
max_history_turns: DEFAULT_MAX_HISTORY_TURNS,
mcp_tool_calling: false,
}
}
}