1use crate::types::CallerKind;
2
3pub fn normalize_event(vendor: &str, caller: &CallerKind) -> String {
7 let canonical = match caller {
8 CallerKind::ClaudeCode => normalize_claude_code_event(vendor),
9 CallerKind::Cursor => normalize_cursor_event(vendor),
10 CallerKind::Windsurf => normalize_windsurf_event(vendor),
11 CallerKind::Cline => normalize_cline_event(vendor),
12 CallerKind::Amp => normalize_amp_event(vendor),
13 CallerKind::GeminiCli => normalize_gemini_cli_event(vendor),
14 CallerKind::Unknown => None,
15 };
16
17 canonical
18 .map(|s| s.to_owned())
19 .unwrap_or_else(|| vendor.to_owned())
20}
21
22fn normalize_claude_code_event(vendor: &str) -> Option<&'static str> {
23 match vendor {
24 "PreToolUse" => Some("tool:before"),
25 "PostToolUse" => Some("tool:after"),
26 "Startup" => Some("session:start"),
27 "Stop" => Some("session:stop"),
28 "SubagentStop" => Some("agent:stop"),
29 "Notification" => Some("notification"),
30 _ => None,
31 }
32}
33
34fn normalize_cursor_event(vendor: &str) -> Option<&'static str> {
35 match vendor {
36 "BeforeToolCall" => Some("tool:before"),
37 "AfterToolCall" => Some("tool:after"),
38 "SessionStart" => Some("session:start"),
39 "SessionEnd" => Some("session:stop"),
40 "Notification" => Some("notification"),
41 _ => None,
42 }
43}
44
45fn normalize_windsurf_event(vendor: &str) -> Option<&'static str> {
46 match vendor {
47 "pre_tool" => Some("tool:before"),
48 "post_tool" => Some("tool:after"),
49 "session_start" => Some("session:start"),
50 "session_end" => Some("session:stop"),
51 "notification" => Some("notification"),
52 _ => None,
53 }
54}
55
56fn normalize_cline_event(vendor: &str) -> Option<&'static str> {
57 match vendor {
58 "beforeToolUse" => Some("tool:before"),
59 "afterToolUse" => Some("tool:after"),
60 "onStart" => Some("session:start"),
61 "onStop" => Some("session:stop"),
62 _ => None,
63 }
64}
65
66fn normalize_amp_event(vendor: &str) -> Option<&'static str> {
67 match vendor {
68 "tool.before" => Some("tool:before"),
69 "tool.after" => Some("tool:after"),
70 "session.start" => Some("session:start"),
71 "session.stop" => Some("session:stop"),
72 "agent.stop" => Some("agent:stop"),
73 _ => None,
74 }
75}
76
77fn normalize_gemini_cli_event(vendor: &str) -> Option<&'static str> {
78 match vendor {
79 "BeforeTool" => Some("tool:before"),
80 "AfterTool" => Some("tool:after"),
81 "SessionStart" => Some("session:start"),
82 "SessionEnd" => Some("session:stop"),
83 "AfterAgent" => Some("agent:stop"),
84 "Notification" => Some("notification"),
85 _ => None,
86 }
87}
88
89#[cfg(test)]
94#[path = "events_tests.rs"]
95mod tests;