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
Here's the fix fyi:
i-have-adhd used args with ${CLAUDE_PLUGIN_ROOT}, and Codex passed that arg literally, so node tried to load Users/dev/${CLAUDE_PLUGIN_ROOT}/hooks/always-on.mjs and exited 1.
The Codex hook runner does not handle this Claude-specific args / ${CLAUDE_PLUGIN_ROOT} combination the same way Claude Code does. In the observed path, only node is executed and the SessionStart JSON on stdin is parsed as JavaScript.
If one manifest must remain Claude-compatible, a host-specific entry/adapter may be needed so Claude can keep its existing root variable while Codex receives the complete command.
Verification
With the local diff above:
the SessionStart payload invokes always-on.mjs;
the hook exits 0;
stdout/stderr are empty when .i-have-adhd-always is absent;
two regression checks pass.
The missing opt-in flag is therefore not the cause—the script already treats that case as success. This is related to #70, but the Codex args handling is the additional failure mode here.
The regression appears to have been introduced by d3cba85, which changed the hook from a single command string to separate command and args fields.
Reacted by Denis Shaporov, Maciej Piasecki, 番茄, Zhengrui Guo, evergreen-helix and Federico Vitale
Still works on macOS — I can't reproduce the original failure.
Codex CLI 0.142.5, Node v25.9.0, current main (b42a45a). With PLUGIN_ROOT set and the opt-in flag present, the SessionStart hook loads and emits the ruleset (exit 0). The args + ${CLAUDE_PLUGIN_ROOT} combination behind hook exited with code 1 is gone from hooks/hooks.json, so @lwu-st's and @fanqiecd's diagnosis matches what's in the manifest now. tests.test_always_on_hooks is 7/7 here.
One gap is left, and it's why a Codex-only user still can't turn always-on on: hooks/always-on.mjs:16 resolves the flag as CLAUDE_CONFIG_DIR || ~/.claude. On a machine with Codex but no Claude Code that directory doesn't exist, so the hook runs, finds nothing and exits silently — which looks exactly like "not supported" from the user's side. grep CODEX_HOME returns nothing in the repo; Codex's own home is CODEX_HOME || ~/.codex.
What I ran, same hook command as the manifest, only the environment changes:
environment
output
PLUGIN_ROOT + flag in CLAUDE_CONFIG_DIR
6647 bytes, exit 0
PLUGIN_ROOT, clean HOME, no CLAUDE_CONFIG_DIR
0 bytes
Happy to send a PR that checks the Codex path too — a few lines across the hooks, a test, and a line in INSTALL.md, same shape as the OpenCode (~/.config/opencode) and Pi (~/.pi/agent) paths. Only if you want it that way; CONTRIBUTING says to discuss hook semantics first.
Activity
ayghri commentedon Aug 1, 2026
Do you have any diagnostic for the failure/lack of support on codex? I haven't tried the hook on codex yet.
lwu-st commentedon Aug 9, 2026
Here's the fix fyi:
i-have-adhd used args with ${CLAUDE_PLUGIN_ROOT}, and Codex passed that arg literally, so node tried to load Users/dev/${CLAUDE_PLUGIN_ROOT}/hooks/always-on.mjs and exited 1.
fanqiecd commentedon Aug 9, 2026
Thanks for opening this. I reproduced the failure on Windows with Codex using the current
mainhook manifest (i-have-adhdv0.1.0) and Node v26.5.0.Observed
Codex reports:
main/hooks/hooks.jsoncurrently contains:The Codex hook runner does not handle this Claude-specific
args/${CLAUDE_PLUGIN_ROOT}combination the same way Claude Code does. In the observed path, onlynodeis executed and the SessionStart JSON on stdin is parsed as JavaScript.Minimal PowerShell reproduction:
This exits 1:
If the argument is forwarded literally instead, the same manifest fails with a
MODULE_NOT_FOUNDpath containing${CLAUDE_PLUGIN_ROOT}.Expected
The
SessionStarthook should invokehooks/always-on.mjsand exit 0 (silently when the opt-in flag is absent) on Codex/Windows as well as Claude Code.Minimal Codex-side fix
Putting the complete command in
commandand using Codex's plugin-root placeholder fixes the failure:{ "type": "command", - "command": "node", - "args": ["${CLAUDE_PLUGIN_ROOT}/hooks/always-on.mjs"], + "command": "node \"${PLUGIN_ROOT}/hooks/always-on.mjs\"", "timeout": 5, "statusMessage": "Checking i-have-adhd always-on flag..." }If one manifest must remain Claude-compatible, a host-specific entry/adapter may be needed so Claude can keep its existing root variable while Codex receives the complete command.
Verification
With the local diff above:
always-on.mjs;0;.i-have-adhd-alwaysis absent;The missing opt-in flag is therefore not the cause—the script already treats that case as success. This is related to #70, but the Codex
argshandling is the additional failure mode here.The regression appears to have been introduced by d3cba85, which changed the hook from a single command string to separate
commandandargsfields.ayghri commentedon Aug 17, 2026
this should be fixed in the latest commits. Let me know if the problem still persists
SergiorCode commentedon Aug 21, 2026
Still works on macOS — I can't reproduce the original failure.
Codex CLI 0.142.5, Node v25.9.0, current
main(b42a45a). WithPLUGIN_ROOTset and the opt-in flag present, the SessionStart hook loads and emits the ruleset (exit 0). Theargs+${CLAUDE_PLUGIN_ROOT}combination behindhook exited with code 1is gone fromhooks/hooks.json, so @lwu-st's and @fanqiecd's diagnosis matches what's in the manifest now.tests.test_always_on_hooksis 7/7 here.One gap is left, and it's why a Codex-only user still can't turn always-on on:
hooks/always-on.mjs:16resolves the flag asCLAUDE_CONFIG_DIR || ~/.claude. On a machine with Codex but no Claude Code that directory doesn't exist, so the hook runs, finds nothing and exits silently — which looks exactly like "not supported" from the user's side.grep CODEX_HOMEreturns nothing in the repo; Codex's own home isCODEX_HOME || ~/.codex.What I ran, same hook command as the manifest, only the environment changes:
PLUGIN_ROOT+ flag inCLAUDE_CONFIG_DIRPLUGIN_ROOT, cleanHOME, noCLAUDE_CONFIG_DIRHappy to send a PR that checks the Codex path too — a few lines across the hooks, a test, and a line in INSTALL.md, same shape as the OpenCode (
~/.config/opencode) and Pi (~/.pi/agent) paths. Only if you want it that way; CONTRIBUTING says to discuss hook semantics first.Not verified on Windows or Linux.