oclaw/runtime/hooks
oliver 9d2900db02 完成运行时与启动链路的全面相对路径整改,统一以仓库根为路径基准并移除 oclaw 双层硬编码。
同时补齐路径回归测试与开源自检文档,确保从非仓库 cwd 启动时 workspace 根、配置和 wiki 路径仍稳定可用。

Made-with: Cursor
2026-04-26 09:22:42 +08:00
..
bundled 完成运行时与启动链路的全面相对路径整改,统一以仓库根为路径基准并移除 oclaw 双层硬编码。 2026-04-26 09:22:42 +08:00
__init__.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
_selftest.py 重构仓库目录为统一的 runtime 分层并清理历史 openclaw 残留。 2026-04-25 01:24:23 +08:00
config.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
eligibility_from_metadata.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
frontmatter.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
gmail_watcher.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
gmail_watcher_lifecycle.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
hook_manifest_core.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
hook_types.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
hooks_status.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
internal_hooks.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
js_hook_runner.mjs 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
loader.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
merge_skill_hook_dirs.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
policy.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
README.md 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
script_handlers.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
ts_hook_runner.ts 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00
user_config_hooks.py 完成运行时与启动链路的全面相对路径整改,统一以仓库根为路径基准并移除 oclaw 双层硬编码。 2026-04-26 09:22:42 +08:00
workspace.py 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。 2026-04-26 08:34:33 +08:00

oclaw/runtime/hooks

Python hooks runtime and bundled hook packages (parity target: OpenClaw src/hooks).

What you get

  • In-process hook bus: register on type or type:action, sync/async handlers, isolated failures.
  • Directory discovery: HOOK.md + one handler file per hook directory (first match in priority order, see workspace._handler_candidates).
  • Config gating: hooks.internal.enabled and hooks.internal.entries.<hookKey>.enabled.
  • Source precedence: bundled / managed / workspace / plugin collision resolution (policy).
  • Eligibility: OS / bins / env / config paths; optional remote context from message metadata (eligibility_from_metadata + config.should_include_hook).

Handler entry priority

First existing file under the hook directory wins:

handler.py → index.py → handler.ts → index.ts → handler.mts → index.mts → handler.cts → index.cts → handler.mjs → index.mjs → handler.cjs → index.cjs → handler.sh → index.sh → handler.bash → index.bash

Hook layout

Put hooks in any of:

  • Bundled: shipped with runtime (runtime_hooks_bundled_root())
  • Managed: ~/.oclaw/hooks/<hookName>/
  • Workspace: <workspace>/hooks/<hookName>/
  • Plugin: .openclaw/extensions/<id>/.codex-plugin/plugin.json → hooks paths
  • Extra dirs: hooks.internal.load.extraDirs plus skill-side .../hooks dirs merged at runtime init

Each hook directory needs HOOK.md (YAML frontmatter with metadata.oclaw.events) plus one handler file as above.

Remote eligibility on inbound messages

Callers (e.g. gateway) may attach JSON metadata:

{
  "hookEligibility": {
    "remote": {
      "platforms": ["linux"],
      "binsPresent": ["git", "node"],
      "note": "remote agent capabilities"
    }
  }
}

Parsed by hook_eligibility_from_message_metadata and passed into initialize_hooks_runtime(..., eligibility=...). Note: hook runtime initializes once per process; the first successful init wins (see hooks_runtime.initialize_hooks_runtime).

TS parity matrix (OpenClaw src/hooks)

Legend: Done / Partial / TODO

Area Status
internal-hooks bus (register / trigger / type + type:action) Done
loader (.py import + TS/JS/shell runners, hookMode / nodeScript) Done
path boundary (handlerPath under baseDir) Done
frontmatter + metadata.oclaw Done
invocation + config enable gate Done
policy / source precedence Done
runtime eligibility (os / requires / env / config) Done
remote eligibility (platforms / hasBin / hasAnyBin) — filter API + gateway metadata wiring Done
package.json openclaw.hooks / oclaw.hooks Done
plugin hook dirs (.codex-plugin + hooks) Done
legacy hooks.internal.handlers Done
hooks list/check/info CLI (python -m oclaw.runtime.operations hooks …) Done
hooks enable / hooks disable (config file patch) Done
install / update hook packs (npm/git; TS install.ts / update.ts) Partial (hooks install / hooks update print deprecation + manual/OpenClaw guidance; no npm/git runner)
gmail watcher family Partial (config gates + initialize_hooks_runtime → start_gmail_watcher_with_logs; gog/API loop not ported). Set OCLAW_SKIP_GMAIL_WATCHER=1 (or OPENCLAW_SKIP_GMAIL_WATCHER) to no-op.
fire-and-forget / message-hook mappers TODO

Minimal self-test

From the repository root (see tests/conftest.py for sys.path layout):

python runtime/hooks/_selftest.py

or run hook discovery / parity tests:

pytest tests/test_oclaw_hooks_bundled_parity.py tests/test_oclaw_hooks_runtime.py -q

Operations CLI (from parent of this repo on sys.path, see tests/conftest.py)

python -m oclaw.runtime.operations hooks list
python -m oclaw.runtime.operations hooks list --eligible --verbose
python -m oclaw.runtime.operations hooks check --json
python -m oclaw.runtime.operations hooks info session-memory --workspace /path/to/workspace
python -m oclaw.runtime.operations hooks enable session-memory --workspace /path/to/workspace
python -m oclaw.runtime.operations hooks disable command-logger --workspace /path/to/workspace
python -m oclaw.runtime.operations hooks install ./path-or-npm-spec   # deprecated, exit 2 + hints
python -m oclaw.runtime.operations hooks update --dry-run             # deprecated, exit 2 + hints

Uses the same merged config as the agent runtime (including skill hooks/ extra dirs via merge_skill_hook_extra_dirs_into_config).

Enable matches OpenClaw semantics: the hook must satisfy requirements (bins/os/env/config) if its config entry were turned on; plugin hooks cannot be toggled from this CLI. Writes go to OCLAW_CONFIG_PATH (optional, relative paths resolved under PROJECT_ROOT) or oclaw/oclaw.json by default.