starpod-hooks — Lifecycle hook system for Starpod
This crate provides the hook infrastructure for the Starpod AI assistant platform. It defines hook events, input/output types, callback mechanisms, and an execution engine with timeout, cancellation, circuit breaking, eligibility checks, and file-based discovery.
Architecture
Hooks are lifecycle callbacks that fire at specific points during agent execution. They can observe events (fire-and-forget) or control behavior (blocking with decisions).
The system is built around these concepts:
- [
HookEvent] — enum of 18 lifecycle events (PreToolUse, PostToolUse, etc.) - [
HookInput] — typed payload for each event, carrying context like session ID, tool name, and tool input/output - [
HookOutput] — return value from hooks, either async (fire-and-forget) or sync (with decisions like approve/block) - [
HookCallback] — async function signature for hook implementations - [
HookCallbackMatcher] — groups callbacks with an optional regex filter, identity (name), and eligibility requirements - [
HookRegistry] — manages hooks by event type and runs them, with an integrated circuit breaker and eligibility cache
Circuit Breaker
Named hooks are automatically monitored for failures. After
[CircuitBreakerConfig::max_consecutive_failures] (default: 5) consecutive
failures, the hook is "tripped" and skipped for a cooldown period (default:
60 seconds). After cooldown, one retry is allowed; a success resets the
breaker, a failure re-opens it.
Eligibility Requirements
Hooks can declare [HookRequirements] specifying binaries that must be on
PATH, environment variables that must be set, and allowed operating systems.
Hooks whose requirements are not met are silently skipped. Results are cached
per named hook to avoid repeated which syscalls.
File-Based Discovery
[HookDiscovery] scans directories for <hook-name>/HOOK.md files with
TOML frontmatter. Each manifest declares the hook's event, matcher, timeout,
requirements, and a shell command. The command receives [HookInput] as JSON
on stdin and returns [HookOutput] as JSON on stdout.
Quick Start
use ;
let mut registry = new;
// Register a hook that fires after any Bash tool use
registry.register;
Hook Events
| Event | When it fires | Can block? |
|---|---|---|
PreToolUse |
Before tool execution | Yes — can modify input or deny |
PostToolUse |
After successful tool execution | No |
PostToolUseFailure |
After failed tool execution | No |
UserPromptSubmit |
When user sends a message | Yes |
SessionStart |
Session begins | No |
SessionEnd |
Session ends | No |
Stop |
Agent stopping | No |
Notification |
System notification | No |
SubagentStart |
Subagent launching | No |
SubagentStop |
Subagent finished | No |
PreCompact |
Before conversation compaction | No |
PermissionRequest |
Permission decision needed | Yes |
Setup |
Initial/maintenance setup | No |
TeammateIdle |
Teammate idle | No |
TaskCompleted |
Task finished | No |
ConfigChange |
Configuration changed | No |
WorktreeCreate |
Git worktree created | No |
WorktreeRemove |
Git worktree removed | No |