openai / openai/codex

Hooks settings: show responsibility names instead of numbered rows

Open
#41,611 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server enhancement hooks
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Problem / outcome

The Codex App Hooks settings page labels every handler as Hook 1, Hook 2, and so on. Users with several safety, lifecycle, and automation hooks cannot identify each hook's responsibility until they expand it and inspect the command or status message.

Hook definitions currently support statusMessage, but that value is shown only in the expanded details and while a hook runs. There is no supported per-hook display-name field.

Evidence and current behavior
  • Codex App: 26.820.60940 (build 7119)
  • Bundled CLI: codex-cli 0.150.0-alpha.8
  • Standalone CLI also checked: codex-cli 0.151.0
  • Platform: Darwin 25.6.0 arm64 arm, macOS 26.6.2 (25G83)

Schemas generated from both installed CLIs with:

codex app-server generate-json-schema --experimental --out /tmp/codex-schema

ConfiguredHookHandler and HookMetadata expose statusMessage, but do not expose name, title, label, or displayName. The generated protocol does expose displayName for other resource types, so this is specific to hooks.

The installed App renderer uses the localized fallback Hook {index} for each hook row. The row title does not consume statusMessage; that field is rendered only in the expanded details.

Reproduction or baseline
  1. Add two command hooks under the same event in ~/.codex/hooks.json.
  2. Give both handlers distinct, responsibility-oriented statusMessage values.
  3. Trust the hooks and open Settings > Hooks.
  4. Expand the event.

Observed: collapsed rows are titled Hook 1 and Hook 2. Their responsibilities are invisible until each row is expanded.

Example:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "./dangerous-delete-guard.sh",
            "statusMessage": "Check dangerous recursive deletion"
          },
          {
            "type": "command",
            "command": "./package-manager-boundary-guard.sh",
            "statusMessage": "Check package-manager ownership boundary"
          }
        ]
      }
    ]
  }
}
Expected behavior

Each collapsed hook row should expose a stable, responsibility-oriented label without requiring the user to inspect its command.

Either of these backward-compatible contracts would satisfy the outcome:

  1. Add an optional displayName to configured hook handlers and HookMetadata, and render it as the row title.
  2. Render a non-empty statusMessage as the row title, falling back to Hook {index} only when no stronger label is available.

If displayName is introduced, statusMessage should remain the runtime-progress message rather than being overloaded.

Scope
  • App-server configured-hook schema and generated bindings.
  • hooks/list metadata propagation.
  • Codex App Hooks settings row title.
  • Backward-compatible fallback for existing hook files.
Non-goals
  • Changing hook execution, trust hashing, matcher semantics, ordering, or permissions.
  • Inferring a label from arbitrary shell commands.
  • Renaming plugin groups, skills, or subagents.
Acceptance criteria
  • AC-1: Given a hook with an explicit supported responsibility label, when Hooks settings are opened, then the collapsed row displays that label instead of Hook {index}.
  • AC-2: Given an existing hook without the new label, when Hooks settings are opened, then it remains valid and receives a documented fallback title.
  • AC-3: Given two hooks under the same event, when both rows are displayed, then each row can show a distinct responsibility label without parsing the command.
  • AC-4: Hook trust hashes, execution behavior, ordering, and statusMessage runtime behavior remain unchanged.
  • AC-5: Generated TypeScript and JSON Schema bindings expose the same supported contract used by the App.
Verification plan
Criterion Verification Expected
AC-1 App UI test with a labeled hook Responsibility label is visible while collapsed
AC-2 App UI test with an unlabeled legacy hook Hook loads and documented fallback is visible
AC-3 App UI test with two differently labeled hooks in one event Two distinct labels are visible
AC-4 Existing hook trust and execution test suites No hash, ordering, or execution regression
AC-5 Generate experimental JSON Schema and TypeScript bindings Supported label field is present and matches the App consumer
Risks, dependencies, rollout

The lowest-risk rollout is additive: introduce an optional field and retain Hook {index} as the final fallback. Clients should continue tolerating unknown protocol fields during version skew.

Clarifications and assumptions
  • This request is based on locally generated schemas from the listed installed versions and on the shipped App UI behavior.
  • No public Codex documentation or existing open/closed issue/PR was found that defines a supported per-hook display-name field.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by generating the experimental schema with codex app-server generate-json-schema --experimental --out /tmp/codex-schema, then trace the hooks/list metadata and the Codex App Hooks settings row title. Confirm how configured handlers and HookMetadata are represented before choosing the additive label contract. Done means labeled rows are visible when collapsed, legacy hooks retain a documented fallback, and existing trust, execution, ordering, and runtime status behavior remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, typescript
Domain
api, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.