Skip to main content

edict/hooks/
registry.rs

1/// Claude Code hook event type
2#[derive(Debug, Clone, PartialEq)]
3pub enum HookEvent {
4    SessionStart,
5    PreCompact,
6    PostToolUse,
7    SessionEnd,
8}
9
10impl HookEvent {
11    pub fn as_str(&self) -> &'static str {
12        match self {
13            HookEvent::SessionStart => "SessionStart",
14            HookEvent::PreCompact => "PreCompact",
15            HookEvent::PostToolUse => "PostToolUse",
16            HookEvent::SessionEnd => "SessionEnd",
17        }
18    }
19}
20
21/// Hook registry entry — event-based hooks
22#[derive(Debug, Clone)]
23pub struct HookEntry {
24    pub name: &'static str,
25    pub events: &'static [HookEvent],
26}
27
28/// Global hook registry — hooks are named by when they fire, not what they do.
29///
30/// Each hook detects context at runtime (maw repo, edict project, $AGENT)
31/// and outputs info accordingly, or exits silently.
32pub struct HookRegistry;
33
34impl HookRegistry {
35    /// Get all registered hooks
36    pub fn all() -> Vec<HookEntry> {
37        vec![
38            HookEntry {
39                name: "session-start",
40                events: &[HookEvent::SessionStart, HookEvent::PreCompact],
41            },
42            HookEntry {
43                name: "post-tool-call",
44                events: &[HookEvent::PostToolUse],
45            },
46            HookEntry {
47                name: "session-end",
48                events: &[HookEvent::SessionEnd],
49            },
50        ]
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn all_hooks_registered() {
60        let hooks = HookRegistry::all();
61        assert_eq!(hooks.len(), 3);
62        assert!(hooks.iter().any(|h| h.name == "session-start"));
63        assert!(hooks.iter().any(|h| h.name == "post-tool-call"));
64        assert!(hooks.iter().any(|h| h.name == "session-end"));
65    }
66}