1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//! Permission management for tool usage control.
//!
//! This module provides a flexible permission system for controlling which tools
//! an agent can use during execution. It integrates with the Hook system to allow
//! custom permission logic via callbacks.
//!
//! # Architecture
//!
//! The permission system evaluates tool usage requests through multiple layers:
//!
//! 1. **Explicit Deny** - Check disallowed_tools first (highest priority)
//! 2. **Explicit Allow** - Check allowed_tools second
//! 3. **Hook Decision** - Invoke registered hooks for custom logic
//! 4. **Default Policy** - Fall back to PermissionMode setting
//!
//! # Permission Modes
//!
//! The [`PermissionMode`](crate::options::PermissionMode) enum controls default
//! behavior when no explicit allow/deny rules match:
//!
//! - `Allow` - Allow all tools by default
//! - `Ask` - Prompt user for each tool use
//! - `Deny` - Deny all tools by default
//! - `Custom` - Require hook-based decision (error if no hooks)
//! - `Default/AcceptEdits/BypassPermissions/Plan` - Use CLI defaults
//!
//! # Permission Result
//!
//! Handlers return a rich [`PermissionDecision`](crate::permissions::PermissionDecision) enum rather than a simple bool:
//!
//! - [`PermissionDecision::Allow`](crate::permissions::PermissionDecision::Allow) - Allow the tool, optionally with a modified input
//! - [`PermissionDecision::Deny`](crate::permissions::PermissionDecision::Deny) - Deny the tool, optionally interrupting the session
//!
//! # Examples
//!
//! ## Basic Permission Configuration
//!
//! ```rust
//! use rusty_claw::permissions::DefaultPermissionHandler;
//! use rusty_claw::options::PermissionMode;
//!
//! // Allow specific tools only
//! let handler = DefaultPermissionHandler::builder()
//! .mode(PermissionMode::Deny)
//! .allowed_tools(vec!["bash".to_string(), "read".to_string()])
//! .build();
//! ```
//!
//! ## With Deny List
//!
//! ```rust
//! use rusty_claw::permissions::DefaultPermissionHandler;
//! use rusty_claw::options::PermissionMode;
//!
//! // Allow all except dangerous tools
//! let handler = DefaultPermissionHandler::builder()
//! .mode(PermissionMode::Allow)
//! .disallowed_tools(vec!["bash".to_string(), "write".to_string()])
//! .build();
//! ```
//!
//! ## Input Mutation via Custom Handler
//!
//! ```rust
//! use rusty_claw::control::handlers::CanUseToolHandler;
//! use rusty_claw::permissions::PermissionDecision;
//! use rusty_claw::error::ClawError;
//! use async_trait::async_trait;
//! use serde_json::{json, Value};
//!
//! struct SanitizingHandler;
//!
//! #[async_trait]
//! impl CanUseToolHandler for SanitizingHandler {
//! async fn can_use_tool(
//! &self,
//! tool_name: &str,
//! tool_input: &Value,
//! ) -> Result<PermissionDecision, ClawError> {
//! if tool_name == "Bash" {
//! // Strip dangerous flags and return sanitized input
//! let safe_input = json!({ "command": "echo 'sanitized'" });
//! return Ok(PermissionDecision::Allow { updated_input: Some(safe_input) });
//! }
//! Ok(PermissionDecision::Allow { updated_input: None })
//! }
//! }
//! ```
pub use ;
/// Rich result type for permission decisions.
///
/// Replaces the previous `bool` return from `CanUseToolHandler::can_use_tool()`.
/// Provides additional capabilities:
///
/// - [`PermissionDecision::Allow`]: Allow tool execution, optionally replacing
/// the tool input with a sanitized or modified version.
/// - [`PermissionDecision::Deny`]: Deny tool execution, optionally interrupting
/// the entire session (not just the current tool use).
///
/// # Examples
///
/// ```rust
/// use rusty_claw::permissions::PermissionDecision;
/// use serde_json::json;
///
/// // Simple allow
/// let decision = PermissionDecision::Allow { updated_input: None };
///
/// // Allow with sanitized input (strips dangerous args)
/// let safe_input = json!({ "command": "echo safe" });
/// let decision = PermissionDecision::Allow { updated_input: Some(safe_input) };
///
/// // Simple deny
/// let decision = PermissionDecision::Deny { interrupt: false };
///
/// // Deny and interrupt the session entirely
/// let decision = PermissionDecision::Deny { interrupt: true };
/// ```