lean_ctx/core/import/
cursor.rs1use std::path::{Path, PathBuf};
4
5use super::{ImportResult, ImportSource, home_dir, push_error, read_jsonl_files};
6
7#[must_use]
9pub fn import() -> ImportResult {
10 let Some(home) = home_dir() else {
11 return ImportResult::default();
12 };
13 import_from_root(&home.join(".cursor/projects"))
14}
15
16#[must_use]
18pub fn import_from_root(root: &Path) -> ImportResult {
19 let projects = match std::fs::read_dir(root) {
20 Ok(projects) => projects,
21 Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
22 return ImportResult::default();
23 }
24 Err(error) => {
25 let mut result = ImportResult::default();
26 push_error(&mut result, format!("{}: {error}", root.display()));
27 return result;
28 }
29 };
30
31 let mut files = Vec::new();
32 let mut errors = Vec::new();
33 for project in projects.flatten() {
34 let transcript_dir = project.path().join("agent-transcripts");
35 if !transcript_dir.is_dir() {
36 continue;
37 }
38 match std::fs::read_dir(&transcript_dir) {
39 Ok(entries) => collect_jsonl_files(entries, &mut files),
40 Err(error) => errors.push(format!("{}: {error}", transcript_dir.display())),
41 }
42 }
43 files.sort();
44 let mut result = read_jsonl_files(ImportSource::Cursor, root, files);
45 for error in errors {
46 push_error(&mut result, error);
47 }
48 result
49}
50
51fn collect_jsonl_files(entries: std::fs::ReadDir, files: &mut Vec<PathBuf>) {
52 for entry in entries.flatten() {
53 let path = entry.path();
54 if path.is_file()
55 && path
56 .extension()
57 .is_some_and(|extension| extension == "jsonl")
58 {
59 files.push(path);
60 }
61 }
62}