# How to Transfer a Claude Code Session to Codex and Resume It There

> Effortlessly transfer your Claude Code session to Codex and resume your work. Use the simple command to convert transcripts and continue coding seamlessly.

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

---

**Run `/codex:transfer` inside Claude Code to convert the active JSONL transcript into a resumable Codex thread, then use the printed `codex resume <threadId>` command to pick up where you left off.**

The `openai/codex-plugin-cc` repository ships a built-in session-transfer mechanism that migrates Claude Code conversation history into Codex format without exposing API secrets. This workflow reads your local Claude transcript files and creates a matching Codex thread that preserves the entire turn-by-turn context.

## How the Session Transfer Architecture Works

The transfer process is completely internal to the plugin—no network requests transmit your Claude data to external services during the conversion.

### CLI Entry Point and Command Parsing

The `codex-companion.mjs` script exposes the `transfer` subcommand through its `handleTransfer` function. When you invoke `/codex:transfer` or run the companion CLI directly, the script parses arguments at lines 24‑31 in `plugins/codex/scripts/codex-companion.mjs` and routes them to the execution pipeline.

### Validating the Claude Transcript Path

Before importing history, `resolveClaudeSessionPath` validates that the supplied `--source` path (or the `CODEX_COMPANION_TRANSCRIPT_PATH` environment variable) points to a valid JSONL file inside `~/.claude/projects`. This check occurs at lines 20‑44 in `plugins/codex/scripts/lib/claude-session-transfer.mjs`, ensuring the plugin only ingests legitimate Claude session files.

### Converting History to a Codex Thread

The core import logic resides in `importExternalAgentSession` within `plugins/codex/scripts/lib/codex.mjs`. This function reads the validated JSONL transcript and generates a new Codex thread that mirrors each conversational turn from Claude Code. The companion script calls this logic at lines 25‑30 of `codex-companion.mjs`, capturing the resulting thread metadata for display.

### Environment Propagation for Resumed Sessions

After successful transfer, `session-lifecycle-hook.mjs` propagates session identifiers to downstream processes. Lines 77‑81 set `CODEX_COMPANION_SESSION_ID` and `CODEX_COMPANION_TRANSCRIPT_PATH` as environment variables, ensuring subsequent Codex commands in the same shell session automatically reference the transferred Claude context.

## Step-by-Step: Transferring Your Claude Code Session

### Using the Built-In Command

From any directory within your Claude Code workspace, execute the transfer command:

```bash
/codex:transfer

```

This locates the active session transcript in `~/.claude/projects` and outputs a human-readable result via `renderTransferResult` (lines 16‑23 in `codex-companion.mjs`):

```

Transferred the Claude session into a Codex thread with visible turn history.
Codex session ID: 12345-abcd-ef01
Resume in Codex: codex resume 12345-abcd-ef01

```

For programmatic consumption, request JSON output:

```bash
/codex:transfer --json

```

### Running the CLI Directly

You can invoke the underlying Node script explicitly with a specific source path:

```bash
node plugins/codex/scripts/codex-companion.mjs transfer \
  --source ~/.claude/projects/my-project/session-001.jsonl \
  --json

```

The command returns a JSON payload:

```json
{
  "threadId": "12345-abcd-ef01",
  "resumeCommand": "codex resume 12345-abcd-ef01",
  "sourcePath": "/home/you/.claude/projects/my-project/session-001.jsonl",
  "sessionId": "session-001"
}

```

## Programmatic Session Transfer

Embed the transfer logic in your own Node.js tooling by importing the core functions:

```javascript
import { executeTransfer } from "./plugins/codex/scripts/lib/codex.mjs";
import { resolveClaudeSessionPath } from "./plugins/codex/scripts/lib/claude-session-transfer.mjs";

async function transferClaudeToCodex(cwd, source) {
  const sourcePath = resolveClaudeSessionPath(cwd, { source });
  const { threadId, resumeCommand } = await importExternalAgentSession(cwd, { sourcePath });
  console.log(`Codex thread ${threadId} created – resume with: ${resumeCommand}`);
}

```

This approach gives you fine-grained control over the working directory (`cwd`) and source selection while maintaining the same validation and thread-creation logic used by the CLI.

## Verifying the Transfer State

After running the transfer, confirm the session context is active by checking your environment:

```bash
echo $CODEX_COMPANION_SESSION_ID
echo $CODEX_COMPANION_TRANSCRIPT_PATH

```

The first variable contains the Claude session identifier, while the second points to the exact JSONL file consumed during transfer. These values persist for the lifetime of your shell session, allowing seamless handoff between Claude Code and Codex.

## Summary

- **Command**: Use `/codex:transfer` inside Claude Code or run `codex-companion.mjs transfer` from the shell to initiate migration.
- **Validation**: The plugin enforces that source transcripts reside within `~/.claude/projects` via `resolveClaudeSessionPath`.
- **Core Logic**: `importExternalAgentSession` in `lib/codex.mjs` handles the JSONL-to-Codex-thread conversion.
- **Resume**: The output provides a `codex resume <threadId>` command that restores your conversation history.
- **State**: Environment variables `CODEX_COMPANION_SESSION_ID` and `CODEX_COMPANION_TRANSCRIPT_PATH` maintain session continuity across tools.

## Frequently Asked Questions

### Where does the Claude Code transcript come from?

Claude Code writes conversation history to JSONL files inside `~/.claude/projects/<project-name>/`. The transfer command automatically resolves the active session path, or you can specify a file explicitly using the `--source` flag when running the companion CLI directly.

### Is the transfer process secure?

Yes. According to the `openai/codex-plugin-cc` source code, all processing happens locally on your machine. The `handleTransfer` function in `codex-companion.mjs` performs filesystem operations only, and no Claude session data is transmitted over the network until you actively invoke the Codex service using the generated resume command.

### Can I transfer multiple sessions at once?

The current implementation processes one transcript per invocation. Each call to `executeTransfer` creates a single Codex thread from one JSONL source. To migrate multiple sessions, run the transfer command sequentially or script the `importExternalAgentSession` function in a loop with different source paths.

### What happens if the transcript path is invalid?

`resolveClaudeSessionPath` throws a validation error if the supplied path is not a JSONL file or resides outside the `~/.claude/projects` directory. The CLI catches this error and exits with a non-zero status, preventing the creation of empty or corrupted Codex threads.