Preserve working directories when importing external sessions (#36964)

## Why

Cursor stores projectless chats under the reserved `empty-window` project, and
their transcripts may not contain embedded working-directory metadata.

## What changed

- Resolve `empty-window` sessions to the parent of the Cursor home directory,
  including when that home is configured as a relative path.
- Record each created or appended session's working directory in its import
  success result instead of inheriting the migration item's directory.

## Testing

- Cover projectless Cursor transcripts without embedded metadata.
- Cover working-directory resolution from a relative Cursor home.

GitOrigin-RevId: 21cc7ea6acab1ed80cc4016a881e07eca3d0abbd
This commit is contained in:
charlesgong-openai authored and copyberry committed 2026-08-04 19:57:33 +00:00
1 parent 40d226e398
commit e9a692d53b
5 files changed
+70 -6

No files matched your search

@@ -38,7 +38,7 @@ pub(crate) fn detect_recent_cur_sessions_with_limits(
if !project_storage.is_dir() {
continue;
}
let fallback_cwd = cur_project_cwd(&project_storage);
let fallback_cwd = cur_project_cwd(&project_storage, external_agent_home);
for path in cur_transcript_files(&project_storage.join("agent-transcripts")) {
candidates.push(SessionFileCandidate {
path,
@@ -79,8 +79,17 @@ fn cur_transcript_files(transcripts_root: &Path) -> Vec<PathBuf> {
files
}
fn cur_project_cwd(project_storage: &Path) -> Option<PathBuf> {
fn cur_project_cwd(project_storage: &Path, external_agent_home: &Path) -> Option<PathBuf> {
let encoded = project_storage.file_name()?.to_str()?;
// Cursor stores projectless chats under this reserved project name.
if encoded == "empty-window" {
let external_agent_home = if external_agent_home.is_absolute() {
external_agent_home.to_path_buf()
} else {
std::env::current_dir().ok()?.join(external_agent_home)
};
return external_agent_home.parent().map(Path::to_path_buf);
}
decode_cur_project_path(encoded)
}
@@ -34,6 +34,43 @@ fn detects_cur_transcript_with_project_cwd() {
);
}
#[test]
fn detects_projectless_cur_transcript_without_embedded_metadata() {
let root = TempDir::new().expect("tempdir");
let external_agent_home = root.path().join(".cursor");
let transcript = write_transcript(
&external_agent_home,
"empty-window",
"projectless-session",
"first request",
);
let sessions =
detect_recent_cur_sessions(&external_agent_home, root.path()).expect("detect sessions");
assert_eq!(
sessions,
vec![ExternalAgentSessionMigration {
path: transcript,
cwd: root.path().to_path_buf(),
title: Some("first request".to_string()),
}]
);
}
#[test]
fn resolves_projectless_cur_cwd_from_relative_home() {
let current_dir = std::env::current_dir().expect("current dir");
assert_eq!(
cur_project_cwd(
Path::new(".cursor/projects/empty-window"),
Path::new(".cursor"),
),
Some(current_dir)
);
}
#[test]
fn detects_cur_transcript_with_embedded_unc_cwd() {
let root = TempDir::new().expect("tempdir");