acp_cli/client/
permissions.rs1use serde::{Deserialize, Serialize};
2
3use crate::bridge::{PermissionKind, PermissionOption, PermissionOutcome, ToolCallInfo};
4
5#[derive(Debug, Clone, Default, Deserialize, Serialize)]
6#[serde(rename_all = "snake_case")]
7pub enum PermissionMode {
8 ApproveAll,
9 #[default]
10 ApproveReads,
11 DenyAll,
12}
13
14pub fn resolve_permission(
20 tool: &ToolCallInfo,
21 options: &[PermissionOption],
22 mode: &PermissionMode,
23) -> PermissionOutcome {
24 match mode {
25 PermissionMode::ApproveAll => select_first_allow(options),
26 PermissionMode::ApproveReads => {
27 if is_read_only_tool(&tool.name) {
28 select_first_allow(options)
29 } else {
30 PermissionOutcome::Cancelled
31 }
32 }
33 PermissionMode::DenyAll => PermissionOutcome::Cancelled,
34 }
35}
36
37pub fn is_read_only_tool(name: &str) -> bool {
39 matches!(
40 name,
41 "Read" | "Glob" | "Grep" | "WebSearch" | "WebFetch" | "LSP"
42 )
43}
44
45fn select_first_allow(options: &[PermissionOption]) -> PermissionOutcome {
46 options
47 .iter()
48 .find(|o| o.kind == PermissionKind::Allow)
49 .map(|o| PermissionOutcome::Selected {
50 option_id: o.option_id.clone(),
51 })
52 .unwrap_or(PermissionOutcome::Cancelled)
53}