You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Plugin docs/examples imply plugin-local hooks, but runtime only executes global hooks.json #16430
Codex plugin docs/examples imply that plugin-local hooks.json is a supported plugin surface, but the current runtime appears to only load hooks from config-layer hooks.json files (for example ~/.codex/hooks.json).
In practice, an installed plugin can contribute skills / .mcp.json / .app.json, but its plugin-local hooks.json does not seem to run.
Environment
Codex CLI: v0.118.0
OS: Linux
Repro
Create or install a local plugin with this shape:
.codex-plugin/plugin.json
hooks.json
scripts/runtime-hook.cjs
Put simple lifecycle hooks in hooks.json, for example SessionStart, UserPromptSubmit, Stop, each running a command that writes a file under /tmp or $HOME.
Install/enable the plugin normally so it is present under ~/.codex/plugins/cache/<marketplace>/<plugin>/local and enabled in ~/.codex/config.toml.
Start a new Codex session.
Expected
If plugin-level hooks are supported, the installed plugin's hooks.json should be discovered and executed.
Actual
The plugin installs and can be enabled, but its lifecycle hooks do not run.
If I place the exact same hooks into ~/.codex/hooks.json, they immediately start working.
Why this looks inconsistent
There are several signals that suggest plugin-local hooks are intended to work:
The plugins docs/examples mention hooks.json as a plugin companion surface.
The public plugin examples include plugin folders with hooks.json.
Example manifests include a hooks field pointing at ./hooks.json.
But the current runtime code seems to say otherwise:
codex-rs/core/src/plugins/manifest.rs parses plugin manifests and recognizes skills, mcpServers, and apps, but not hooks.
codex-rs/hooks/src/engine/discovery.rs discovers hooks by scanning config-layer folders for hooks.json, not installed plugin roots.
So right now the observed behavior is:
plugin install/load path: plugin capabilities work for skills/MCP/apps
hook runtime path: only config-layer hooks.json is actually executed
Request
Could you clarify which of these is intended?
Plugin-local hooks.json is supposed to work, and this is a runtime bug.
Plugin-local hooks.json is not supported yet, and the docs/examples should be updated to avoid implying support.
If plugin-local hooks are intended to be supported, that would make plugin packaging much cleaner because lifecycle hooks could live inside the plugin bundle instead of requiring a second global ~/.codex/hooks.json installation path.
A bit of additional technical framing that may help here:
Plugins already act as a packaging/composition boundary for reusable Codex capabilities. Today, an enabled plugin can contribute:
skills
MCP servers
apps
From that perspective, hooks look like a missing runtime capability in the same composition model. Right now, a plugin can package the tools and instructions for a workflow, but not the lifecycle behavior that should accompany that workflow.
That is why this feels more like an incomplete plugin boundary than just a docs mismatch.
expose effective hook config paths for enabled, healthy plugins
pass those paths into the existing hooks discovery/runtime
keep ordering deterministic: config-layer hooks first, plugin hooks after
That would preserve current global/workspace behavior while allowing plugins to package lifecycle behavior together with the rest of the plugin bundle.
Adding a current-version confirmation: I can still reproduce this on Codex 0.128.0-alpha.1 on macOS, specifically in codex exec.
I tested while packaging a small local plugin with both:
a stdio MCP server
a UserPromptSubmit hook
Results:
direct config-level UserPromptSubmit hook works
direct MCP registration works
plugin-packaged MCP works when present in the installed plugin cache
plugin-packaged UserPromptSubmit hook does not execute
I used a marker-file test for the hook command, so this was not just “the model didn’t see the additionalContext”; the plugin hook command itself did not run.
I also tried:
hooks/hooks.json with top-level { "hooks": { ... } }
bare top-level { "UserPromptSubmit": [...] }
manifest hooks field present / absent
relative and absolute hook commands
[features] codex_hooks = true
All plugin-bundled hook variants failed in codex exec.
One related install-path note: codex plugin marketplace add <local path> registers the marketplace in config but does not appear to install/activate local plugin components by itself; codex plugin marketplace upgrade <name> rejects local marketplaces because it expects a Git marketplace.
Confirming reproduction on 0.128.0 (release) on macOS — same setup as @zorkary's report (.codex-plugin/plugin.json with explicit hooks: "./hooks/hooks.json" + hooks/hooks.json + marketplace registered via codex plugin marketplace add . + plugin enabled + [features] codex_hooks = true).
Plugin hooks silent. Same exact command moved to top-level [[hooks.SessionStart]] / [[hooks.UserPromptSubmit]] in ~/.codex/config.toml fires immediately. Marker-file test confirms the hook command never runs from the plugin path — not a "model didn't see additionalContext" issue, the process itself isn't spawned.
Use case context: filed #21675 for the broader rule-cache proposal that this bug currently blocks distributing as a plugin. Once hooks discovery from plugin manifests works, the entire workaround collapses to a single --uninstall command.
Confirming this is still a blocker on Codex CLI 0.130.0 on macOS.
Use case: packaging SLOPE lifecycle guards as a Codex plugin. SLOPE can generate a .codex-plugin/plugin.json and package the guard dispatcher/scripts cleanly, but the lifecycle hooks still need to live in a config-layer .codex/hooks.json or ~/.codex/hooks.json to be discovered and reviewed by /hooks.
Observed locally:
codex features list reports hooks as stable/true
plugin_hooks is present but under development/false
/hooks discovers config-layer project hooks from ~/Development/fathoms/.codex/hooks.json
plugin-local hooks are not available as a usable trust/review surface, so a plugin alone cannot activate the guards
This means a clean slope hook add --level=full --harness=codex implementation currently has to install a shim into global/project hook config rather than shipping lifecycle behavior entirely inside the plugin bundle. The desired fix from @andre-menutole above would resolve that: plugin manifests should expose effective hook config paths to the existing hook discovery/runtime.
Activity
andre-menutole commentedon Apr 10, 2026
A bit of additional technical framing that may help here:
Plugins already act as a packaging/composition boundary for reusable Codex capabilities. Today, an enabled plugin can contribute:
From that perspective,
hookslook like a missing runtime capability in the same composition model. Right now, a plugin can package the tools and instructions for a workflow, but not the lifecycle behavior that should accompany that workflow.That is why this feels more like an incomplete plugin boundary than just a docs mismatch.
A minimal implementation path seems to be:
hooksin plugin manifest loading, alongsideskills/mcpServers/appsThat would preserve current global/workspace behavior while allowing plugins to package lifecycle behavior together with the rest of the plugin bundle.
zorkary commentedon May 3, 2026
Adding a current-version confirmation: I can still reproduce this on Codex
0.128.0-alpha.1on macOS, specifically incodex exec.I tested while packaging a small local plugin with both:
UserPromptSubmithookResults:
UserPromptSubmithook worksUserPromptSubmithook does not executeI used a marker-file test for the hook command, so this was not just “the model didn’t see the additionalContext”; the plugin hook command itself did not run.
I also tried:
hooks/hooks.jsonwith top-level{ "hooks": { ... } }{ "UserPromptSubmit": [...] }hooksfield present / absent[features] codex_hooks = trueAll plugin-bundled hook variants failed in
codex exec.One related install-path note:
codex plugin marketplace add <local path>registers the marketplace in config but does not appear to install/activate local plugin components by itself;codex plugin marketplace upgrade <name>rejects local marketplaces because it expects a Git marketplace.oalanicolas commentedon May 8, 2026
Confirming reproduction on
0.128.0(release) on macOS — same setup as @zorkary's report (.codex-plugin/plugin.jsonwith explicithooks: "./hooks/hooks.json"+hooks/hooks.json+ marketplace registered viacodex plugin marketplace add .+ plugin enabled +[features] codex_hooks = true).Plugin hooks silent. Same exact command moved to top-level
[[hooks.SessionStart]]/[[hooks.UserPromptSubmit]]in~/.codex/config.tomlfires immediately. Marker-file test confirms the hook command never runs from the plugin path — not a "model didn't see additionalContext" issue, the process itself isn't spawned.@andre-menutole's 4-step plan upthread looks correct to me.
Use case context: filed #21675 for the broader rule-cache proposal that this bug currently blocks distributing as a plugin. Once
hooksdiscovery from plugin manifests works, the entire workaround collapses to a single--uninstallcommand.docs(v2.3.6): document Codex /plugins toggle trap and detach asymmetry
srbryers commentedon May 16, 2026
Confirming this is still a blocker on Codex CLI
0.130.0on macOS.Use case: packaging SLOPE lifecycle guards as a Codex plugin. SLOPE can generate a
.codex-plugin/plugin.jsonand package the guard dispatcher/scripts cleanly, but the lifecycle hooks still need to live in a config-layer.codex/hooks.jsonor~/.codex/hooks.jsonto be discovered and reviewed by/hooks.Observed locally:
codex features listreportshooksas stable/trueplugin_hooksis present but under development/false/hooksdiscovers config-layer project hooks from~/Development/fathoms/.codex/hooks.jsonThis means a clean
slope hook add --level=full --harness=codeximplementation currently has to install a shim into global/project hook config rather than shipping lifecycle behavior entirely inside the plugin bundle. The desired fix from @andre-menutole above would resolve that: plugin manifests should expose effective hook config paths to the existing hook discovery/runtime.docs(agent-runtime): cite upstream codex issues blocking hooks materi…
fix(codex): --with-hooks workaround for openai/codex#16430 (closes #509…
hi-onboard: 接 channel_code 归因(owner 公开页/邀请链接来路追踪)
TB-10: re-home Codex hook install to config-layer + complete trust spike
19 remaining items
git-guard: port git_guard.py onto hook-bridge for claude-code + codex…
fix(codex): --with-hooks workaround for openai/codex#16430 (closes ro…
CLI onboarding UX, colored output, build + docs cleanup (rohitg00#984)
Track upstream Codex hook-firing risk; fix plugin manifest naming
Improve plain-spokenness and clarity across agent docs and templates (#…
Add live end-to-end hook-dispatch tests (Claude Code + Codex) in CI (#31
feat(marketplace): support Agent Plugins 1.0 alongside the client man…
feat(marketplace): support Agent Plugins 1.0 alongside the client man…
feat(marketplace): distribute Magpie 0.2.0 via agent marketplaces + a…
fix(codex): adapt was still writing a hooks file, and telling the use…
v0.50.0 — the Agent Plugins manifest was silencing every hook on Code…
v0.50.0 — the Agent Plugins manifest was silencing every hook on Code…
v0.50.0 — the Agent Plugins manifest was silencing every hook on Code…
feat(codex): config-layer Codex hooks sync via launcher scripts (R1b) (…
feat(mcp): Codex plugin hooks for tool guardrails (#1620)