HME hooks

June 12, 2026 ยท View on GitHub

Claude Code and Codex hooks enter through event_kernel/*_adapter.js. The kernel chooses native JS handlers first, then shell stages. Shell hooks source helpers/_hooks_bootstrap.sh first; it loads _safety.sh, _policy_enabled.sh, _onboarding.sh, _nexus.sh in the correct order and exposes _hook_decision_deny|allow|rewrite_bash envelope helpers.

Keep here only what must be a hook: pre-execution denials, lifecycle events, and terminal-facing output. Reactive enrichment belongs in tools/HME/proxy/middleware/.

Layout

  • pretooluse/ -- before a tool runs; may block with exit 2 + _emit_block
  • posttooluse/ -- after a tool completes; logging, NEXUS state, activity emission
  • lifecycle/ -- sessionstart, stop, precompact, postcompact, userpromptsubmit
  • helpers/ -- shared safety, onboarding, NEXUS, tab, signal, and IPC helpers
  • direct/ -- watchdog/supervisor entrypoints launched outside normal tool hooks
  • ../event_kernel/native_hooks/ -- portable JS handlers for tools and diagnostics

Output channels

ChannelReaches agent?Reaches terminal?Use for
STDERRYesYesLIFESAVER warnings, NEXUS transitions
STDOUT JSONYesYesPre-tool allow/block decisions
_emit_blockYesYesHard rejection with rule + fix
_emit_enrich_allowYesNoSilent KB enrichment
hme.logNoNoDebug trail

Use _emit_block "reason" only for rules the agent MUST NOT violate. For soft guidance, prefer _emit_enrich_allow or silent telemetry.

Dispatch

hooks.json is the single source of truth for both Claude Code and Codex CLI hook layouts. codex-extensions.json carries Codex-only event deltas (e.g. PermissionRequest); sync-codex-settings.py materializes ~/.codex/hooks.json by projecting the canonical manifest plus extensions through claude_settings.codex_expected_settings (collapses SessionStart matchers, swaps claude_adapter.js for codex_adapter.js, adds matcher: "*" for Codex tool-use events, drops StatusLine). Sync Claude with sync-claude-settings.py; audit both with the matching audit-*settings.py scripts. Codex user hooks may need one-time approval from /hooks.

proxy up:   Host event -> *_adapter.js -> POST /hme/lifecycle -> lifecycle_bridge.js -> dispatcher.js
proxy down: Host event -> *_adapter.js -> dispatcher.js

Both paths use the same dispatcher and policy order. Proxy HTTP middleware is absent only while the daemon is down.

Events

EventScripts firedNotes
SessionStartlifecycle/sessionstart.shOrientation, state reset, bundle health on startup/resume/clear/compact.
UserPromptSubmitlifecycle/userpromptsubmit.shStale-state sweep, lifesaver scan, autocommit.
PreToolUsenative JS or pretooluse/pretooluse_<tool>.shPre-execution gates can deny.
PermissionRequestJS policy registryCodex approval prompts reuse deny policies.
PostToolUselog-tool-call.sh + native/shell handlersLogging, NEXUS, activity, KB.
PreCompactlifecycle/precompact.shFlush KB and snapshot.
PostCompactlifecycle/postcompact.shReload KB.
Stopproxy/stop_chain + shell fallbackFirst-deny-wins stop policy chain.

Helpers

  • _safety.sh -- emit/block/streak/latency machinery; source first.
  • _autocommit.sh -- failsafe commit wrapper used by prompt/stop/direct paths.
  • _nexus.sh -- tmp/hme-nexus.state EDIT/BRIEF/REVIEW tracking.
  • _check_errors_inline.sh -- inline hme-errors.log scan.
  • _signals.sh -- append-only event bus in tools/HME/runtime/metrics/.
  • _resolve_bg_stub.sh -- resolves Claude Code background-command stubs.

Direct shell script inventory

Referenced directly or through dispatcher/native fallback: autocommit-direct.sh, canary.sh, proxy-maintenance.sh, proxy-watchdog.sh, pretooluse_bash.sh, pretooluse_check_pipeline.sh, pretooluse_edit.sh, pretooluse_grep.sh, pretooluse_hme_primer.sh, pretooluse_read.sh, pretooluse_write.sh, posttooluse_addknowledge.sh, posttooluse_bash.sh, posttooluse_edit.sh, posttooluse_hme_review.sh, posttooluse_pipeline_kb.sh, posttooluse_read_kb.sh, posttooluse_write.sh.

Supervisors (direct/)

Service metadata lives in tools/HME/config/services.json; doctors and pulse probes read that registry.

ScriptPid fileHeartbeatPurpose
proxy-supervisor.shtools/HME/runtime/proxy-supervisor.pid/health q10s, 3 misses -> respawnKeep proxy alive between sessions.
codex-proxy-supervisor.shtools/HME/runtime/codex-proxy-supervisor.pidcodex_proxy health pollKeep Codex routing alive.
universal-pulse-supervisor.shtools/HME/runtime/universal-pulse-supervisor.pidtmp/hme-universal-pulse.heartbeat q15sActive proxy/worker/daemon/CPU probes.