# xz-agent-hooks
Product-agnostic lifecycle hook **contract**, ordered **registry**, Claude/Codex **wire** parsing, **context buffer**, and **ExternalHookRunner** adapter.
```text
xz-agent/
core/ → xz-agent-core
engine/ → xz-agent-engine
hooks/ → xz-agent-hooks ← this crate
```
## Features
| Event kinds + Claude aliases | `HookEventKind::parse`, `HookEvent::{pre_tool,post_tool,permission_request,unit}` |
| Outcomes | `Continue`, `AdditionalContext`, `Deny`, `MutateArgs`, `Allow`, `Ask`, `ReplaceResult` |
| Typed merge | `merge_pre_tool` / `merge_post_tool` / `merge_permission` / `merge_inject` → `MergedEffect` |
| PreTool helpers | `PreToolEffect::{is_denied, final_args, into_final_args}`, `apply_pre_tool_args` |
| PostTool helpers | `PostToolEffect::effective_result` (replace > block_feedback > original) |
| Permission helpers | `PermissionDecision::{Allow,Deny,Ask,Unspecified}` |
| Ordered fire | `HookRegistry` (Vec order; PreTool deny short-circuit; fail-open errors) |
| Wire protocol | `parse_handler_output` — exit 0/2/3 + JSON `updatedInput` / `permissionDecision` |
| External adapter | `ExternalHookHandler` + `ExternalHookRunner` |
| Context buffer | `ContextInjectionBuffer` |
## What this crate is **not**
- Product tool names (`BashExec`, …)
- `.xz-code` / `.claude` path discovery
- Permission UI / TUI
- Session / Message types
## Product integration sketch
```rust
// 1. Implement ExternalHookRunner (shell/HTTP) in the product.
// 2. Register ExternalHookHandler into HookRegistry.
// 3. Before tool exec:
// let r = registry.fire_pre_tool(&HookEvent::pre_tool(name, args)).await;
// let effect = r.effect.as_pre_tool()...;
// let args = effect.clone().into_final_args(args)?; // Err = deny reason
// 4. After tool exec: fire_post_tool → effective_result
// 5. Drain ContextInjectionBuffer into the next LLM turn / UI
```
## Tests
```bash
cargo test -p xz-agent-hooks
cargo clippy -p xz-agent-hooks --all-targets -- -D warnings
cargo doc -p xz-agent-hooks --no-deps
```
Coverage targets (unit + `tests/end_to_end.rs`):
- All merge modes and priority rules
- Wire exit codes 0/1/2/3 + Claude JSON shapes
- Registry ordering, matcher, kind filter, remove/clear, fail-open
- ExternalHookHandler rewrite + I/O fail-open
- Context buffer drain/join
- Outcome/event serde roundtrip