1use super::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct LocatedNativeSession {
7 pub native_session_id: String,
8 pub source_path: PathBuf,
9}
10
11#[derive(Debug, Clone)]
13pub struct NativeSessionListing {
14 pub native_session_id: String,
15 pub title: String,
16 pub modified_at: SystemTime,
17 pub git_branch: String,
18 pub size_bytes: u64,
19 pub cwd: PathBuf,
20 pub unavailable_reason: Option<&'static str>,
22 pub natively_archived: bool,
24}
25
26pub fn locate_native_session(
28 harness: HarnessKind,
29 home: &Path,
30 selection: &ClaudeSessionSelection,
31) -> Result<LocatedNativeSession> {
32 let (native_session_id, source_path) = match harness {
33 HarnessKind::Muse => {
34 return muse::locate(&mj_checkpoint::native::muse_sessions_root(home)?, selection);
35 }
36 HarnessKind::Codex => {
37 let located = locate_codex_session(home, selection)?;
38 (located.native_session_id, located.jsonl_path)
39 }
40 HarnessKind::Claude => {
41 let located = locate_claude_session(home, selection)?;
42 (located.native_session_id, located.jsonl_path)
43 }
44 HarnessKind::Kimi => {
45 let located = locate_kimi_session(home, selection)?;
46 (located.native_session_id, located.session_path)
47 }
48 HarnessKind::Grok => {
49 let located = locate_grok_session(home, selection)?;
50 (located.native_session_id, located.session_path)
51 }
52 };
53 Ok(LocatedNativeSession {
54 native_session_id,
55 source_path,
56 })
57}
58
59pub fn read_native_transcript(
61 harness: HarnessKind,
62 source_path: &Path,
63) -> Result<ClaudeTranscript> {
64 match harness {
65 HarnessKind::Muse => muse::read_transcript(source_path),
66 HarnessKind::Codex => read_codex_transcript(source_path),
67 HarnessKind::Claude => read_claude_transcript(source_path),
68 HarnessKind::Kimi => read_kimi_transcript(source_path),
69 HarnessKind::Grok => read_grok_transcript(source_path),
70 }
71}
72
73pub fn scan_native_sessions(
75 harness: HarnessKind,
76 home: &Path,
77 mut report: impl FnMut(SessionScanProgress<NativeSessionListing>),
78) -> Result<()> {
79 let mut forward = |scanned, total, session| {
80 report(SessionScanProgress {
81 scanned,
82 total,
83 session,
84 });
85 };
86 match harness {
87 HarnessKind::Muse => muse::scan(
88 &mj_checkpoint::native::muse_sessions_root(home)?,
89 |progress| {
90 forward(progress.scanned, progress.total, progress.session);
91 },
92 ),
93 HarnessKind::Codex => scan_codex_sessions(home, |progress| {
94 let session = progress.session.map(|session| NativeSessionListing {
95 unavailable_reason: session.history_mode.import_issue(),
96 native_session_id: session.native_session_id,
97 title: session.title,
98 modified_at: session.modified_at,
99 git_branch: session.git_branch,
100 size_bytes: session.size_bytes,
101 cwd: session.cwd,
102 natively_archived: session.natively_archived,
103 });
104 forward(progress.scanned, progress.total, session);
105 }),
106 HarnessKind::Claude => scan_claude_sessions(home, |progress| {
107 let session = progress.session.map(|session| NativeSessionListing {
108 native_session_id: session.native_session_id,
109 title: session.title,
110 modified_at: session.modified_at,
111 git_branch: session.git_branch,
112 size_bytes: session.size_bytes,
113 cwd: session.cwd,
114 unavailable_reason: None,
115 natively_archived: false,
116 });
117 forward(progress.scanned, progress.total, session);
118 }),
119 HarnessKind::Kimi => scan_kimi_sessions(home, |progress| {
120 let session = progress.session.map(|session| NativeSessionListing {
121 native_session_id: session.native_session_id,
122 title: session.title,
123 modified_at: session.modified_at,
124 git_branch: session.git_branch,
125 size_bytes: session.size_bytes,
126 cwd: session.cwd,
127 unavailable_reason: None,
128 natively_archived: false,
129 });
130 forward(progress.scanned, progress.total, session);
131 }),
132 HarnessKind::Grok => scan_grok_sessions(home, |progress| {
133 let session = progress.session.map(|session| NativeSessionListing {
134 native_session_id: session.native_session_id,
135 title: session.title,
136 modified_at: session.modified_at,
137 git_branch: session.git_branch,
138 size_bytes: session.size_bytes,
139 cwd: session.cwd,
140 unavailable_reason: None,
141 natively_archived: false,
142 });
143 forward(progress.scanned, progress.total, session);
144 }),
145 }
146}