openai / openai/codex-plugin-cc
/codex:transfer is broken when CLAUDE_CONFIG_DIR is set — Claude transcript root hardcoded to ~/.claude/projects
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 33.3k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Description
/codex:transfer cannot transfer a session when Claude Code's config dir is not ~/.claude. Claude Code supports relocating it via the CLAUDE_CONFIG_DIR env var (mine is ~/.claude-work), and transcripts then live under $CLAUDE_CONFIG_DIR/projects/<project>/<session>.jsonl. The plugin hardcodes the default root:
plugins/codex/scripts/lib/claude-session-transfer.mjs:8
const CLAUDE_PROJECTS_DIR = path.join(os.homedir(), ".claude", "projects");
Two separate failures follow.
1. Plugin-side path validation. resolveClaudeSessionPath() rejects any transcript outside ~/.claude/projects. Worse, the realpathSync of the source and of CLAUDE_PROJECTS_DIR share one try/catch, so when the default root doesn't exist the user gets a wrong diagnosis pointing at a file that does exist:
Claude session file not found: ~/.claude-work/projects/-Users-...-my-repo/<uuid>.jsonl
2. Codex-side detection. Even with the path accepted, codex-cli 0.153.0 only detects Claude transcripts under ~/.claude/projects, so importedThreadIdForSource() finds no ledger record and the import fails with:
Codex reported that the Claude import completed, but did not record an imported thread. Check the Codex app-server logs for the underlying import error.
strings on the codex binary shows no CLAUDE_CONFIG_DIR occurrence at all (external-agent-migration/src/source_cla.rs), so the Rust side appears to assume the default root too. That part may need a fix in openai/codex rather than here, but the plugin can work around it.
Steps to Reproduce
- Run Claude Code with
CLAUDE_CONFIG_DIR=~/.claude-work(any non-default value; the default~/.claudemay also exist and be non-empty). - In a session, run
/codex:transfer. - Failure 1 (path validation) fires. Patch
CLAUDE_PROJECTS_DIRto the real root and rerun — failure 2 (ledger) fires. - Copy the same transcript to
~/.claude/projects/<same-project-dir>/and pass it via--source: the transfer succeeds.
Expected behavior
/codex:transfer works when the transcript lives under $CLAUDE_CONFIG_DIR/projects/, and the error message for a genuinely missing file is distinguishable from a root-not-allowed one.
Actual behavior
Transfer is impossible without hand-copying the transcript into ~/.claude/projects/.
Suggested fix
In claude-session-transfer.mjs, resolve the accepted roots from CLAUDE_CONFIG_DIR (falling back to ~/.claude) instead of a single constant, and split the two realpathSync calls so a missing default root can't be reported as a missing source file.
Until the Codex CLI understands the relocated root, the plugin can stage a copy of the transcript into ~/.claude/projects/<project-dir>/ and hand Codex that path. Locally patching those two things makes /codex:transfer succeed:
Transferred the Claude session into a Codex thread with visible turn history.
Codex session ID: 01a0691d-...
Happy to open a PR for the plugin-side change if that shape looks right.
Notes
Not a duplicate of the existing "did not record an imported thread" reports — those are Windows path/hash issues with the transcript already under ~/.claude/projects. Here the root itself is different, and the same failure reproduces on macOS.
Environment
- OS: macOS 15 (Darwin 24.6.0), Apple Silicon
- Node.js: v24
- Shell: zsh
- Plugin version: 1.0.6 (
plugins/cache/openai-codex/codex/1.0.6) - codex-cli: 0.153.0 (Homebrew)
CLAUDE_CONFIG_DIR=~/.claude-work
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with plugins/codex/scripts/lib/claude-session-transfer.mjs, especially CLAUDE_PROJECTS_DIR and resolveClaudeSessionPath(). Reproduce with CLAUDE_CONFIG_DIR set, then verify path validation, missing-file diagnostics, and transfer behavior against the codex-cli detection limitation. Done means relocated transcripts can be transferred without manual copying, or the remaining Codex-side constraint is clearly isolated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- cli, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100