# What Hooks Does the Codex Plugin Register? SessionStart, SessionEnd, and Stop Explained

> Discover the Codex plugin's SessionStart, SessionEnd, and Stop hooks. Learn how these events trigger Node.js scripts for session management and control.

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

---

**The Codex plugin registers three lifecycle hooks—SessionStart, SessionEnd, and Stop—defined in [`plugins/codex/hooks/hooks.json`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/hooks/hooks.json) that execute Node.js scripts for session initialization, cleanup, and review gate control.**

The openai/codex-plugin-cc repository implements a Claude plugin that automates Codex Companion workflows through a declarative hook system. According to the source code, the plugin registers exactly three execution hooks that trigger at specific lifecycle events, enabling deterministic startup, shutdown, and abort behaviors that integrate tightly with the Claude plugin runtime.

## The Three Codex Plugin Hooks

The hook registry in [`plugins/codex/hooks/hooks.json`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/hooks/hooks.json) declares three distinct event points that the Claude plugin engine executes automatically.

### SessionStart

The **SessionStart** hook fires at the beginning of a Codex Companion session. It runs `session-lifecycle-hook.mjs` with the `SessionStart` argument and enforces a **5-second timeout**. This script initializes environment variables required for the new session.

### SessionEnd

The **SessionEnd** hook triggers when a session finishes or is cancelled. It executes the same lifecycle script with the `SessionEnd` argument (also with a **5-second timeout**), terminating running jobs and shutting down the broker to ensure clean resource cleanup.

### Stop

The **Stop** hook activates when the optional "stop-review-gate" is triggered, such as when a user aborts a review. It runs `stop-review-gate-hook.mjs` with a **900-second (15-minute) timeout**, allowing the script to block the review gate and wait for in-flight review processes to complete before cancellation.

## Hook Registration Configuration

The JSON configuration file maps each event to a command invocation using the `${CLAUDE_PLUGIN_ROOT}` environment variable. The structure defines the hook type, the executable command, and the timeout duration.

```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
          }
        ]
      }
    ]
  }
}

```

## Implementation Scripts

The actual behavior resides in two JavaScript modules referenced by the hook definitions in the repository.

### Session Lifecycle Handler

The `session-lifecycle-hook.mjs` script handles environment-variable setup during **SessionStart** and performs comprehensive cleanup during **SessionEnd**, including terminating running jobs and shutting down the broker.

### Stop Review Gate Handler

The `stop-review-gate-hook.mjs` script implements the logic that blocks the review gate when a user explicitly stops a review. It respects the 900-second timeout defined in the hook registration, waiting for in-flight processes to finish before aborting.

## Debugging and Manual Invocation

You can inspect the registered hooks programmatically or trigger them manually for testing purposes.

### Inspecting Registered Hooks

Use Node.js to read and parse the hook registry:

```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' ]

```

### Simulating SessionStart

Mirror the plugin runner behavior by passing JSON via stdin:

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

```

### Triggering the Stop Hook

Execute the review gate abort logic directly:

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

```

This command will wait up to 15 minutes for any in-flight review processes to finish before cancelling them, as defined by the timeout in the hook registration.

## Summary

- The Codex plugin registers **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** and **SessionEnd** both use `session-lifecycle-hook.mjs` with 5-second timeouts for initialization and cleanup.
- The **Stop** hook uses `stop-review-gate-hook.mjs` with a 900-second timeout to handle user-initiated aborts and review gate blocking.
- All hooks execute as Node.js commands referenced via the `${CLAUDE_PLUGIN_ROOT}` environment variable path.

## Frequently Asked Questions

### What file contains the Codex plugin hook registration?

The hook registration is defined 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 lifecycle events to specific command invocations that the Claude plugin runtime executes automatically when those events occur.

### How long does the Stop hook wait before timing out?

The Stop hook configured in [`hooks.json`](https://github.com/openai/codex-plugin-cc/blob/main/hooks.json) specifies a **900-second (15-minute) timeout**. This extended duration allows the `stop-review-gate-hook.mjs` script to wait for in-flight review processes to finish before cancellation occurs, preventing abrupt termination of active operations.

### Can I manually trigger Codex plugin hooks for testing?

Yes, you can invoke the hook scripts directly using Node.js. For example, run `node plugins/codex/scripts/session-lifecycle-hook.mjs SessionStart` followed by a JSON payload via stdin to simulate the SessionStart event outside of the Claude plugin runtime, or invoke the Stop script directly to test review gate behavior.

### Do SessionStart and SessionEnd use the same script?

Yes, both hooks invoke the same `session-lifecycle-hook.mjs` script but pass different arguments (`SessionStart` vs `SessionEnd`). The script handles initialization logic when the argument is `SessionStart` and cleanup logic—including broker shutdown and job termination—when the argument is `SessionEnd`.