start of hooks engine (#13276)

(Experimental)

This PR adds a first MVP for hooks, with SessionStart and Stop

The core design is:

- hooks live in a dedicated engine under codex-rs/hooks
- each hook type has its own event-specific file
- hook execution is synchronous and blocks normal turn progression while
running
- matching hooks run in parallel, then their results are aggregated into
a normalized HookRunSummary

On the AppServer side, hooks are exposed as operational metadata rather
than transcript-native items:

- new live notifications: hook/started, hook/completed
- persisted/replayed hook results live on Turn.hookRuns
- we intentionally did not add hook-specific ThreadItem variants

Hooks messages are not persisted, they remain ephemeral. The context
changes they add are (they get appended to the user's prompt)
This commit is contained in:
Andrei Eternal
2026-03-09 21:11:31 -07:00
committed by GitHub
parent da616136cc
commit 244b2d53f4
73 changed files with 4791 additions and 483 deletions

View File

@@ -95,6 +95,8 @@ pub enum Feature {
ApplyPatchFreeform,
/// Allow requesting additional filesystem permissions while staying sandboxed.
RequestPermissions,
/// Enable Claude-style lifecycle hooks loaded from hooks.json files.
CodexHooks,
/// Expose the built-in request_permissions tool.
RequestPermissionsTool,
/// Allow the model to request web searches that fetch live content.
@@ -591,6 +593,12 @@ pub const FEATURES: &[FeatureSpec] = &[
stage: Stage::UnderDevelopment,
default_enabled: false,
},
FeatureSpec {
id: Feature::CodexHooks,
key: "codex_hooks",
stage: Stage::UnderDevelopment,
default_enabled: false,
},
FeatureSpec {
id: Feature::RequestPermissionsTool,
key: "request_permissions_tool",