# Internal Architecture of the codex-companion.mjs Entry Point

> Explore the internal architecture of codex-companion.mjs, the CLI entry point for Codex Companion. Understand its command parsing, job record creation, and handler delegation for efficient tool execution.

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

---

**The `codex-companion.mjs` script serves as the command-line front door for the Codex Companion tool, parsing sub-commands, creating persistent job records, and delegating execution to specialized handlers while maintaining a strict separation between CLI orchestration and domain logic.**

The `codex-companion.mjs` file in the `openai/codex-plugin-cc` repository functions as the primary entry point for the Codex CLI Companion. When invoked via `node scripts/codex-companion.mjs`, it coordinates argument parsing, workspace resolution, and job dispatching before handing off compute-intensive operations to modular helper libraries located under `plugins/codex/scripts/lib/`.

## Command Dispatch and Orchestration

The `main()` function (lines 24-68) acts as the central **sub-command dispatcher**. It first normalizes raw process arguments through `parseCommandInput` (lines 41-49), which supports "raw-string" mode and builds a rich options object. The function then resolves workspace contexts via `resolveCommandCwd` and `resolveCommandWorkspace` (lines 51-57) to locate the repository root. Based on the first positional argument, `main()` delegates to dedicated handlers including `handleReview`, `handleTask`, `handleSetup`, `handleStatus`, `handleResult`, and `handleCancel` (lines 83-122).

## Job Lifecycle and State Management

Every action creates a **persistent job record** through `createCompanionJob` (lines 67-78). This function generates a unique job ID, captures metadata (kind, title, summary), and writes the state to disk at `<workspaceRoot>/.codex/jobs/<jobId>.json`. This architecture enables background execution, status polling, and cancellation across separate process lifetimes. Progress tracking attaches via `createTrackedProgress` (lines 80-89), which initializes a log file and streams updates to both the console and the persistent job file via `writeJobFile` and `upsertJob` functions from `lib/state.mjs`.

## Execution Paths

### Foreground Execution

For synchronous operations, `runForegroundCommand` (lines 58-69) wraps the job runner, captures output, and sets the process exit code on failure. This path supports both human-readable formatting via `lib/render.mjs` and machine-readable JSON output through `outputResult`.

### Background Execution

Long-running tasks utilize `enqueueBackgroundTask` (lines 84-99), which spawns a detached child process via `spawnDetachedTaskWorker`. This allows the parent CLI process to exit immediately while the `task-worker` continues execution, writing progress to the job file that can be monitored later via `handleStatus`.

## Domain-Specific Workflows

### Review Workflows

The `executeReviewRun` function (around line 58) implements the review logic, branching between **native review** and **adversarial review** modes. It builds appropriate prompts using `buildAdversarialReviewPrompt`, delegates the heavy lifting to `runAppServerReview` or `runAppServerTurn` from `lib/codex.mjs`, and formats results via `renderNativeReviewResult` or equivalent renderers.

### Task Execution

`executeTaskRun` (lines 61-90) manages task-run metadata creation and optionally resumes previous conversation threads through `resolveLatestTrackedTaskThread` from `lib/job-control.mjs`. It invokes the App-Server turn via `runAppServerTurn` and renders final output using utilities from `lib/render.mjs`.

### Session Transfer

The `executeTransfer` function (lines 25-36) handles importing external Claude session JSONL files into Codex-compatible threads, returning resumable command structures that integrate with the existing job tracking system.

## Utility Functions and Normalization

The entry point includes several **normalization utilities** defined near the top of the file (lines 103-129):

- `normalizeRequestedModel`: Validates and formats model identifiers
- `normalizeReasoningEffort`: Converts reasoning effort strings to standardized values
- `shorten`: Truncates text for display purposes
- `firstMeaningfulLine`: Extracts preview text from command output
- `sleep`: Promise-based delay utility for polling loops

## Supporting Library Architecture

The architecture cleanly separates **CLI orchestration** from **domain logic** through modular libraries:

- **`lib/args.mjs`**: Contains `parseArgs` and `splitRawArgumentString` for sophisticated argument parsing
- **`lib/codex.mjs`**: Wraps the Codex App-Server with functions like `runAppServerTurn`, `runAppServerReview`, and turn interruption utilities
- **`lib/state.mjs`**: Implements persistent job state management (list, read, write operations)
- **`lib/job-control.mjs`**: Provides helpers for locating resumable jobs and sorting job histories
- **`lib/tracked-jobs.mjs`**: Handles progress logging, job record creation, and tracked job execution
- **`lib/render.mjs`**: Formats human-readable output for results, status reports, and cancellation confirmations
- **`lib/process.mjs`**: Contains process utilities including `binaryAvailable` and `terminateProcessTree` for cleanup
- **`lib/workspace.mjs``: Detects repository workspace roots for context-aware execution

## Practical Usage Examples

### Running a Native Review

```bash
node scripts/codex-companion.mjs review --base main --scope working-tree

```

This flows through `handleReview` → `executeReviewRun` → `runAppServerReview` → `renderNativeReviewResult`.

### Starting a Background Task

```bash
node scripts/codex-companion.mjs task --background --model spark "Generate a README for this repo"

```

The `--background` flag triggers `enqueueBackgroundTask`, which spawns a detached `task-worker` process that persists after the CLI exits.

### Resuming the Latest Task Thread

```bash
node scripts/codex-companion.mjs task --resume-last

```

`resolveLatestTrackedTaskThread` locates the most recent resumable job, then `executeTaskRun` continues the conversation thread.

### Checking Job Status with Polling

```bash
node scripts/codex-companion.mjs status 12345 --wait

```

`handleStatus` uses `waitForSingleJobSnapshot` to poll the job file until completion, rendering updates via `lib/render.mjs`.

### Canceling a Running Job

```bash
node scripts/codex-companion.mjs cancel 12345

```

`handleCancel` attempts to interrupt the App-Server turn, then invokes `terminateProcessTree` from `lib/process.mjs` to clean up spawned workers.

## Summary

- **`codex-companion.mjs`** acts purely as a coordinator, delegating all domain work to specialized libraries under `plugins/codex/scripts/lib/`.
- The **job record architecture** enables durable execution across process lifetimes, supporting both foreground and background operation modes.
- **Sub-command handlers** (`handleReview`, `handleTask`, etc.) implement specific workflows while sharing common infrastructure for argument parsing, workspace resolution, and progress tracking.
- **App-Server abstraction** in `lib/codex.mjs` isolates the CLI from underlying API details, making it possible to swap implementations without modifying the entry point.
- **Persistent state management** via JSON job files in `.codex/jobs/` enables status polling, cancellation, and thread resumption across separate CLI invocations.

## Frequently Asked Questions

### What is the role of the `main()` function in codex-companion.mjs?

The `main()` function (lines 24-68) serves as the central orchestration point. It parses command-line input via `parseCommandInput`, resolves the working directory and workspace root, and dispatches to the appropriate sub-command handler (`handleReview`, `handleTask`, etc.) based on the first argument provided by the user.

### How does codex-companion.mjs handle long-running tasks without blocking the terminal?

For background operations, the script uses `enqueueBackgroundTask` (lines 84-99) to spawn a detached child process via `spawnDetachedTaskWorker`. This creates a `task-worker` that continues execution after the parent process exits, writing progress updates to a persistent job file that can be monitored later using the `status` sub-command.

### Where does codex-companion.mjs store job state and progress?

Job state is persisted to disk at `<workspaceRoot>/.codex/jobs/<jobId>.json` using functions from `lib/state.mjs`. The `createCompanionJob` function (lines 67-78) initializes these records, while `createTrackedProgress` (lines 80-89) attaches log streams that update both the console and the persistent job file, enabling status polling and resume functionality across separate CLI invocations.