xz-agent-hooks 0.1.0

Lifecycle hook contract, ordered registry, and wire parsers for agent extension hosts
Documentation

xz-agent-hooks

Product-agnostic lifecycle hook contract, ordered registry, Claude/Codex wire parsing, context buffer, and ExternalHookRunner adapter.

xz-agent/
  core/    → xz-agent-core
  engine/  → xz-agent-engine
  hooks/   → xz-agent-hooks   ← this crate

Features

Capability API
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_injectMergedEffect
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

// 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

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