Expand description
Lifecycle hook system for OpenDev.
Hooks are shell commands triggered by lifecycle events (tool use, session start/end, subagent spawn, etc.). They receive JSON on stdin describing the event and communicate results via exit codes and optional JSON on stdout.
§Architecture
models— Data types:HookEvent,HookCommand,HookMatcher,HookConfigexecutor—HookExecutorruns individual shell commands with timeout, stdin piping, and output capturemanager—HookManagerorchestrates hook execution: matches events to registered hooks, runs them sequentially, aggregates results
§Exit Code Protocol
- 0: Success — operation proceeds normally. Hook may emit JSON on stdout
with
additionalContext,updatedInput,permissionDecision, ordecision. - 2: Block — operation is denied. Hook may emit JSON with
reasonanddecisionfields. - Other: Error — logged and operation proceeds.
§Usage
use opendev_hooks::{HookConfig, HookEvent, HookManager};
// Load config from settings.json
let mut config: HookConfig = serde_json::from_str(r#"{"hooks":{}}"#).unwrap();
config.compile_all();
config.strip_unknown_events();
let manager = HookManager::new(config, "session-id", "/working/dir");
// Before executing a tool
let outcome = manager.run_hooks(
HookEvent::PreToolUse,
Some("bash"),
None,
).await;
if outcome.blocked {
eprintln!("Blocked: {}", outcome.block_reason);
}Re-exports§
pub use executor::HookExecutor;pub use executor::HookResult;pub use manager::HookManager;pub use manager::HookOutcome;pub use models::HookCommand;pub use models::HookConfig;pub use models::HookEvent;pub use models::HookMatcher;