Skip to content

Hooks

Hooks run custom actions at specific points in the agent lifecycle. Use them to lint files after edits, run tests after source changes, log tool usage, or enforce pre-session checks. A hook binds a shell command to a lifecycle event, with an optional matcher that filters which tools or files trigger it.

interface Hook {
event: HookEvent;
matcher?: string;
handler: string;
scope: Scope;
}

Hooks are defined in the hooks section of .ai/config.yaml:

hooks:
- event: postFileEdit
matcher: "*.ts"
handler: "npx biome check --write"
scope: project
- event: sessionStart
handler: "echo 'Session started at $(date)'"
scope: user
EventFires whenMatcher type
preToolUseBefore a tool is invokedTool name (e.g. Bash, Write)
postToolUseAfter a tool completesTool name
preFileEditBefore a file is modifiedFile glob (e.g. *.ts, src/**)
postFileEditAfter a file is modifiedFile glob
sessionStartWhen the agent session beginsNone
sessionEndWhen the agent session endsNone
userPromptSubmittedWhen the user submits a promptNone
agentStopWhen the primary agent stopsNone
subagentStopWhen a sub-agent stopsNone
errorOccurredWhen an error occursNone
FieldTypeRequiredDescription
eventHookEventYesLifecycle event to listen for
matcherstringNoFilter condition — tool name for tool events, file glob for file-edit events, omit for session/agent events
handlerstringYesShell command to execute when the hook fires
scopeScopeYesScope tier (enterprise / project / user / local)

Run the linter automatically whenever the agent modifies a TypeScript file:

- event: postFileEdit
matcher: "*.{ts,tsx}"
handler: "npx biome check --write"
scope: project

Trigger the test suite when source files change:

- event: postFileEdit
matcher: "src/**/*.ts"
handler: "npm test"
scope: project

Append a timestamped entry to a local log file whenever any tool is used:

- event: postToolUse
handler: "echo '$(date): Tool used' >> .ai/agent.log"
scope: local

Hook support is the most divergent aspect of dotai’s output. Three tools have no support at all; the remaining three have partial or full support.

AspectClaude CodeCursorCodexOpenCodeCopilotAntigravity
SupportFullPartialNoneNonePartialNone
EventClaude CodeCursorCopilot
preToolUseYesNoYes
postToolUseYesNoYes
preFileEditYesYesNo
postFileEditYesYesNo
sessionStartYesNoYes
sessionEndYesNoYes
userPromptSubmittedYesNoYes
agentStopYesNoYes
subagentStopYesNoYes
errorOccurredYesNoYes

Notes:

  • Cursor translates file-edit hooks into rule-triggered actions in .cursor/rules/. Only preFileEdit and postFileEdit map; all other events are dropped.
  • Copilot outputs hooks to .github/hooks/dotai.hooks.json. It supports 8 of the 10 events but has no mechanism for file-edit hooks.
  • Codex, OpenCode, Antigravity: No hook support. All hooks are silently dropped when emitting to these targets. If your workflow depends on hooks, these tools will not fire them.
  • Cursor: Only file-edit events (preFileEdit, postFileEdit) are emitted. Tool events, session events, and agent lifecycle events are dropped.
  • Copilot: File-edit hooks (preFileEdit, postFileEdit) are not supported. The remaining 8 events are emitted to .github/hooks/dotai.hooks.json.