How to Transfer Sessions from Claude Code to Codex: Complete Technical Guide
The openai/codex-plugin-cc repository provides a dedicated transfer command that converts Claude Code JSONL transcripts into resumable Codex threads by validating the source path, importing conversation history via importExternalAgentSession, and configuring environment variables for seamless session continuation.
Transferring sessions from Claude Code to Codex preserves your conversation context when migrating between AI coding assistants. The openai/codex-plugin-cc implementation handles this through a local-only pipeline that reads Claude's transcript files from ~/.claude/projects and reconstructs the turn history as a native Codex thread. This workflow requires no external API keys and keeps all processing within your local environment until the final Codex API call.
Understanding the Session Transfer Architecture
The transfer functionality relies on a modular architecture with distinct responsibilities across four core components.
CLI Entry Point and Command Parsing
The codex-companion.mjs script serves as the primary interface, exposing the transfer sub-command through the handleTransfer function. Located at plugins/codex/scripts/codex-companion.mjs (lines 24-31), this entry point parses arguments including the optional --source flag and delegates to the resolution and import layers.
Claude Transcript Resolution
The resolveClaudeSessionPath function in plugins/codex/scripts/lib/claude-session-transfer.mjs (lines 20-44) validates that the supplied path points to a valid JSONL file within the ~/.claude/projects directory hierarchy. This function accepts either a direct path argument or falls back to the CODEX_COMPANION_TRANSCRIPT_PATH environment variable, ensuring strict validation before processing.
Thread Creation and Import
The core conversion logic resides in importExternalAgentSession within plugins/codex/scripts/lib/codex.mjs. This function reads the validated JSONL transcript and creates a new Codex thread that mirrors the Claude conversation turns, preserving the full context history for subsequent interactions.
Environment Propagation
The session-lifecycle-hook.mjs script (lines 77-81) manages post-transfer state by exporting CODEX_COMPANION_SESSION_ID and CODEX_COMPANION_TRANSCRIPT_PATH to the environment. This ensures that subsequent Codex commands automatically reference the correct session context without manual configuration.
Step-by-Step Transfer Workflow
The complete process follows these execution stages:
- Command Invocation – User runs
/codex:transferfrom Claude Code or executes the companion script directly. - Path Resolution – The system validates the JSONL file location within
~/.claude/projectsusingresolveClaudeSessionPath. - Session Import –
importExternalAgentSessionreads the transcript and creates the corresponding Codex thread. - Result Rendering – The
renderTransferResultfunction outputs the new thread ID and resume command. - Environment Setup – The lifecycle hook propagates session identifiers to downstream processes.
Code Examples
Using the Built-in Transfer Command
Run the transfer directly from Claude Code to convert the active session:
/codex:transfer
For programmatic consumption of the result, add the JSON flag:
/codex:transfer --json
Expected output:
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
Running the CLI Script Directly
Invoke the underlying Node script for specific transcript files:
node plugins/codex/scripts/codex-companion.mjs transfer \
--source ~/.claude/projects/my-project/session-001.jsonl \
--json
Sample JSON payload:
{
"threadId": "12345-abcd-ef01",
"resumeCommand": "codex resume 12345-abcd-ef01",
"sourcePath": "/home/you/.claude/projects/my-project/session-001.jsonl",
"sessionId": "session-001"
}
Programmatic Integration
Import the transfer functions directly into your Node.js applications:
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}`);
}
Verifying Environment Variables
After a successful transfer, confirm the session state:
echo $CODEX_COMPANION_SESSION_ID
# Output: session-001
echo $CODEX_COMPANION_TRANSCRIPT_PATH
# Output: /home/you/.claude/projects/my-project/session-001.jsonl
Summary
- The session transfer process converts Claude Code JSONL transcripts into Codex threads using the
handleTransferfunction incodex-companion.mjs. - Path validation ensures source files reside within
~/.claude/projectsviaresolveClaudeSessionPath. - Thread creation occurs through
importExternalAgentSessioninlib/codex.mjs, preserving conversation history. - Environment variables (
CODEX_COMPANION_SESSION_IDandCODEX_COMPANION_TRANSCRIPT_PATH) maintain session context across commands. - The workflow operates locally without exposing API keys or secrets until the final Codex service interaction.
Frequently Asked Questions
Where does Claude Code store session transcripts?
Claude Code stores session transcripts as JSONL files within the ~/.claude/projects directory hierarchy. The resolveClaudeSessionPath function strictly validates that source paths point to this location, ensuring only legitimate Claude session files are processed for transfer.
Is the session transfer process secure?
Yes, the transfer operates entirely within your local environment. According to the openai/codex-plugin-cc source code, no external API keys or secrets are exposed during the conversion process. The only network interaction occurs when the newly created Codex thread subsequently communicates with the Codex service.
Can I resume a transferred session after creation?
Yes. The transfer command returns a resumeCommand field containing the specific codex resume <thread-id> command needed to continue the conversation. The session-lifecycle-hook.mjs file also sets CODEX_COMPANION_SESSION_ID to ensure automatic session recognition by subsequent Codex commands.
What file format is required for the transfer?
The system requires JSONL (JSON Lines) format, which is the native export format used by Claude Code. The resolveClaudeSessionPath function validates both the file extension and the internal structure before processing, ensuring compatibility with the importExternalAgentSession parser.
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 →