openclaw hooks
Inspect and configure internal hooks: handlers for command,
message, session, and Gateway events. Bare openclaw hooks runs the same report
as openclaw hooks list. These commands do not manage HTTP
Webhooks or the typed api.on(...) hook catalog in
Plugin hooks.
Target and scope
Read-only reports (hooks, list, info, check) first call hooks.status on
the selected Gateway. Configured remote Gateways and explicit
OPENCLAW_GATEWAY_URL targets are authoritative: missing remote URLs,
connection/authentication failures, and unsupported methods fail instead of
showing client-local hooks. An implicitly selected local Gateway can fall back
to local discovery when unavailable or when its hook-report method/agent
parameter is unsupported. Other errors are not silently replaced with local
inventory.
Enable, disable, install, and update mutate local files/config/state. They do
not change a remote Gateway over RPC. To change the server, run the command on
that host using its profile/config, then restart that Gateway.
--agent <id> selects the agent workspace used for inspection. It is required
when configured agents do not have an implicit owner; blank or unknown IDs
fail. The option works before or after list, info, check, enable, and
disable. It does not scope the persisted hook entry to that agent and is not
supported on install/update. See
Local, remote, and agent scope
for the distinction between workspace inventory and Gateway loading.
List hooks
Human output is a table with Status, Hook, Description, and Source columns,
preceded by
Hooks (<ready>/<total> ready). Plugin-managed sources appear as
plugin:<id>.
ready, eligible, and loadable are inventory results, not a live handler
registration check. The report does not apply the Gateway’s master switch or
configured-name selection, import the handler to prove it works, or verify that
the event has run. A bundled hook can appear ready while the internal hook
system is off. Enable the intended hook, restart, and
verify its real side effect.List JSON
The root object containsworkspaceDir, managedHooksDir, and hooks.
Each hook includes:
- Identity/display:
name,description,source, optionalpluginId,emoji,homepage, andmanagedByPlugin. - Status:
enabledByConfig,requirementsSatisfied,loadable, optionalblockedReason, plus compatibility aliaseseligible(loadable) anddisabled(!enabledByConfig). - Events/requirements:
events,unknownEvents, andmissing, whose arrays arebins,anyBins,env,config, andos.
blockedReason can be disabled in config, workspace hook (disabled by default),
missing requirements, or no events defined. Unknown events are
advisory: they do not by themselves make a hook unloadable.
Get hook info
hookKey. Exact hook names take precedence
over matching keys; a key must identify a single hook. Shows source, descriptor
and handler paths, homepage, events, unknown-event warnings, blocked reason, and
per-requirement status. A missing or ambiguous hook exits with code 1; an
ambiguous selector lists candidates so you can choose a unique name or key.
JSON includes the list fields plus filePath, baseDir, handlerPath,
hookKey, always, requirements, configChecks, and normalized install
options. Each config check has path and satisfied; each install option has
id, kind, label, and bins. Install options are descriptive metadata, not
a command to install dependencies automatically.
Check eligibility
total, eligible, notEligible, and hooks containing an eligible name
array and a notEligible array of { name, blockedReason?, missing } objects.
A successful report exits with code 0 even when hooks are not ready. For an
automated eligibility gate, inspect the JSON counts rather than treating the
exit code as an all-hooks-ready result. This still does not test actual loading.
Enable a hook
hooks.internal.entries.<hookKey>.enabled = true and
hooks.internal.enabled = true in local config. Other fields in that entry are
preserved. Exact hook names take precedence over matching keys; ambiguous key
matches fail without writing.
Enable fails for a missing hook, a plugin-managed hook, or unmet runtime
requirements. It can enable a currently disabled workspace hook. This does not
prove a valid module export or event subscription; inspect info and the
Gateway logs too.
The entry is global, even with --agent: it applies wherever that key is
discovered. Adding named entries can narrow a previously open-ended directory
selection. See Configuration.
Restart after enabling:
hooks enable.
Disable a hook
hooks.internal.entries.<hookKey>.enabled = false. It does not remove the
hook files or change the master switch. Missing/ambiguous and plugin-managed
hooks are rejected; missing runtime requirements do not prevent disabling.
Restart the Gateway afterward.
Plugin-managed hooks cannot be toggled by these commands. Enable or disable the
owning plugin through openclaw plugins.
Install and update hook packs
Use the unified plugin installer for reviewed hook packs:package.json under openclaw.hooks.
A local directory without package.json can contain a single HOOK.md and
handler. Copied hook packs are installed into <stateDir>/hooks/<id>; their
hooks are enabled in config and install provenance is recorded in shared SQLite
state. Restart the Gateway to load them. Do not author
hooks.internal.installs in openclaw.json.
For the npm hook-pack path, specs are registry-only: package name with an
optional exact version or dist-tag. Git/URL/file specs, npm aliases, and semver
ranges are not npm registry specs. Bare specs and @latest stay on the stable
track; a prerelease resolution requires an explicit prerelease version or a
non-latest tag such as @beta or @rc. Use npm: to select npm explicitly; the
unified installer supports other plugin sources described in
openclaw plugins.
Supported local archives are .zip, .tgz, .tar.gz, and .tar. Copied hook
packs resolve runtime packages from dependencies and optionalDependencies,
including packs with only optional dependencies. Packages listed only in
devDependencies are omitted. npm pack and dependency installation use
--ignore-scripts; this does not sandbox the installed handler.
The download always creates an archive in OpenClaw’s temporary workspace,
regardless of npm’s dry-run or pack-destination settings.
Install options and trust
Interactive non-ClawHub installs ask you to confirm trust. Noninteractive
installs require
--force; neither plugins install nor the hooks install
alias accepts a --yes flag. --force is also not a substitute for
acknowledging an install-policy warning. Review the source before supplying
either acknowledgement.
Update behavior
Updates use tracked npm install records. A tracked hook-pack ID uses its stored spec; a matching npm package spec can select a new version/tag. Local path and archive records are not refreshed by the npm hook updater.--dry-run reports what would change without installing or rewriting config.
--all selects both plugins and hook packs in the unified updater, including
when reached through the deprecated alias; it is not a hooks-only bulk command.
When an applicable stored integrity hash differs from the downloaded artifact,
the updater warns and asks for confirmation in the terminal. No CLI flag answers
that prompt: neither plugins update nor the hooks update alias accepts
--yes, and --acknowledge-install-policy-warning covers only install-policy
warnings. --dry-run reports the drift without prompting.
Deprecated aliases
These commands print a deprecation warning and forward to the unified owners:id or --all. The aliases do not accept --agent and are
not the preferred interface for new automation.
Bundled hooks
The maintained catalog, event subscriptions, options, and verification notes are in Bundled hooks. This includesboot-md, bootstrap-extra-files, command-logger, compaction-notifier, and
session-memory (manual and automatic reset capture).
command-logger log file
On the Gateway host, with the default state directory:<stateDir>/logs/commands.log for a custom state directory. These records
contain session and sender identifiers; protect access and arrange retention or
rotation. The hook does not rotate them.
Notes
Report commands support--json; success JSON goes directly to stdout. Failures
use the standard CLI JSON failure envelope, and missing
hook info also includes the requested hook name. Reports do not execute a hook
as a test.
The hidden hooks relay command is reserved for generated native harness
integration. It is not an internal-hook testing or manual event-trigger command.