How the Session Transfer Mechanism Converts Claude Conversations to Codex Threads

The Codex plugin provides a built-in session transfer mechanism that converts active Claude chats into Codex threads by reading transcript files, mapping message formats, and pushing history via the Codex API.

The openai/codex-plugin-cc repository implements a robust session transfer mechanism that enables seamless migration of conversation history from Claude to Codex. This functionality preserves the full context of AI-assisted sessions, allowing developers to continue work inside the Codex environment without losing prior dialogue. According to the source code, the transfer process is orchestrated through a lifecycle hook that automates transcript parsing, message mapping, and thread persistence.

How the Session Transfer Mechanism Works

The session transfer mechanism operates through a seven-step pipeline defined in claude-session-transfer.mjs. Each stage handles a specific transformation, from file resolution to API synchronization.

Resolving the Claude Transcript

The process begins when the session-lifecycle hook detects a transfer trigger. It reads the environment variable TRANSCRIPT_PATH_ENV to locate the JSON transcript that Claude writes for the current session. The helper function resolveClaudeSessionPath() expands any relative path and verifies the file exists before proceeding.

Parsing and Mapping Messages

Once located, the transcript is parsed as a newline-delimited list of Claude messages. Each entry contains a role (assistant or human) and raw content. The mapper translates Claude's assistant role to Codex's assistant role, and Claude's human role to Codex's user role, preserving optional metadata such as timestamps and tool calls.

Creating and Populating the Codex Thread

Using the codex.mjs library, the code either creates a new thread via codex.createThread() or appends to an existing one if a thread ID was previously stored in the session context. The mapped message array is then sent to Codex via codex.appendMessages(threadId, messages), populating the thread with the full Claude conversation history.

Persistence and Cleanup

After a successful push, the newly created thread ID is stored back into the session's metadata so subsequent commands can reference it. The hook optionally removes the Claude transcript file to avoid stale data and emits a log entry indicating the transfer result.

Triggering the Session Transfer

The session transfer mechanism can be invoked through multiple interfaces depending on whether you are using the CLI or building a custom integration.

CLI Command

For end users, the built-in command provides the simplest entry point:


# While a Claude session is running, issue the built-in command:

codex transfer

Programmatic Integration

Developers can import the transfer functions directly into plugins or automation scripts:

import { resolveClaudeSessionPath } from "./lib/claude-session-transfer.mjs";
import { createThread, appendMessages } from "./lib/codex.mjs";

async function transferSession() {
  const transcriptPath = await resolveClaudeSessionPath();
  const claudeMessages = await readClaudeTranscript(transcriptPath); // parses JSON lines
  const codexMessages = claudeMessages.map(m => ({
    role: m.role === "human" ? "user" : "assistant",
    content: m.content,
  }));

  const threadId = await createThread();               // creates a new Codex thread
  await appendMessages(threadId, codexMessages);      // populates the thread
  console.log(`✅ Claude conversation transferred to Codex thread ${threadId}`);
}

Key Source Files

Understanding the session transfer mechanism requires familiarity with three core modules:

  • claude-session-transfer.mjs: Located at plugins/codex/scripts/lib/claude-session-transfer.mjs, this file contains the core logic that resolves transcripts, parses Claude messages, maps them to Codex format, and drives the API calls.

  • session-lifecycle-hook.mjs: Found at plugins/codex/scripts/session-lifecycle-hook.mjs, this module hooks into Claude's session lifecycle, detects when a transfer should happen, and invokes the transfer routine.

  • codex.mjs: Located at plugins/codex/scripts/lib/codex.mjs, this wrapper around the Codex API provides createThread and appendMessages functions used to create threads and append messages.

Summary

  • The session transfer mechanism converts Claude conversations to Codex threads through a seven-step automated pipeline.
  • Environment variable TRANSCRIPT_PATH_ENV specifies the location of the Claude transcript JSON file.
  • Role mapping translates Claude's human to Codex's user while preserving assistant roles.
  • The session-lifecycle-hook.mjs orchestrates the transfer when triggered by the codex transfer command or session shutdown.
  • Thread IDs are persisted to session metadata, enabling continued access via commands like codex status.

Frequently Asked Questions

What triggers the session transfer mechanism?

The session transfer mechanism is triggered by the session-lifecycle hook defined in session-lifecycle-hook.mjs. It activates when a user runs the codex transfer command or when the Claude session shuts down gracefully, automatically invoking transferClaudeSessionToCodex to begin the conversion process.

How does the session transfer mechanism handle message formatting differences?

The mechanism maps Claude's message format to Codex's expected shape inside claude-session-transfer.mjs. Specifically, it translates the human role to user while keeping the assistant role unchanged, ensuring compatibility with Codex's API requirements while preserving message content and optional metadata.

Where is the transferred thread ID stored after conversion?

After successful transfer, the thread ID is persisted to the session's metadata storage, which may be a temporary file or environment variable depending on the configuration. This allows subsequent commands like codex status to retrieve and display the active thread ID for continued reference.

Can the session transfer mechanism append to existing Codex threads?

Yes, the mechanism checks for existing thread IDs in the session context before creating new threads. If a thread ID is found, codex.appendMessages() adds the converted Claude messages to that existing thread rather than creating a duplicate, maintaining conversation continuity across multiple transfer operations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →