Codex Plugin Hooks: SessionStart, SessionEnd, and Stop Events Explained

The Codex plugin registers three lifecycle hooks—SessionStart, SessionEnd, and Stop—in plugins/codex/hooks/hooks.json that trigger at the beginning of a session, when a session ends, and when a user aborts a review, respectively.

The OpenAI Codex Companion plugin integrates with Claude's plugin infrastructure through a declarative hook system defined in the openai/codex-plugin-cc repository. These Codex plugin hooks provide deterministic startup, shutdown, and abort flows by executing specific scripts when session lifecycle events occur.

Hook Registration in hooks.json

The canonical definition of Codex plugin hooks resides in plugins/codex/hooks/hooks.json. This JSON file declares three distinct lifecycle events that the Claude plugin infrastructure monitors and executes automatically.

The registry specifies:

  • SessionStart: Executes session-lifecycle-hook.mjs with a 5-second timeout
  • SessionEnd: Executes session-lifecycle-hook.mjs with a 5-second timeout
  • Stop: Executes stop-review-gate-hook.mjs with a 900-second (15-minute) timeout

Here is the complete hook registration configuration:

{
  "description": "Optional stop-time review gate for Codex Companion.",
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/session-lifecycle-hook.mjs\" SessionStart",
            "timeout": 5
          }
        ]
      }
    ],
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/session-lifecycle-hook.mjs\" SessionEnd",
            "timeout": 5
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/stop-review-gate-hook.mjs\"",
            "timeout": 900
          }
        ]
      }
    ]
  }
}

When Each Codex Plugin Hook Triggers

The Claude plugin engine evaluates these hooks at specific points in the Codex Companion session lifecycle.

SessionStart Hook

The SessionStart hook fires at the beginning of a Codex Companion session. It runs plugins/codex/scripts/session-lifecycle-hook.mjs with the SessionStart argument to initialize environment variables and prepare the execution context. The plugin runner enforces a strict 5-second timeout for this operation.

SessionEnd Hook

The SessionEnd hook triggers when a session finishes or is cancelled. It executes the same lifecycle script (session-lifecycle-hook.mjs) but passes the SessionEnd argument. This phase performs critical cleanup operations, including terminating running jobs and shutting down the broker. Like SessionStart, this hook has a 5-second timeout.

Stop Hook

The Stop hook activates when the optional "stop-review-gate" triggers, such as when a user explicitly aborts a review. Unlike the session hooks, this runs plugins/codex/scripts/stop-review-gate-hook.mjs with a generous 900-second timeout (15 minutes) to allow in-flight review processes to complete or gracefully terminate. This hook blocks the review gate until the script resolves.

Hook Implementation Details

The executable logic for Codex plugin hooks resides in two Node.js modules within the plugins/codex/scripts/ directory.

session-lifecycle-hook.mjs handles both startup and shutdown phases for SessionStart and SessionEnd events. It reads session metadata from stdin, sets environment variables, and manages the broker lifecycle. When invoked with SessionEnd, it ensures proper termination of running jobs and broker shutdown.

stop-review-gate-hook.mjs implements the abort logic for the Stop hook. This script executes when users trigger the stop-review-gate, providing a mechanism to block and gracefully cancel in-progress reviews within the 15-minute execution window.

Inspecting and Debugging Hooks

You can interact directly with the hook registry and scripts for testing and debugging purposes.

List Registered Hooks

To programmatically inspect which hooks are registered:

import fs from "node:fs";
import path from "node:path";

const hooksPath = path.resolve(
  process.cwd(),
  "plugins/codex/hooks/hooks.json"
);
const hooks = JSON.parse(fs.readFileSync(hooksPath, "utf8"));
console.log(Object.keys(hooks.hooks)); // → [ 'SessionStart', 'SessionEnd', 'Stop' ]

Simulate SessionStart Locally

To manually trigger the SessionStart hook for debugging:

node plugins/codex/scripts/session-lifecycle-hook.mjs SessionStart < <(echo '{"session_id":"abc123","transcript_path":"tmp/transcript.txt"}')

This mirrors the plugin runner's behavior: it reads JSON from stdin, configures environment variables, and exits silently on success.

Trigger the Stop Hook

To manually invoke the stop-review-gate logic:

node plugins/codex/scripts/stop-review-gate-hook.mjs

This script will block for up to 15 minutes, allowing in-flight review processes to finish before cancellation.

Summary

  • The Codex plugin defines three lifecycle hooks in plugins/codex/hooks/hooks.json: SessionStart, SessionEnd, and Stop.
  • SessionStart triggers at the beginning of a session with a 5-second timeout to initialize the environment.
  • SessionEnd fires when sessions terminate, using a 5-second timeout for cleanup and broker shutdown.
  • Stop activates when users abort a review, executing with a 900-second timeout to gracefully cancel in-flight processes.
  • session-lifecycle-hook.mjs handles both SessionStart and SessionEnd events.
  • stop-review-gate-hook.mjs implements the abort logic for the Stop hook.

Frequently Asked Questions

What is the timeout for the Codex plugin Stop hook?

The Stop hook executes with a 900-second timeout (15 minutes), as defined in plugins/codex/hooks/hooks.json. This extended duration allows the stop-review-gate-hook.mjs script to wait for in-flight review processes to complete before cancellation.

Where are the Codex plugin hooks defined?

Hook definitions reside in plugins/codex/hooks/hooks.json in the openai/codex-plugin-cc repository. This JSON file maps hook names (SessionStart, SessionEnd, Stop) to their respective command invocations and timeout values.

What script handles the Codex SessionStart and SessionEnd events?

The plugins/codex/scripts/session-lifecycle-hook.mjs script handles both events. The plugin runner passes either "SessionStart" or "SessionEnd" as a command-line argument to determine which lifecycle phase to execute.

When does the Stop hook trigger in the Codex plugin?

The Stop hook triggers when the optional "stop-review-gate" mechanism activates, typically when a user explicitly aborts a review. This event causes the plugin infrastructure to execute stop-review-gate-hook.mjs, blocking further review progress until the script completes or the 15-minute timeout expires.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →