HOOK.md metadata fields. Part of the Hooks guide.
Writing hooks
This example replies to a reset command and writes a fixed log marker. It does not read message content, call a model, or contact an external service.Hook structure
On the Gateway host, use a new managed hook directory. The following commands assume the default state directory and thatreset-greeting does not already
exist; choose another name rather than overwrite an existing hook.
HOOK.md and a handler file. Discovery checks, in order,
handler.ts, handler.js, index.ts, then index.js, using the first file it
finds. The example uses JavaScript so no TypeScript types or SDK imports are
needed.
Enable and load it:
/new in a disposable conversation on a configured chat channel that can
route replies, such as a direct message to the bot. Expect Reset hook ran.
in that conversation and [reset-greeting] reset hook ran in Gateway logs.
/reset triggers the same example. Normal command authorization still applies.
Use an ordinary OpenClaw conversation, not an ACP-bound thread; bound sessions
delegate reset handling to their owning runtime. Do not use Control UI/webchat
or a sessions.reset RPC as the chat-reply check:
those paths do not deliver this hook’s event.messages to the UI. The log marker
can still show that a reset event ran. See
Reply delivery for the exact boundary.
Disable the example when finished:
<workspace>/hooks/reset-greeting/, then explicitly enable the
hook. Workspace placement is not an agent sandbox or a guarantee that the
Gateway will load that workspace’s hooks.
Handler implementation
A handler exports a function returningvoid or Promise<void>. The loader uses
the default export unless metadata.openclaw.export names another export.
Returned values do not block, cancel, or rewrite the operation.
Every event has these fields:
Treat context as an observation, not a live state-editing API. Fields vary by
producer, and
cfg is not present on every event. In particular, patch events
carry cloned snapshots. The explicit mutable exception is
agent:bootstrap’s context.bootstrapFiles.
Reply delivery
Pushing toevent.messages is not a general send-message API:
A missing recipient, unsupported route, send policy, or delivery failure can
prevent a reply. Append messages before the handler’s promise settles; detached
work that pushes later can miss the producer’s delivery step. To control normal
agent replies or send cancellation, use the appropriate
typed plugin hook.
HOOK.md format
HOOK.md uses YAML frontmatter followed by human-readable Markdown:
name defaults to the directory name; use a unique, stable name.
description is shown in reports. The following fields belong under
metadata.openclaw:
Use
hooks.internal.entries.<hookKey>.enabled to control activation, not a
top-level enabled flag in HOOK.md. For historical requirement metadata,
workspace.dir, browser.enabled, and browser.evaluateEnabled default to true
when absent. workspace.dir is not a new setting you need to add to your config.