How Session Transfer Works Between Claude Code and Codex

TLDR: The session transfer feature serializes Claude Code's conversation state, files, and runtime context to a JSON transcript that Codex reads on startup, enabling seamless continuity between the two AI assistants.

The openai/codex-plugin-cc repository implements session transfer through a plugin architecture that persists Claude Code session data to a standardized JSON file, which Codex then reconstructs on initialization. This process captures the full conversation history, generated files, and workspace state, allowing developers to migrate work from Claude Code to Codex without manual context switching.

Environment Configuration and Path Resolution

The transfer mechanism relies on environment-based configuration defined in plugins/codex/scripts/lib/claude-session-transfer.mjs.

The constant TRANSCRIPT_PATH_ENV specifies the environment variable that overrides the default transcript location. The resolveClaudeSessionPath() function implements the resolution logic: it first checks the environment variable, then falls back to the default path .claude/session.json within the workspace. This ensures flexibility for CI/CD pipelines while providing sensible defaults for local development.

Persisting the Claude Code Session

When a Claude Code session ends, the plugin serializes the full session state through lifecycle hooks defined in plugins/codex/scripts/session-lifecycle-hook.mjs.

This module registers handlers for the "stop-review-gate" and "session-end" events, as declared in the plugin manifest at plugins/codex/.claude-plugin/plugin.json. When either event fires, the plugin calls saveClaudeSession() to write the transcript file. The serialized payload includes the complete message history, file contents, and runtime metadata required to reconstruct the development context.

Loading Sessions in Codex

On startup, Codex restores the previous session by reading the persisted transcript through plugins/codex/scripts/codex-companion.mjs.

This module imports resolveClaudeSessionPath to locate the JSON file, then executes loadClaudeSession() to parse the data. The function reconstructs the conversation transcript and injects the previously generated files into the Codex workspace, effectively resuming the exact state from the Claude Code session.

Manual Transfer via CLI

Users can trigger session serialization manually using the transfer command defined in plugins/codex/commands/transfer.md.

This CLI command invokes the same helper functions used by the automatic lifecycle hooks, providing explicit control over when to snapshot the current Claude Code state for transfer.

Practical Implementation Examples

The following examples demonstrate how to interact with the session transfer system programmatically.

Triggering a Manual Transfer

Run this command while a Claude Code session is active to copy the current transcript to the default path:

codex transfer

Programmatic Session Persistence

To save a session object from within a plugin:

import { resolveClaudeSessionPath } from "./lib/claude-session-transfer.mjs";
import { readFile, writeFile } from "./fs.mjs";

async function saveSession(session) {
  const path = await resolveClaudeSessionPath();
  await writeFile(path, JSON.stringify(session, null, 2));
}

async function loadSession() {
  const path = await resolveClaudeSessionPath();
  const data = await readFile(path, "utf-8");
  return JSON.parse(data);
}

Automatic Session Restoration

This simplified excerpt from codex-companion.mjs shows how Codex initializes with previous Claude Code context:

import { resolveClaudeSessionPath } from "./lib/claude-session-transfer.mjs";

async function init() {
  const transcriptPath = await resolveClaudeSessionPath();
  const transcript = await readFile(transcriptPath, "utf-8");
  const { messages, files } = JSON.parse(transcript);
  // Re‑hydrate workspace with the previous Claude files
  await workspace.applyFiles(files);
  // Show the previous conversation in the UI
  await ui.showMessages(messages);
}

Summary

  • Session transfer uses a JSON transcript file to bridge Claude Code and Codex, preserving conversation history and workspace state.
  • The TRANSCRIPT_PATH_ENV environment variable and resolveClaudeSessionPath() function in plugins/codex/scripts/lib/claude-session-transfer.mjs determine where session data is stored.
  • Claude Code persists sessions through lifecycle hooks in plugins/codex/scripts/session-lifecycle-hook.mjs that listen for "stop-review-gate" and "session-end" events.
  • Codex restores sessions via plugins/codex/scripts/codex-companion.mjs, which reads the transcript and reconstructs the workspace on startup.
  • The transfer command in plugins/codex/commands/transfer.md provides manual control over session serialization.
  • Because the transcript is plain JSON, developers can inspect, version-control, or manually edit the transferred session data.

Frequently Asked Questions

What file format does the session transfer use?

The session transfer uses a plain JSON document that contains the serialized session object, including messages, files, and runtime state. This format is human-readable and can be version-controlled or inspected manually, providing full transparency over what data is being transferred between Claude Code and Codex.

Can I customize where the session transcript is saved?

Yes. Set the environment variable defined by TRANSCRIPT_PATH_ENV (imported from plugins/codex/scripts/lib/claude-session-transfer.mjs) to override the default location. If this variable is not set, the system falls back to .claude/session.json in the workspace root.

What happens if the transcript file is missing when Codex starts?

If resolveClaudeSessionPath() points to a non-existent file when Codex initializes, the codex-companion.mjs module will not find a session to restore, and Codex will start with a fresh workspace. The transfer is optional and does not block Codex startup if no previous Claude Code session is available.

Is the session transfer bidirectional between Claude Code and Codex?

The current implementation documented in openai/codex-plugin-cc specifically handles transfer from Claude Code to Codex. The architecture uses Claude Code lifecycle hooks to export data and Codex companion scripts to import it, creating a one-way handoff designed to migrate Claude Code workflows into the Codex environment.

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 →