# How the Codex Plugin Integrates with Claude Code's Background Job System

> Discover how the Codex plugin integrates with Claude Code's background job system. Learn about unique job IDs, persistent logs, and native infrastructure delegation. Read now!

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

---

**The Codex plugin integrates with Claude Code's background job system by wrapping the Bash sub-agent's `run_in_background` capability, using the `tracked-jobs` module to assign unique job IDs and persist logs while delegating process forking to Claude Code's native infrastructure.**

The openai/codex-plugin-cc repository enables long-running Codex operations to execute independently of active chat sessions. Understanding how the Codex plugin integrates with Claude Code's background job system reveals a clean delegation pattern where the companion script handles CLI parsing and state management while Claude Code's sub-agent infrastructure manages the heavy lifting of detached process execution.

## Architecture Overview

The integration follows a **wrapper pattern** where the Codex companion script serves as a thin orchestration layer atop Claude Code's existing job infrastructure. When users invoke commands with the `--background` (or `--wait`) flag, the system performs three distinct operations: CLI parsing, job registration, and detached execution via the Bash sub-agent.

The core components responsible for this workflow include:

- **`codex-companion.mjs`**: The CLI entry point in `plugins/codex/scripts/` that parses flags and coordinates with the job system
- **`tracked-jobs.mjs`**: The utility module in `plugins/codex/scripts/lib/` handling job ID generation, registry management, and log persistence
- **`job-control.mjs`**: Core helpers in `plugins/codex/scripts/lib/` for starting and stopping background workers
- **Claude Code Bash Sub-Agent**: The underlying execution engine that forks detached processes and manages worker lifecycles

## Job Lifecycle: From CLI to Background Execution

### Parsing the --background Flag

Background execution begins in `codex-companion.mjs` at **line 788**, where the companion script parses command-line arguments. When detecting the `--background` flag, the script switches from synchronous execution to background job mode, preparing the payload for handoff to the job tracking system. Documentation for this behavior spans lines **715-788** in the same file.

### Registering Tracked Jobs

Before spawning the worker process, the companion script creates a **tracked job** via the `tracked-jobs` module. This module assigns a unique `jobId`, initializes the job state (typically "queued"), and writes an initial log entry to disk. The in-memory registry maintains metadata about active jobs, enabling status queries even after the original CLI process exits.

### Detached Execution via Bash Sub-Agent

The actual background execution relies on Claude Code's Bash sub-agent with the option `run_in_background: true`. The companion script passes the Codex task payload—whether `task`, `review`, or `adversarial-review`—to the sub-agent, which then forks a detached worker process. This worker continues execution independently of the parent session, allowing users to close their terminal or move to other tasks while the operation completes.

## Monitoring and Status Reporting

Once a job enters the background, the `tracked-jobs` module continuously updates the job state through its registry. Status messages are appended to a dedicated log file via the `appendLogLine` function implemented at **line 686** of `codex-companion.mjs`.

Users query progress through the `/codex:status <job-id>` command, which reads the log file managed by `tracked-jobs.mjs` and reports the current phase. The system tracks standard lifecycle states including **queued**, **running**, **succeeded**, and **cancelled**, providing visibility into long-running operations without requiring persistent connection to the worker process.

## Cancelling Background Jobs

Cancellation flows through the same architectural layers. When a user issues the cancel command with a specific `jobId`, the plugin looks up the job in `tracked-jobs.mjs` and signals the Bash sub-agent to terminate the associated worker process.

The implementation details are validated in `tests/runtime.test.mjs` at **line 1542**, which tests the cancellation handshake between the plugin and Claude Code's job infrastructure. Upon successful termination, the job state updates to **cancelled** and the log file receives a final status entry documenting the interruption.

## Practical Implementation Examples

### Launching a Background Task

To execute a long-running Codex task without blocking your session:

```bash
node scripts/codex-companion.mjs task --background "investigate the failing test"

```

The companion script executes the following sequence:
1. Parses the `--background` flag at line 788
2. Registers a tracked job with a unique ID via `tracked-jobs.mjs`
3. Returns immediately: "Investigation started in the background as `<jobId>`. Check `/codex:status <jobId>` for progress."
4. Internally invokes `Bash(..., run_in_background: true)` to spawn the detached worker

### Checking Job Status

Monitor the progress of any background operation:

```bash
/codex:status <jobId>

```

This command reads the log file maintained by the `tracked-jobs` module and displays the current execution phase (queued, running, completed, or cancelled).

### Cancelling an Active Job

Terminate a running background job before completion:

```bash
node scripts/codex-companion.mjs cancel <jobId>

```

The cancellation process lookups the job ID in the registry, sends a termination signal to the Bash sub-agent worker, and updates the state to cancelled as implemented in the runtime tests at line 1542.

## Summary

- The Codex plugin acts as a **wrapper** around Claude Code's native Bash sub-agent, adding Codex-specific job tracking without reimplementing process management.
- Background execution requires the `--background` flag parsed in `codex-companion.mjs` (line 788), which triggers job registration in `tracked-jobs.mjs`.
- Actual process forking uses Claude Code's `run_in_background: true` option, ensuring reliable detached execution.
- Status persistence relies on the `appendLogLine` function (line 686) and the `/codex:status` command for user-facing progress updates.
- Cancellation is handled through the job registry with validation in `runtime.test.mjs` (line 1542).

## Frequently Asked Questions

### How does the Codex plugin handle job persistence across Claude Code sessions?

The plugin delegates persistence to Claude Code's Bash sub-agent infrastructure while maintaining supplemental metadata through the `tracked-jobs` module. The in-memory registry and log files written by `appendLogLine` in `codex-companion.mjs` survive the original CLI process, allowing the `/codex:status` command to retrieve job history even after disconnecting and reconnecting to Claude Code.

### What is the difference between the --background and --wait flags in the Codex companion script?

Both flags trigger the background job system in `codex-companion.mjs`, but they handle CLI attachment differently. The `--background` flag returns control immediately after job registration (line 788), while `--wait` typically blocks until the job completes or reaches a specific state. Both utilize the same `tracked-jobs` registration and Bash sub-agent execution path with `run_in_background: true`.

### Where does the Codex plugin store logs for background job status?

Logs are written via the `tracked-jobs` module to files managed by the `appendLogLine` function visible at line 686 of `codex-companion.mjs`. These logs capture state transitions (queued, running, succeeded, cancelled) and are read by the `/codex:status` command to display current progress without querying the active process directly.

### Can multiple Codex background jobs run simultaneously?

Yes. The `tracked-jobs` module maintains an in-memory registry that assigns unique `jobId` values to each request, allowing concurrent execution of multiple `task`, `review`, or `adversarial-review` operations. Each job spawns its own Bash sub-agent worker with `run_in_background: true`, and the cancellation mechanism in `runtime.test.mjs` (line 1542) supports targeting specific jobs without affecting others.