Hooks
Hooks let you run arbitrary shell commands at specific points in the Kodik agent lifecycle: before and after a tool call, on session start, during compaction, and more. Use hooks to block unwanted actions, write audit logs, automatically modify tool inputs, and much more.
Where hooks are defined
Section titled “Where hooks are defined”Hooks can come from three sources, all loaded simultaneously:
| Source | File location |
|---|---|
| Project | .kodik/hooks/hooks.json (or .kodik/hooks/hooks.toml) in the workspace root |
| User | ~/Documents/Kodik/Hooks/hooks.json (or hooks.toml) |
| Plugin | hooks/hooks.json inside an installed plugin’s directory |
Project hooks only apply to trusted workspace directories. On first encountering a hooks file, Kodik will ask you to confirm trust for that project.
Use /create-hook to scaffold a hook quickly from the chat.
Supported events
Section titled “Supported events”| Event | When it fires | Matcher target |
|---|---|---|
PreToolUse | Before any tool runs | Regex against tool name |
PostToolUse | After a tool completes | Regex against tool name |
PermissionRequest | When a tool permission is requested | Regex against tool name |
SubagentStart | When a sub-agent starts | Regex against agent type |
SubagentStop | When a sub-agent stops | Regex against agent type |
SessionStart | On session start or resume | Regex against source (startup or resume) |
PreCompact | Before context compaction | Regex against trigger (manual or auto) |
PostCompact | After context compaction | Regex against trigger (manual or auto) |
UserPromptSubmit | When the user submits a message | Matcher ignored, always fires |
Stop | When the agent stops | Matcher ignored, always fires |
The matcher
Section titled “The matcher”The matcher field is a regex string tested against the event’s discriminator value:
- Tool events (
PreToolUse,PostToolUse,PermissionRequest): matched against the tool name. - Sub-agent events (
SubagentStart,SubagentStop): matched against the agent type. SessionStart: matched against the source —startuporresume.PreCompact/PostCompact: matched against the trigger —manualorauto.UserPromptSubmit,Stop: matcher is ignored; the hook always fires.
The regex is anchored to the full value — Bash matches only the tool named Bash. Use Edit|Write or .* to match multiple values.
Hooks file format
Section titled “Hooks file format”{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "python3 audit_tool.py", "timeout": 10 } ] } ], "SessionStart": [ { "hooks": [ { "type": "command", "command": "echo session started >> ~/kodik-sessions.log" } ] } ] }}Each entry in an event array contains:
matcher— optional regex string; omitting it means “always match”.hooks— array of handlers. Onlytype: "command"is supported.command— the shell command to run.timeout— seconds before the hook is killed (default 30, range 1–300).
Hook input
Section titled “Hook input”The hook receives a JSON object on stdin describing the event:
{ "hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": { "command": "ls -la" }, "context": { ... }}Hook outcome
Section titled “Hook outcome”A hook signals its decision through its exit code and/or stdout:
| Exit code | Meaning |
|---|---|
0 | Continue execution |
2 | Block the action; stderr content becomes the block reason |
A hook can also emit structured JSON as the last non-empty line of stdout. Supported fields:
| Field | Type | Description |
|---|---|---|
decision | "block" | "approve" | Explicitly block or approve the action |
reason | string | Reason shown to the user |
modified_input | object | Modified tool input (for PreToolUse only) |
modified_prompt | string | Modified prompt text (for UserPromptSubmit only) |
additional_context | string | Extra context injected into the agent |
Example of blocking with a reason:
{ "decision": "block", "reason": "Changes to the production branch require a code review."}Environment variables
Section titled “Environment variables”Kodik injects environment variables into the hook process depending on the hook’s source:
- Project hook:
KODIK_PROJECT_ROOT— path to the project root. - User hook:
KODIK_HOOKS_ROOT— path to the user hooks directory. - Plugin hook:
KODIK_PLUGIN_ROOTandKODIK_PLUGIN_ID.
Creating a hook with /create-hook
Section titled “Creating a hook with /create-hook”Type /create-hook in the chat and describe what the hook should do. Kodik will generate and save a hooks file to .kodik/hooks/hooks.json in your project (or to the global directory if you ask). After creating a hook, reload the IDE window or start a new task for the changes to take effect.