Skip to main content

stynx_code_types/domain/
permission.rs

1use std::sync::atomic::{AtomicU8, Ordering};
2
3use stynx_code_errors::AppResult;
4use serde_json::Value;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum PermissionDecision {
8    Allow,
9    Deny(String),
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13#[repr(u8)]
14pub enum PermissionMode {
15    Normal = 0,
16    AutoAccept = 1,
17    Plan = 2,
18    Bypass = 3,
19}
20
21impl PermissionMode {
22    pub fn next(self) -> Self {
23        match self {
24            Self::Normal => Self::AutoAccept,
25            Self::AutoAccept => Self::Plan,
26            Self::Plan => Self::Bypass,
27            Self::Bypass => Self::Normal,
28        }
29    }
30
31    pub fn label(self) -> &'static str {
32        match self {
33            Self::Normal => "Normal",
34            Self::AutoAccept => "Auto-accept",
35            Self::Plan => "Plan",
36            Self::Bypass => "Bypass",
37        }
38    }
39
40    pub fn description(self) -> &'static str {
41        match self {
42            Self::Normal => "prompts for dangerous tools",
43            Self::AutoAccept => "auto-approves all tools",
44            Self::Plan => "read-only tools only",
45            Self::Bypass => "bypasses all permission checks",
46        }
47    }
48
49    pub fn from_u8(v: u8) -> Self {
50        match v {
51            1 => Self::AutoAccept,
52            2 => Self::Plan,
53            3 => Self::Bypass,
54            _ => Self::Normal,
55        }
56    }
57
58    pub fn load(atomic: &AtomicU8) -> Self {
59        Self::from_u8(atomic.load(Ordering::Relaxed))
60    }
61
62    pub fn store(self, atomic: &AtomicU8) {
63        atomic.store(self as u8, Ordering::Relaxed);
64    }
65}
66
67#[async_trait::async_trait]
68pub trait PermissionChecker: Send + Sync {
69    async fn check(&self, tool_name: &str, input: &Value) -> AppResult<PermissionDecision>;
70}
71
72pub struct AllowAll;
73
74#[async_trait::async_trait]
75impl PermissionChecker for AllowAll {
76    async fn check(&self, _tool_name: &str, _input: &Value) -> AppResult<PermissionDecision> {
77        Ok(PermissionDecision::Allow)
78    }
79}