"Import Claude Code Conversations" never shows any sessions on Windows (drive-letter colon not stripped)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

On Windows, Import Claude Code Conversations silently imports nothing. The setting is on, the feature gate is on, and Claude Code transcripts exist on disk — but no imported agents ever appear in the Agents window.

Root cause: the directory-name encoder used to locate ~/.claude/projects/<encoded-cwd> only replaces forward slashes with dashes. It does not strip the Windows drive-letter colon (or handle backslashes), so the computed directory name is not a legal Windows filename and can never exist.

Steps to Reproduce

  1. On Windows, use Claude Code in a local workspace, e.g. C:\Code\MyProject, so that transcripts are written to %USERPROFILE%\.claude\projects\C--Code-MyProject\*.jsonl.
  2. Open that workspace in Cursor’s Agents window.
  3. Enable Cursor Settings → Agents → Third-Party Imports → Import Claude Code Conversations.
  4. Restart Cursor and look at the agent list.

Expected Behavior

Claude Code sessions appear in the Agents list with the Imported from Claude Code source badge.

Actual: No imported sessions appear, in any grouping or filter mode. No error is surfaced.

Operating System

Windows 10/11

Version Information

Cursor: 3.21.16
Commit: 8ae78e8eee1e63479c7e0504b664bc0a80c68000
VS Code base: 1.128.0
OS: Windows 11 Pro, build 26200

For AI issues: which model did you use?

N/A — not an AI-request issue; this is Agents-window import of Claude Code transcripts.

For AI issues: add Request ID with privacy disabled

N/A — no AI request involved.

Additional Information

Root cause

From workbench.glass.main.js (minified; module marker claude-code/paths.ts):

// Kwu = ".claude", Ywu = "projects"
function ANk(t){ return t.replaceAll("/","-") || "-" }
function Ffs(t){ return `${t.homeDir.replace(/\/$/,"")}/${Kwu}/${Ywu}/${ANk(t.cwd)}` }

Ffs is called from both the transcript mtime poller and the session counter:

const e = this.pathService.userHome({preferLocal:true}).fsPath;
for (const r of t) {
  const s = Ffs({ homeDir: e, cwd: r.cwd });
  if (!await this.pathExists(s)) continue;   // always taken on Windows
}

cwd originates from uri.fsPath of the workspace identifier, which on Windows is c:\Code\MyProject.

The mismatch:

Directory name
What Claude Code actually writes C--Code-MyProject
What ANk() computes c:\Code\MyProject (no / present, so unchanged)
If the path were POSIX-normalised first c:-Code-MyProject

Claude Code’s own encoder replaces the drive colon and the separators with -. Cursor’s replaces only /.

Both candidate results still contain :, which is not a legal NTFS filename character. Attempting to create c:-Code-MyProject under .claude\projects fails outright (The second path fragment must not be a drive or UNC name.).

The lookup can never succeed on Windows regardless of slash normalisation. On macOS/Linux the encoding happens to match (/Users/me/proj → -Users-me-proj), which is presumably why this went unnoticed.

Ruled out

These were verified as correct on the affected machine:

  • Feature gate import_cc_conversation = true (full rollout, rule ...:100.00:1)
  • cursor/importClaudeCodeAgents = 'true' in state.vscdb ItemTable (read via SQL)
  • Sidebar filter glassSidebarSettings.filter.show includes source:third_party
  • Scan window is 30 days / 50 sessions max; the sessions in question are hours old
  • ~/.claude.json and ~/.claude/projects both exist, so the “is Claude Code installed” probe succeeds (it builds its path differently)

Suggested fix

Match Claude Code’s encoder — normalise separators and strip the drive colon:

function encodeProjectDir(cwd){
  return cwd.replace(/[\\/:]/g, "-") || "-";
}

This yields C--Code-MyProject for C:\Code\MyProject and leaves POSIX paths behaving as they do today.

Workaround

None available to users. The expected directory name contains a colon, so it cannot be created, symlinked, or junctioned on Windows.

Affected data on this machine: 68 Claude Code sessions total, 49 for the workspace under test.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Update — solved. There are actually two separate Windows bugs here, not one.

Fixing the path encoder is necessary but not sufficient. With only that fix, Cursor does locate and read the transcripts, but every single session is then dropped by a second, completely silent filter. With both fixed, the import works: my Claude Code sessions now show up in the Agents list with the Imported from Claude Code badge.

Bug 1 — path encoder (the one in the original post)

claude-code/paths.ts, minified:

function ANk(t){return t.replaceAll("/","-")||"-"}

Patched to:

function ANk(t){return t.replace(/[\\/:]/g,"-")||"-"}

C:\Code\MyProject now encodes to C--Code-MyProject, which is what Claude Code itself writes. POSIX behaviour is unchanged.

Bug 2 — case-sensitive cwd comparison silently drops every Windows session

This is the one that kept the list empty even after bug 1 was fixed. In the transcript head parser:

if(e.cwd!==t.workspaceCwd)return{kind:"skip"};
  • e.cwd is read verbatim out of the Claude Code transcript, where it was written by the OS: C:\Code\MyProject — uppercase drive letter, backslashes.
  • t.workspaceCwd comes from URI.fsPath, which on Windows lowercases the drive letter by design: c:\Code\MyProject.

So the strict !== can never match on Windows. Worse, this branch returns a bare {kind:"skip"} with no reason attached, so unlike the other skip paths (missing_cwd, cwd_beyond_head_limit, no_visible_content, …) it never reaches the skip-warning logger. Nothing is written to the logs at all, which is why it is indistinguishable from bug 1 from the outside.

You can see both spellings coexisting inside Cursor’s own state.vscdb: the stored workspace entry holds "fsPath":"c:\\Code\\…" right next to "path":"/C:/Code/…".

Patched to:

if(String(e.cwd).toLowerCase().replace(/\\/g,"/")!==String(t.workspaceCwd).toLowerCase().replace(/\\/g,"/"))return{kind:"skip"};

Suggested fix for the Cursor team

  1. Encoder: replace /, \ and : with - so it matches Claude Code’s own encoding scheme.
  2. Comparison: normalise separators and compare case-insensitively on Windows (e.g. via the existing extpath.isEqual / isWindows helpers) instead of raw !==. This one alone would still block every Windows user even if the encoder were fixed.
  3. Observability: route this skip through the same warning path as the other skip reasons. A one-line log here would have made both bugs obvious immediately.

If you want it working today

This patches the shipped bundle, so it is unsupported and every Cursor update will wipe it. Back the file up first.

  1. Fully close Cursor.
  2. Back up %LOCALAPPDATA%\Programs\cursor\resources\app\out\vs\workbench\workbench.glass.main.js (~43 MB).
  3. Apply the two replacements above as exact string search-and-replace — each source pattern occurs exactly once in the file.
  4. Confirm Settings → Agents → Third-Party Imports → Import Claude Code Conversations is enabled, then fully restart Cursor (not just reload window).

Verified on Cursor 3.21.16 / commit 8ae78e8eee1e63479c7e0504b664bc0a80c68000, Windows 11 Pro build 26200. Sessions appear grouped normally and open read-only as expected; no other behaviour changed, and no new errors appeared in the logs after patching.

Hey @MENGYANG_ZHHANG

Thanks a lot for the report, and also your detailed follow-up. This is a known issue we’re already tracking, and I’ve added your report to it!

Where does the bug appear (feature/product)?

Somewhere else…

Describe the Bug

Summary

On Windows, Import Claude Code Conversations (Agents Window → Settings → Third-Party Imports) never shows imported chats for local projects under C:\…, even when Claude Code .jsonl transcripts exist on disk.

Environment

  • OS: Windows 11
  • Cursor: [paste Help → About version]
  • Setting enabled: Import Claude Code Conversations (importClaudeCodeAgents = true)
  • Claude sessions present under: %USERPROFILE%\.claude\projects\C--AI-Projects-<repo>\*.jsonl

Actual

Sidebar shows No agents yet. No imported conversations appear.
glass.claudeCodeSessionRegistry.v1 stays empty / unused.

Root cause (from client bundle inspection)

Importer builds project dir as:
{userHome}/.claude/projects/{cwd.replaceAll("/", "-")}
using uri.fsPath as cwd.

On Windows fsPath is like C:\AI-Projects\my-repo, so Cursor looks for:
…\.claude\projects\C:\AI-Projects\my-repo
which stat/mkdir cannot use (colon / invalid path) → ENOENT → session scan skipped.

Claude Code encodes with non-alphanumeric → -, producing C--AI-Projects-my-repo (files exist there).

On macOS/Linux (/Users/... → -Users-...) encoding matches; Windows drive letters do not.

Suggested fix

Encode like Claude Code: replace /[^a-zA-Z0-9]/g with - (keep C--…), not only / → -.

Notes

  • Copy/rename workaround is impossible: Cursor’s expected folder name is illegal on Windows (C: in a path segment).
  • Ban/account status is unrelated; local JSONL files remain on disk.

Steps to Reproduce

Steps to reproduce

  1. Use Claude Code on a Windows path like C:\AI-Projects\my-repo so transcripts are stored as %USERPROFILE%\.claude\projects\C--AI-Projects-my-repo\*.jsonl.
  2. Open that same folder in Cursor.
  3. Open Agents Window → Settings → Third-Party Imports → enable Import Claude Code Conversations.
  4. Check the Agents sidebar for that repository.

Expected Behavior

Expected

Imported chats appear (e.g. tagged as imported from Claude Code), based on local JSONL transcripts.

Operating System

Windows 10/11

Version Information

3.22.7 (user setup)

Does this stop you from using Cursor

No - Cursor works, but with this issue