Skip to content

Implement full Claude Code 29-hook compatibility #584

@oxysoft

Description

@oxysoft

Context

Every Code already has real hook infrastructure, but it is split across two surfaces and stops short of Claude Code parity:

  • codex-rs Claude-style hooks currently recognize 6 events: PreToolUse, PermissionRequest, PostToolUse, SessionStart, UserPromptSubmit, Stop.
  • code-rs project hooks currently recognize 6 events: session.start, session.end, tool.before, tool.after, file.before_write, file.after_write.
  • codex-rs parses command, prompt, and agent handler configs, but current discovery skips prompt hooks, agent hooks, and async hooks; sync command hooks are the supported runtime path.

Claude Code has moved much further. The current hooks reference lists 29 hook events and 5 handler types. If Every Code wants to be the high-velocity Codex UX/product fork, this is a natural place to go to town: keep the upstream merge pipeline for core Codex, but own the operator automation surface harder than upstream.

Existing Every Code work

The closed #501 PR is especially useful as prior art: it already attempted a broader event surface, including compact, subagent, notification, and session lifecycle events. The new ticket should not restart from zero; it should decide what from that branch is still correct and port the useful pieces into the current hook architecture.

Claude Code parity target

Current Claude Code event list:

  • SessionStart
  • Setup
  • UserPromptSubmit
  • UserPromptExpansion
  • PreToolUse
  • PermissionRequest
  • PermissionDenied
  • PostToolUse
  • PostToolUseFailure
  • PostToolBatch
  • Notification
  • SubagentStart
  • SubagentStop
  • TaskCreated
  • TaskCompleted
  • Stop
  • StopFailure
  • TeammateIdle
  • InstructionsLoaded
  • ConfigChange
  • CwdChanged
  • FileChanged
  • WorktreeCreate
  • WorktreeRemove
  • PreCompact
  • PostCompact
  • Elicitation
  • ElicitationResult
  • SessionEnd

Handler type parity:

  • command
  • http
  • mcp_tool
  • prompt
  • agent

Config/runtime parity:

  • if conditional hook expressions
  • timeout
  • statusMessage
  • async command hooks
  • plugin-local hook env such as plugin root
  • hook browser/listing visibility for every event
  • stable hook keys that survive insertion/reordering
  • hook reload semantics
  • clear diagnostics for skipped, invalid, timed out, and failed hooks

Upstream Codex demand signal

There is already a large cluster of official Codex hook tickets asking for pieces of this surface:

This is exactly the kind of backlog a downstream product fork can consume faster than upstream.

Suggested implementation shape

Wave 1: one canonical hook engine

Make codex-rs/hooks the canonical Claude-compatible event engine, then map code-rs project hooks onto it or consciously keep project hooks as a thin compatibility layer. Two independent hook models will keep leaking semantics.

Deliverables:

  • Expand the event enum/config/schema/listing to the full 29-event vocabulary.
  • Keep aliases for existing code-rs event names (session.start, tool.before, etc.).
  • Add a runtime support matrix so unimplemented dispatch points can be visible instead of silently absent.

Wave 2: high-value dispatch points

Implement events with obvious Codex lifecycle anchors first:

  • SessionEnd
  • PreCompact
  • PostCompact
  • SubagentStart
  • SubagentStop
  • PostToolUseFailure
  • PostToolBatch
  • Notification
  • ConfigChange
  • CwdChanged
  • FileChanged

These cover the existing Codex upstream tickets and the most useful automation workflows.

Wave 3: handler parity

Move beyond sync command-only hooks:

  • enable prompt hooks
  • enable agent hooks
  • add HTTP hooks
  • add MCP tool hooks
  • add async command hooks
  • support if expressions

Wave 4: UX and diagnostics

Make /hooks a real operator console:

  • show all 29 events
  • show implemented vs pending dispatch support
  • show handler type support
  • show skipped hook reasons
  • show last run status and output
  • allow enabling/disabling non-managed hooks with stable keys

Open questions

  • Should Every Code aim for strict Claude input/output JSON compatibility where possible, or intentionally expose a superset with Code-specific fields?
  • Should code-rs project hook names remain first-class, or become aliases into the Claude event model?
  • Should full parity land as one epic branch or as separate waves that can merge while upstream keeps syncing?

Why this matters

Hooks are the automation spine of an agentic coding environment. Claude Code has proved the shape: users want lifecycle interception, policy gates, context injection, completion validation, and external orchestration. Every Code can use its upstream merge strategy to keep the Codex engine fresh while moving much faster on the hook/operator layer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions