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 atplugins/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 atplugins/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 atplugins/codex/scripts/lib/codex.mjs, this wrapper around the Codex API providescreateThreadandappendMessagesfunctions 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_ENVspecifies the location of the Claude transcript JSON file. - Role mapping translates Claude's
humanto Codex'suserwhile preservingassistantroles. - The
session-lifecycle-hook.mjsorchestrates the transfer when triggered by thecodex transfercommand 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →