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
//! Hook system for event-driven callbacks and permission management.
//!
//! The hooks module provides a flexible system for responding to lifecycle events in Claude agents.
//! Hooks can intercept tool uses, user prompts, and session events, allowing you to:
//!
//! - Control which tools can be used
//! - Inject additional context into Claude's prompts
//! - Modify tool inputs before execution
//! - Implement custom permission policies
//!
//! # Architecture
//!
//! The hook system consists of several key components:
//!
//! - `HookEvent` - Events that trigger hooks (defined in options module)
//! - `HookMatcher` - Pattern matching for selective hook triggering
//! - `HookCallback` - Trait for implementing hook logic
//! - `HookInput` - Data passed to hooks
//! - `HookContext` - Session context available to hooks
//! - `HookResponse` - Response with permission decisions
//!
//! # Examples
//!
//! ## Basic Hook: Block Dangerous Tools
//!
//! ```
//! use rusty_claw::prelude::*;
//!
//! async fn block_rm(
//! input: HookInput,
//! _tool_use_id: Option<&str>,
//! _context: &HookContext,
//! ) -> Result<HookResponse, ClawError> {
//! if let Some(tool_name) = &input.tool_name {
//! if tool_name == "Bash" {
//! if let Some(tool_input) = &input.tool_input {
//! if let Some(cmd) = tool_input.get("command").and_then(|v| v.as_str()) {
//! if cmd.contains("rm -rf") {
//! return Ok(HookResponse::deny("Destructive command blocked"));
//! }
//! }
//! }
//! }
//! }
//! Ok(HookResponse::allow("Safe"))
//! }
//! ```
//!
//! ## Hook with Context Injection
//!
//! ```
//! use rusty_claw::prelude::*;
//!
//! async fn inject_context(
//! input: HookInput,
//! _tool_use_id: Option<&str>,
//! context: &HookContext,
//! ) -> Result<HookResponse, ClawError> {
//! let additional_context = if let Some(tools) = &context.available_tools {
//! format!("Available tools: {}", tools.join(", "))
//! } else {
//! "No tools available".to_string()
//! };
//!
//! Ok(HookResponse::allow("Approved")
//! .with_context(additional_context))
//! }
//! ```
//!
//! ## Pattern Matching
//!
//! ```
//! use rusty_claw::prelude::*;
//!
//! // Match all tools
//! let matcher = HookMatcher::all();
//! assert!(matcher.matches("Bash"));
//! assert!(matcher.matches("Read"));
//!
//! // Match specific tool
//! let matcher = HookMatcher::tool("Bash");
//! assert!(matcher.matches("Bash"));
//! assert!(!matcher.matches("Read"));
//! ```
pub use HookCallback;
pub use ;
pub use ;
// Re-export HookEvent and HookMatcher from options for convenience
pub use crate;