coding_agent_hooks/agents/
amazonq.rs1use anyhow::Result;
6use serde_json::Value;
7
8use super::{AgentKind, resolve_tool_name};
9use crate::input::ToolUseHookInput;
10use crate::protocol::{HookProtocol, json_str};
11
12pub struct AmazonQProtocol;
13
14impl HookProtocol for AmazonQProtocol {
15 fn agent(&self) -> AgentKind {
16 AgentKind::AmazonQ
17 }
18
19 fn parse_tool_use(&self, raw: &Value) -> Result<ToolUseHookInput> {
20 let tool_name = json_str(raw, "tool_name").to_string();
21 let original = tool_name.clone();
22 let resolved = resolve_tool_name(AgentKind::AmazonQ, &tool_name).to_string();
23
24 Ok(ToolUseHookInput {
25 session_id: json_str(raw, "session_id").to_string(),
26 transcript_path: json_str(raw, "transcript_path").to_string(),
27 cwd: json_str(raw, "cwd").to_string(),
28 permission_mode: "default".to_string(),
29 hook_event_name: json_str(raw, "hook_event_name").to_string(),
30 tool_name: resolved,
31 tool_input: raw
32 .get("tool_input")
33 .cloned()
34 .unwrap_or(Value::Object(serde_json::Map::new())),
35 tool_use_id: None,
36 tool_response: raw.get("tool_response").cloned(),
37 agent: Some(AgentKind::AmazonQ),
38 original_tool_name: Some(original),
39 })
40 }
41
42 fn format_allow(
44 &self,
45 reason: Option<&str>,
46 _context: Option<&str>,
47 _updated_input: Option<Value>,
48 ) -> Value {
49 let mut output = serde_json::json!({ "action": "allow" });
50 if let Some(r) = reason {
51 output["reason"] = Value::String(r.to_string());
52 }
53 output
54 }
55
56 fn format_deny(&self, reason: &str, _context: Option<&str>) -> Value {
57 serde_json::json!({ "action": "deny", "reason": reason })
58 }
59
60 fn format_ask(&self, _reason: Option<&str>, _context: Option<&str>) -> Value {
61 serde_json::json!({ "action": "allow" })
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn parse_amazonq_execute_bash() {
71 let raw = serde_json::json!({
72 "session_id": "q-123",
73 "cwd": "/home/user",
74 "hook_event_name": "preToolUse",
75 "tool_name": "execute_bash",
76 "tool_input": {"command": "npm test"}
77 });
78 let input = AmazonQProtocol.parse_tool_use(&raw).unwrap();
79 assert_eq!(input.tool_name, "Bash");
80 assert_eq!(input.original_tool_name.as_deref(), Some("execute_bash"));
81 }
82
83 #[test]
84 fn format_deny_amazonq() {
85 let out = AmazonQProtocol.format_deny("no", None);
86 assert_eq!(out["action"], "deny");
87 }
88}