Cmd. /hooks
Review lifecycle hooks and manage trust or disabled state.
Written and reviewed by Eric Han · Co-founder & CTO, reopt
Key takeaways
- Review lifecycle hooks and manage trust or disabled state.
- New or changed hooks do not run until you review and trust them in
/hooks. Trust is tied to the hook content hash, and managed hooks cannot be disabled by users.
Purpose
Review lifecycle hooks and manage trust or disabled state.
/hooksAvailability
| Field | Value |
|---|---|
| Input surface | Running CLI prompt |
| Kind | Built-in |
| Status | Current reference |
| Aliases | — |
| Documented minimum | Not specified |
| Reviewed against | 2026-10-23 · Codex CLI 0.163.0 |
The installed command menu and account or organization settings determine availability.
Examples
/hooksWhen to use it
- Run
/hooksafter adding.codex/hooks.jsonor inline[hooks]config to verify source and trust state. - Before enabling plugin-bundled hooks, check
/pluginsfor plugin state and/hooksfor actual hook behavior. - Record which hooks are managed by policy and which are local project hooks.
Choosing related commands
| Command | Difference | Choose It When |
|---|---|---|
/hooks | Reviews hook sources and trust state | Hooks may run before, during, or after turns |
/plugins | Shows plugin inventory and bundled hooks | You need to know where a hook came from |
/debug-config | Explains config layers | You need precedence and policy diagnostics |
Where hooks live
| Location | Scope |
|---|---|
~/.codex/hooks.json, [hooks] in ~/.codex/config.toml | All of your sessions |
<repo>/.codex/hooks.json, [hooks] in <repo>/.codex/config.toml | That project, loaded only when the project .codex/ layer is trusted |
A plugin's hooks/hooks.json or the hooks entry in .codex-plugin/plugin.json | Enabled plugins |
Managed hooks from requirements.toml | Organization policy; users cannot disable them |
Hooks from every matching source run, and matching command hooks for the same event start concurrently. One hook cannot stop another from starting.
Minimal configuration
This .codex/hooks.json routes shell commands through a policy script before they run.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/check_command.py\"",
"timeout": 30
}
]
}
]
}
}In config.toml, write the matcher group as [[hooks.PreToolUse]] and each handler as [[hooks.PreToolUse.hooks]]. After saving, review and trust the hook in /hooks before it runs.
Hook events
| Event | When it fires | What it can do |
|---|---|---|
SessionStart | Session start, resume, clear, compact, or fork | Add stdout as developer context |
SessionEnd | Conversation archived or deleted, Codex closes, or 30 minutes idle (main thread only) | Cleanup; 1 second by default, 3 seconds max |
SubagentStart | A subagent starts | Add stdout as context |
SubagentStop | A subagent stops | Request continuation |
PreToolUse | Before a supported tool runs | Deny or rewrite the call |
PermissionRequest | Before an approval prompt appears | Allow or deny |
PostToolUse | After a tool produces output | Inspect the result |
PreCompact / PostCompact | Before and after compaction | Pre- and post-processing |
UserPromptSubmit | Before a prompt is sent | Block it, or add stdout as context |
Stop | A turn stops | Request continuation |
Interrupt | The user interrupts the main turn | Cleanup; 1 second by default, 3 seconds max |
PreToolUse covers shell commands, apply_patch file edits, MCP tool calls, and other local function tools. Hosted tools such as WebSearch are not covered.
Input and output
- Each hook receives one JSON object on stdin. Common fields are
session_id,transcript_path,cwd,hook_event_name, andmodel; some events addtool_name,tool_input,prompt, orsource. - Exit code 0 with no output means success. For events that support blocking, exit code 2 blocks the action and uses stderr as the reason.
- Return a
PreToolUsedenial inhookSpecificOutput.permissionDecisionand aPermissionRequestdecision inhookSpecificOutput.decision.behavior(allowordeny). If any matching hook denies, the request is denied. matcheris a regular expression. For tool events it filters tool names such asBash,Edit|Write, ormcp__filesystem__.*;"*"or an empty value matches everything.timeoutis in seconds and defaults to 600. Output over about 2,500 tokens is saved to disk and the model receives a preview.
Effects and persistence
Shows configured hooks and their triggers. Editing a hook changes what runs when its event occurs.
/hooks opens the hook browser so you can inspect configured lifecycle hooks, trust new or changed
hooks, and disable individual non-managed hooks before they run.
A startup warning points to /hooks when a hook needs review. Trust is tied to the hook's current hash, so a new or edited hook is skipped until you trust it again.
Cautions
Hooks are on by default. To turn them all off, set hooks = false under [features] in config.toml (codex_hooks is the older name). --dangerously-bypass-hook-trust runs enabled hooks without persisted trust for a single invocation, so keep it out of shared scripts.
- Managed hooks are trusted by policy and cannot be disabled from the user hook browser.
- Project-local hooks load only when the project
.codex/layer is trusted. - User approval of a project hook is tied to the exact content hash; review and trust it again after a change.
- MCP hook handlers reuse an existing connection, run synchronously, cannot request approval, and do not trigger other hooks. Treat auth and availability failures as a separate failure path.
- Hooks are guardrails, but they are not a complete enforcement boundary for every shell or tool path.
Official sources
Complete command list · Verification scope · History for this command