Hook settings page shows generic Hook N labels instead of hook names or commands

Open 💬 2 comments Opened May 30, 2026 by majiayu000

What happened?

In the Codex desktop app Hooks settings page, configured hooks are displayed only as generic rows such as Hook 1, Hook 2, Hook 3 (localized as 钩子 1, 钩子 2, etc.).

When several hooks are registered under the same lifecycle event, it is hard to tell which toggle belongs to which hook without inspecting the underlying config manually.

Example from my current ~/.codex/hooks.json:

PreToolUse Hook 1: matcher=Bash  command=... run-hook-codex.sh vibeguard-pre-bash-guard.sh
PreToolUse Hook 2: matcher=Edit  command=... run-hook-codex.sh vibeguard-pre-edit-guard.sh
PreToolUse Hook 3: matcher=Write command=... run-hook-codex.sh vibeguard-pre-write-guard.sh

PostToolUse Hook 1: matcher=Edit       command=... run-hook-codex.sh vibeguard-post-edit-guard.sh
PostToolUse Hook 2: matcher=Write      command=... run-hook-codex.sh vibeguard-post-write-guard.sh
PostToolUse Hook 3: matcher=Bash       command=... run-hook-codex.sh vibeguard-post-build-check.sh
PostToolUse Hook 4: matcher=Edit|Write command=... run-hook-codex.sh vibeguard-post-build-check.sh

Stop Hook 1: command=... run-hook-codex.sh vibeguard-stop-guard.sh
Stop Hook 2: command=... run-hook-codex.sh vibeguard-learn-evaluator.sh
Stop Hook 3: command=... remem summarize

The UI only shows Hook 1, Hook 2, etc. for these rows, so the user cannot tell at a glance whether a row is vibeguard-pre-bash-guard.sh, vibeguard-post-build-check.sh, remem summarize, etc.

Expected behavior

The Hooks settings page should show a human-readable label per hook row. Good fallbacks would be, in order:

  1. An explicit hook name / displayName if the config schema supports it.
  2. The command basename or script name, for example vibeguard-pre-bash-guard.sh.
  3. The matcher plus command basename, for example Bash · vibeguard-pre-bash-guard.sh.
  4. Only fall back to Hook {index} if no better label can be derived.

This would make the toggles understandable and reduce the chance of disabling or trusting the wrong hook.

Actual behavior

All rows under an event use the fallback label Hook {index}. In zh-CN this appears as 钩子 {index}.

I inspected the packaged webview bundle for the installed app and found the hook row title path using the settings.hooks.event.fallbackHookTitle string (Hook {index}). I did not see the settings page rendering a command/script-derived label for the row.

Steps to reproduce

  1. Configure multiple hooks in ~/.codex/hooks.json under the same lifecycle event, for example several PreToolUse, PostToolUse, or Stop hooks.
  2. Open Codex desktop app.
  3. Go to Settings → Hooks.
  4. Expand a hook event section.
  5. Observe that rows are labeled only Hook 1, Hook 2, etc.

Environment

  • Codex desktop app: 26.527.31326 (build 3390)
  • Bundled CLI: codex-cli 0.135.0-alpha.1
  • OS: macOS 26.2 (25C56)
  • Locale observed: zh-CN, but the issue appears to come from the generic fallback label rather than the locale itself.

Notes

This does not appear to affect hook execution. It is a settings UI discoverability issue: the active hooks work, but the user cannot identify them from the settings page labels.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗