Hooks
Run or translate lifecycle behavior across harness event systems.
A hook attaches behavior to a harness lifecycle event. Event names, blocking behavior, and executable handler types vary by target, so Soubi resolves hooks through the capability map before emission.
Define a hook
Add a TypeScript or JavaScript module under hooks/:
import { defineHook } from "soubi";
export default defineHook({
event: "PreToolUse",
matcher: "Edit|Write",
description: "Protect generated and security-sensitive files.",
handler: {
type: "command",
command: "node ./scripts/guard-files.mjs",
},
});Hook modules may use .ts, .tsx, .mts, .js, or .mjs.
Choose a handler
Soubi models four handler types:
| Type | Behavior |
|---|---|
command | Run a shell command |
prompt | Ask the harness model to evaluate instructions |
agent | Delegate the event to an agent |
function | Call generated runtime code where supported |
An event can exist on a harness without supporting every handler type. soubi check reports that distinction.
Use portable command paths
Provide platform-specific commands when a hook must run on both Unix and PowerShell:
handler: {
type: "command",
command: {
unix: "./scripts/check.sh",
powershell: "./scripts/check.ps1",
},
async: true,
}async remains non-blocking only on harnesses with a compatible native feature.
Remap one target
Use a harness override when a target names an equivalent event differently:
harness: {
codex: { event: "SessionEnd" },
}Read Capability Map for event-level support and Fallback Tiers for the effect of onUnsupported.