transession translates interactive session history between Codex and Claude Code.
The default workflow is direct native-to-native conversion by session id:
transession --from claude --to codex <SESSION_ID>
transession --from codex --to claude <SESSION_ID>By default, transession:
- resolves the source session id from the local Claude or Codex store
- creates a fresh target session id automatically
- writes the translated session into the target tool's storage
- immediately opens the translated session in the target agent
If you only want the translation and do not want to start the target agent yet:
transession --from claude --to codex <SESSION_ID> --no-open
transession --from codex --to claude <SESSION_ID> --no-opencargo install transessionOr install directly from GitHub:
cargo install --git https://github.com/inmzhang/transession.gitOr from a local checkout:
cargo install --path .For development:
git clone https://github.com/inmzhang/transession.git
cd transession
cargo build --releaseConvert a Claude session into Codex and open the translated Codex session immediately:
transession --from claude --to codex <CLAUDE_SESSION_ID>Convert a Codex session into Claude and open the translated Claude session immediately:
transession --from codex --to claude <CODEX_SESSION_ID>If you want the translated session to be written somewhere else first, override the target root explicitly:
transession --from claude --to codex <SESSION_ID> --output ./tmp/codex-home
transession --from codex --to claude <SESSION_ID> --output ./tmp/claude-homeWhen opening after translation, transession launches the target CLI with the translated session id. For custom output roots, it also sets CODEX_HOME or CLAUDE_HOME for the launched process.
For Codex and Claude inputs, transession accepts either:
- a native session id
- a direct session file path
By default it searches:
- Codex:
TRANSESSION_CODEX_HOME, thenCODEX_HOME, then~/.codex - Claude:
TRANSESSION_CLAUDE_HOME, thenCLAUDE_HOME, then~/.claude
That means you can usually use the same id you would pass to codex resume or claude -r.
transession preserves the main conversation state needed for practical handoff:
- user and assistant messages
- reasoning summaries
- tool calls and tool results
- timestamps
- working directory and branch hints
- lightweight platform metadata needed for native session discovery
transession intentionally focuses on the durable conversation logs and lightweight resume metadata. It does not recreate every platform-specific side channel.
The current test suite covers the main happy paths, but real-world session logs are messy and platform behavior keeps evolving. You should expect some edge cases and translation failures to surface over time, and the converter will likely need further iteration as those cases are discovered.
Known omissions:
- opaque reasoning payloads and token-accounting side data
- Codex SQLite state and shell snapshot sidecars
- Claude subagent trees and tool-result sidecar directories
- platform-specific runtime caches outside the main session log
Local development checks:
cargo fmt --all --check
cargo clippy --all-targets --all-features -- -D warnings
cargo testPre-commit hooks are configured in .pre-commit-config.yaml.
To enable them locally:
pipx install pre-commit
pre-commit installThe configured hooks run:
cargo fmt --all --checkcargo clippy --all-targets --all-features -- -D warningscargo test
GitHub Actions workflows are included:
.github/workflows/ci.ymlfor formatting, linting, and tests.github/workflows/publish.ymlfor dry-run or real crates.io publishing
The repository is prepared for cargo install transession once the crate is published.
What you need to do before the real publish:
- Create a crates.io API token with publish permission.
- Add that token to the GitHub repository secrets as
CARGO_REGISTRY_TOKEN. - Make sure the version in
Cargo.tomlis the version you want to release. - Push the release commit to
master.
How to run the publish workflow:
- For a dry run in GitHub Actions: open the
publishworkflow and runworkflow_dispatchwithdry_run=true. - For a real publish in GitHub Actions: run
workflow_dispatchwithdry_run=false, or push a tag likev0.1.0.
The publish workflow will:
- verify formatting
- run clippy with
-D warnings - run tests
- verify that a pushed
vX.Y.Ztag matches theCargo.tomlversion - run
cargo publish --locked
The crate name transession appeared available during the latest local check, and cargo publish --dry-run succeeded locally. You should still treat name availability as time-sensitive until the first real publish completes.
There is also a portable intermediate representation for debugging and advanced workflows, but it is intentionally not the main interface.
Advanced commands remain available:
transession inspect <SESSION_ID> --from claude
transession import <SESSION_ID> ./session.json --from codex
transession export ./session.json ./out/codex-home --to codex --new-session-id
transession convert <SESSION_ID> ./out/claude-home --from codex --to claude --new-session-idThis project was built with Codex. The code and documentation were generated and refined collaboratively with AI assistance, then validated locally with tests and CLI smoke checks.