# How codex-plugin-cc Manages State Separately from Codex Internal Configuration

> Discover how codex-plugin-cc keeps its state separate from Codex configuration. Learn how it reads settings via API without modifying them for seamless integration.

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

---

**codex-plugin-cc maintains its own persistent JSON state independent of Codex's internal configuration, reading Codex settings via the App-Server API but never modifying them.**

The `openai/codex-plugin-cc` repository implements a strict architectural boundary between plugin-specific persistence and the Codex CLI's core configuration system. While the plugin tracks its own flags and job history in a local JSON file, it queries Codex's internal settings—such as provider IDs and authentication tokens—through the App-Server RPC API.

## Understanding the State Separation Architecture

The relationship between **codex-plugin-cc state** and **Codex internal configuration** is designed to be strictly one-directional. The plugin maintains complete autonomy over its own persistence layer while treating Codex's configuration as read-only external data.

**Plugin State** lives in a JSON file managed entirely by the plugin's own lifecycle methods. **Codex Internal Configuration** resides within the Codex installation directory (`~/.codex`) and runtime memory, exposed only through authenticated API endpoints. This separation ensures that plugin operations cannot corrupt Codex's core authentication or provider settings, while allowing the plugin to adapt its behavior based on Codex's current operational mode.

## Where codex-plugin-cc Stores Its State

The plugin persists its data in a JSON file located under a directory determined by the `CLAUDE_PLUGIN_DATA` environment variable, falling back to `$TMPDIR/codex-companion` if unset. According to the source code in `plugins/codex/scripts/lib/state.mjs`, this state file contains:

- A `version` field for migration tracking
- A lightweight `config` object (including the `stopReviewGate` boolean)
- A capped array of recent `jobs` for resume functionality

The module exports functions like `loadState()`, `saveState()`, `setConfig()`, and `upsertJob()` to manage this persistence. When you invoke `loadState(cwd)`, the system either reads the existing [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json) or initializes a default structure, ensuring the plugin can resume work across CLI invocations without touching Codex's internal files.

## How Codex Internal Configuration Works

Codex's internal configuration—including provider settings, authentication tokens, model-selection parameters, and broker endpoint details—is stored in the user's Codex configuration directory and accessed exclusively through the App-Server API. As implemented in `plugins/codex/scripts/lib/codex.mjs`, helper functions like `getCodexAuthStatus()`, `getCodexAvailability()`, and `getSessionRuntimeStatus()` query endpoints such as `account/read` and `config/read` to retrieve current operational parameters.

This configuration layer determines how Codex communicates with models, which authentication methods are required, and whether shared broker sessions are being reused. The plugin never writes to these settings; it merely consumes them via the RPC client defined in `plugins/codex/scripts/lib/app-server.mjs`.

## Reading Codex Configuration from the Plugin

The plugin interacts with Codex's internal configuration strictly as a read-only consumer. By calling `getCodexAuthStatus(process.cwd())`, the plugin obtains critical details like `provider`, `requiresOpenaiAuth`, and availability status, then uses this information to conditionally adjust its own behavior.

For example, if the Codex configuration indicates that OpenAI authentication is required, the plugin might automatically disable its review gate by updating its own state via `setConfig(cwd, "stopReviewGate", true)`. This demonstrates the unidirectional flow: **Codex configuration influences plugin state, but plugin state never influences Codex configuration.**

## Practical Implementation Examples

### Managing Plugin State Locally

```javascript
import {
  loadState,
  setConfig,
  upsertJob,
  resolveStateFile
} from "./plugins/codex/scripts/lib/state.mjs";

const cwd = process.cwd();

// Load current state (creates default if missing)
const state = loadState(cwd);
console.log("Current config:", state.config);

// Update plugin-specific flag
setConfig(cwd, "stopReviewGate", true);

// Track a new job
upsertJob(cwd, {
  id: generateJobId(),
  description: "Run lint",
  createdAt: new Date().toISOString()
});

```

*Source:* `plugins/codex/scripts/lib/state.mjs` defines the state management API.

### Querying Codex Internal Configuration

```javascript
import { getCodexAuthStatus } from "./plugins/codex/scripts/lib/codex.mjs";

(async () => {
  const authInfo = await getCodexAuthStatus(process.cwd());
  console.log("Provider:", authInfo.provider);
  console.log("Requires OpenAI auth:", authInfo.requiresOpenaiAuth);
})();

```

*Source:* `plugins/codex/scripts/lib/codex.mjs` implements the App-Server client wrappers.

### Combining Both Systems

```javascript
import { getCodexAuthStatus } from "./plugins/codex/scripts/lib/codex.mjs";
import { setConfig } from "./plugins/codex/scripts/lib/state.mjs";

(async () => {
  const auth = await getCodexAuthStatus(process.cwd());
  
  // Adapt plugin behavior based on Codex configuration
  if (auth.requiresOpenaiAuth) {
    await setConfig(process.cwd(), "stopReviewGate", true);
  }
})();

```

This pattern shows the plugin reading Codex's internal configuration (`requiresOpenaiAuth`) and writing only to its own isolated state (`stopReviewGate`), maintaining the strict separation between the two systems.

## Summary

- **codex-plugin-cc** maintains independent persistent state in a JSON file managed by `plugins/codex/scripts/lib/state.mjs`, storing plugin-specific flags and job history.
- **Codex internal configuration** resides in `~/.codex` and runtime memory, accessed via the App-Server API (`account/read`, `config/read`) through `plugins/codex/scripts/lib/codex.mjs`.
- The plugin reads Codex configuration to make operational decisions but **never writes** to Codex's internal settings.
- Codex cannot access the plugin's [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json), ensuring complete isolation between the plugin's persistence layer and Codex's core configuration.
- Environment variable `CLAUDE_PLUGIN_DATA` controls the plugin's state directory, while Codex uses its own fixed configuration paths.

## Frequently Asked Questions

### Does codex-plugin-cc modify Codex's internal configuration?

No. The plugin only **reads** Codex's internal configuration through the App-Server API using functions like `getCodexAuthStatus()`. It never writes to Codex's configuration files or modifies provider settings, authentication tokens, or model parameters. All mutations are restricted to the plugin's own [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json) file.

### Where is codex-plugin-cc state stored?

The plugin stores its state in a JSON file within a directory specified by the `CLAUDE_PLUGIN_DATA` environment variable, or falls back to `$TMPDIR/codex-companion` if the variable is unset. The specific file path is resolved by `resolveStateFile()` in `plugins/codex/scripts/lib/state.mjs`, typically resulting in [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json) inside that directory.

### How does the plugin access Codex authentication status?

The plugin queries Codex's authentication status by calling `getCodexAuthStatus(cwd)` from `plugins/codex/scripts/lib/codex.mjs`, which internally communicates with the Codex App-Server via RPC calls to endpoints like `account/read`. This returns details including the current provider, whether OpenAI authentication is required, and session availability without exposing sensitive tokens directly to the plugin code.

### Can Codex read the plugin's state.json file?

No. Codex's internal systems have no awareness of the plugin's state file location or format. The [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json) file is managed exclusively by the plugin's own modules (`loadState`, `saveState`), and Codex never references this data. This ensures that plugin-specific implementation details cannot interfere with Codex's core functionality.