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

> Learn about Codex Plugin hooks: SessionStart, SessionEnd, and Stop. Discover when these crucial events trigger for session management and user aborts.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-07-15

---

**The Codex plugin registers three lifecycle hooks—SessionStart, SessionEnd, and Stop—in [`plugins/codex/hooks/hooks.json`](https://github.com/openai/codex-plugin-cc/blob/main/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`](https://github.com/openai/codex-plugin-cc/blob/main/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:

```json
{
  "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:

```javascript
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:

```bash
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:

```bash
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`](https://github.com/openai/codex-plugin-cc/blob/main/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`](https://github.com/openai/codex-plugin-cc/blob/main/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`](https://github.com/openai/codex-plugin-cc/blob/main/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.