openai / openai/codex

Imported Claude worktree sessions create standalone projects instead of grouping under the original repository

Open
#43,382 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug session
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Local paths and session identifiers in this report are synthetic.

Environment

  • macOS 26.6.2
  • ChatGPT desktop with Codex: 26.901.51231, build 8109
  • Claude session import enabled, including automatic import at app startup
  • Public source inspected at openai/codex commit 694b6319d3ad2399f6e435760a22d9b9357f0697; this is not asserted to be the exact source revision of the installed desktop build

Reproduction

  1. Save /Users/example/code/repo as a Codex project.
  2. Run a Claude session in /Users/example/code/repo/.claude/worktrees/example-task.
  3. Import Claude projects and chats into Codex.
  4. Observe the sidebar: the worktree is represented as another standalone project or the imported session is not assigned to the saved parent project.
  5. Manually repair existing imports, create another Claude worktree session, and restart with automatic import enabled. Newly imported sessions produce the same grouping problem.

Expected: group the imported session under the existing parent repository/workspace, while preserving the worktree as its runtime cwd. An explicit user project assignment or projectless choice should take precedence.

Actual local observation: a later import batch left 8 imported worktree sessions with a null database project ID and created 6 standalone worktree project entries. The local resolver can associate all 8 with desktop originCwd, independently corroborated by Git.

Evidence and distinction between cwd and project ownership

Claude CLI JSONL samples contain the worktree cwd; they do not contain a separate original-repository field. This is a valid execution directory, not by itself a Claude CLI bug. The parent association should be additional project metadata, not a replacement for cwd.

Claude desktop has a separate mapping:

{
  "cliSessionId": "example-cli-session-id",
  "cwd": "/Users/example/code/repo/.claude/worktrees/example-task",
  "originCwd": "/Users/example/code/repo"
}

It lives in ~/Library/Application Support/Claude/claude-code-sessions/<org>/<user>/local_*.json. The filename stem of the CLI JSONL matches cliSessionId. In the observed local snapshot, 91 worktree desktop sessions had originCwd, but only 78 had cliSessionId; this source alone does not cover all sessions or terminal-only sessions.

~/Library/Application Support/Claude/git-worktrees.json provides path/baseRepo as a secondary, garbage-collected mapping. The encoded CLI project folder can be stale after a worktree is renamed/reused; it should not be decoded as the authoritative repository identity.

Public code pointers

  • Claude session detection enumerates JSONL files and has no project-directory fallback.
  • Session summary takes the first cwd and includes it in ExternalAgentSessionMigration.
  • App-server session importer preserves that execution cwd when creating the imported session. The precise desktop project-creation/grouping consumer still needs maintainer confirmation.

Suggested fix and regression coverage

Resolve a separate project-root hint without modifying the working directory:

  1. Respect CLAUDE_CONFIG_DIR first; fall back to the default directory only if unavailable, without blindly merging sources.
  2. Match desktop cliSessionId to originCwd where available.
  3. Otherwise infer the base from <repo>/.claude/worktrees/<name> using the JSONL cwd, including deleted worktrees. Do not require that the worktree still exists.
  4. Use the desktop pool or Git common-directory/worktree metadata as additional evidence. Conflicting evidence should remain unresolved.
  5. Associate with the longest matching saved local project, preserving explicit user overrides. Apply this consistently to interactive and startup imports.
  6. Keep normalization idempotent. Do not delete a project referenced by archived/native sessions, another host, or explicit user state.

Tests should include desktop and CLI-only sessions, renamed encoded folders, deleted worktrees, custom Git worktree locations, a saved umbrella workspace, duplicate roots, configuration fallback, explicit projectless assignments, and repeated import.

The local workaround also found both SQLite project IDs and desktop legacy project mappings in use; changing one alone was insufficient in the observed build. An official fix should coordinate ownership through supported application APIs, not adopt direct offline database writes.

Related report

#40935 describes Desktop/App Server project-assignment divergence for a custom client. This report concerns the built-in Claude import flow and the missing worktree-to-original-project association, including the available originCwd mapping and recurrence on startup imports.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codex-rs/external-agent-migration/src/detect/sessions/cla.rs, codex-rs/external-agent-migration/src/sessions/records_cla.rs, and codex-rs/app-server/src/external_agent_migration/session_importer.rs, then locate the desktop project-grouping consumer. Reproduce both interactive and startup imports using the listed worktree cases and add regression coverage. Done means imported sessions retain their worktree cwd, associate with the correct saved parent when evidence is sufficient, and preserve explicit assignments.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, rust, sqlite
Domain
backend, desktop
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.