Claude Code vs OpenClaw hooks: events and CLI compared

16 lifecycle moments · event names from both official hook references · updated 2026-10-07

Claude Code and OpenClaw both let you run your own code at lifecycle moments, but the two hook models are shaped by different architectures. Claude Code hooks live inside a single agent session: more than thirty PascalCase events cover the loop from SessionStart through PreToolUse, PostToolUse and Stop to SessionEnd, with a matcher field narrowing when most of them fire. OpenClaw's internal hooks live in a long-running gateway that serves chat channels: fifteen colon-namespaced keys (command:new, message:received, gateway:startup) group into five families, and subscribing to a bare family name catches everything in it. The table pairs the moments that correspond; the fourth column is our note on how exact each pairing is.

Lifecycle momentClaude CodeOpenClawHow close is the match
A new conversation or session is createdSessionStartcommand:newApproximate: SessionStart fires whenever a session begins or resumes - startup, resume, clear, compact or fork, selectable by matcher. command:new comes from new-session command handling (/new), or from a Gateway session operation that emits the same hooks.
A session is resetSessionStartcommand:resetApproximate: Claude Code has no reset event - /clear is reported as SessionEnd (reason clear) followed by SessionStart (source clear). OpenClaw emits a dedicated command:reset for /reset or a Gateway session reset.
Before context compactionPreCompactsession:compact:beforeNear-identical concept; Claude Code's matcher distinguishes manual from auto.
After compaction completesPostCompactsession:compact:afterBoth fire once compaction has completed; OpenClaw's docs specify a successful compaction.
Work is stoppedStopcommand:stopSame word, different moments: Claude Code's Stop fires when Claude finishes responding and does not run after a user interrupt; OpenClaw's command:stop fires when the /stop command aborts a run.
A scheduled or idle reset-session:auto-resetNo Claude Code counterpart: its hooks reference lists no event for a session replaced by a daily or idle policy. OpenClaw's daily/idle reset is its own event; the nearest Claude Code moment is SessionStart, which fires when any session begins or resumes.
Settings or session properties changeConfigChangesession:patchLoose equivalence: ConfigChange fires when a settings, managed policy or skill file changes during a session; session:patch fires when a Gateway patch is applied to a session or a model selection is persisted.
Inbound user inputUserPromptSubmitmessage:receivedApproximate: Claude Code's hook runs before Claude processes the prompt and can block it; OpenClaw's is an asynchronous observation of an accepted inbound channel message, with transcription and preprocessing reported by the two separate events below.
Audio input transcribed-message:transcribedNo Claude Code equivalent - transcription is an OpenClaw gateway concern.
Media/link preprocessing done-message:preprocessedFires whether preprocessing ran or was skipped.
Outbound message / displayMessageDisplaymessage:sentLoose pairing: MessageDisplay is display-only and runs while assistant text streams to the screen; message:sent reports the outcome of an outbound send in context.success.
Workspace context injectionInstructionsLoadedagent:bootstrapApproximate: InstructionsLoaded fires for each CLAUDE.md or rules file loaded and is observation-only; agent:bootstrap fires during workspace bootstrap resolution, before the files are injected, and its handler can change the file list.
Session ends / gateway shuts downSessionEndgateway:shutdownLoose pairing across different architectures: SessionEnd fires when a Claude Code session ends; gateway:shutdown fires when OpenClaw's long-running gateway begins to shut down. gateway:startup and gateway:pre-restart have no Claude Code counterpart.
Subscribe to a whole family-commandOpenClaw accepts bare family names (command, session, agent, gateway, message) as catch-alls; Claude Code hooks subscribe per event, with matchers narrowing within an event.
List configured hooks/hooksopenclaw hooks listClaude Code's /hooks is an in-session command; OpenClaw manages hooks from the shell.
Enable or disable one hook-openclaw hooks enable NAMEOpenClaw's CLI switches a single hook on or off with enable and disable, and adds info and check for inspection. Claude Code's docs say an individual hook cannot be disabled while it stays in the configuration: you delete its entry, or set disableAllHooks to turn every hook off.

The structural difference is where filtering happens. Claude Code has many events and a matcher within most of them: PreToolUse alone can be narrowed by tool name, SessionStart by how the session began, StopFailure by error type. OpenClaw has fewer, more specific keys and no matcher; its docs instead note that core never emits an unlisted name, so a hook subscribed to a typo never fires - the loader logs a warning and openclaw hooks info reports the unknown event. Tool-call interception is the biggest one-sided gap: Claude Code's PreToolUse, PermissionRequest, PostToolUse and PostToolUseFailure have no counterpart among OpenClaw's internal hooks, which watch commands, sessions, messages, agent bootstrap and the gateway. OpenClaw's docs send tool interception to a separate system, plugin hooks registered through api.on(...), which this page does not compare.

Management is the mirror image. OpenClaw ships a shell CLI - openclaw hooks list, info, check, enable, disable - with an eligibility check for the binaries, environment variables, config values and operating system a hook requires. Claude Code keeps configuration in settings files, with plugins, skills and subagents able to add hooks of their own, shows the current state in the read-only /hooks menu, and decides at fire time via matchers. The event tables with per-event notes are on the two reference pages below.

Full references: Claude Code (157) · OpenClaw (116) · all comparisons