执行单个 hook 命令。 通过环境变量和 stdin 传递上下文信息给 hook 脚本: - 环境变量:HOOK_EVENT, HOOK_TOOL_NAME, HOOK_TOOL_INPUT, ... - stdin:JSON 格式的完整上下文 对应源码: hooks.rs:152-206
(
self,
command: str,
event: HookEvent,
tool_name: str,
tool_input: str,
tool_output: Optional[str],
is_error: bool,
)
| 205 | return HookRunResult.allow(messages) |
| 206 | |
| 207 | def _run_one_command( |
| 208 | self, |
| 209 | command: str, |
| 210 | event: HookEvent, |
| 211 | tool_name: str, |
| 212 | tool_input: str, |
| 213 | tool_output: Optional[str], |
| 214 | is_error: bool, |
| 215 | ) -> tuple[HookOutcome, str]: |
| 216 | """ |
| 217 | 执行单个 hook 命令。 |
| 218 | |
| 219 | 通过环境变量和 stdin 传递上下文信息给 hook 脚本: |
| 220 | - 环境变量:HOOK_EVENT, HOOK_TOOL_NAME, HOOK_TOOL_INPUT, ... |
| 221 | - stdin:JSON 格式的完整上下文 |
| 222 | |
| 223 | 对应源码: hooks.rs:152-206 |
| 224 | """ |
| 225 | # 构造传给 hook 的 JSON 数据(通过 stdin 传入) |
| 226 | payload = json.dumps({ |
| 227 | "hook_event_name": event.value, |
| 228 | "tool_name": tool_name, |
| 229 | "tool_input": tool_input, |
| 230 | "tool_output": tool_output, |
| 231 | "tool_result_is_error": is_error, |
| 232 | }) |
| 233 | |
| 234 | # 设置环境变量(hook 脚本可以直接读取) |
| 235 | env = os.environ.copy() |
| 236 | env["HOOK_EVENT"] = event.value |
| 237 | env["HOOK_TOOL_NAME"] = tool_name |
| 238 | env["HOOK_TOOL_INPUT"] = tool_input |
| 239 | env["HOOK_TOOL_IS_ERROR"] = "1" if is_error else "0" |
| 240 | if tool_output is not None: |
| 241 | env["HOOK_TOOL_OUTPUT"] = tool_output |
| 242 | |
| 243 | try: |
| 244 | result = subprocess.run( |
| 245 | ["sh", "-lc", command], # 用 shell 执行命令 |
| 246 | input=payload, # 通过 stdin 传入 JSON |
| 247 | capture_output=True, |
| 248 | text=True, |
| 249 | timeout=10, |
| 250 | env=env, |
| 251 | ) |
| 252 | |
| 253 | stdout = result.stdout.strip() |
| 254 | exit_code = result.returncode |
| 255 | |
| 256 | if exit_code == 0: |
| 257 | # 退出码 0 → 允许 |
| 258 | return (HookOutcome.ALLOW, stdout) |
| 259 | |
| 260 | elif exit_code == 2: |
| 261 | # 退出码 2 → 拒绝 |
| 262 | return (HookOutcome.DENY, stdout) |
| 263 | |
| 264 | else: |