@@ -54,6 +54,15 @@ pub async fn registered_project_roots() -> Vec<PathBuf> {
5454/// is projectless.
5555pub async fn try_registered_project_roots ( ) -> Option < Vec < PathBuf > > {
5656 let global = GlobalDb :: open ( ) . await ?;
57+ registered_project_roots_from ( & global) . await
58+ }
59+
60+ async fn try_registered_project_roots_at ( profile_root : & Path ) -> Option < Vec < PathBuf > > {
61+ let global = GlobalDb :: open_at ( & profile_root. join ( "global.db" ) ) . await ?;
62+ registered_project_roots_from ( & global) . await
63+ }
64+
65+ async fn registered_project_roots_from ( global : & GlobalDb ) -> Option < Vec < PathBuf > > {
5766 let mut roots = global
5867 . list_project_paths ( )
5968 . await
@@ -72,27 +81,42 @@ pub async fn ingest_user_codex_sessions(session_id: Option<String>) -> Transcrip
7281 let Ok ( profile_root) = crate :: storage:: default_profile_root ( ) else {
7382 return TranscriptIngestStats :: default ( ) ;
7483 } ;
75- let Some ( db ) = open_user_session_db ( & profile_root ) . await else {
84+ let Some ( registered_roots ) = try_registered_project_roots ( ) . await else {
7685 return TranscriptIngestStats :: default ( ) ;
7786 } ;
78- let Some ( source) = codex:: CodexSource :: new ( ) else {
87+ ingest_user_codex_sessions_at ( & profile_root, session_id, registered_roots) . await
88+ }
89+
90+ async fn ingest_user_codex_sessions_at (
91+ profile_root : & Path ,
92+ session_id : Option < String > ,
93+ registered_roots : Vec < PathBuf > ,
94+ ) -> TranscriptIngestStats {
95+ let Some ( db) = open_user_session_db ( profile_root) . await else {
7996 return TranscriptIngestStats :: default ( ) ;
8097 } ;
81- let Some ( registered_roots ) = try_registered_project_roots ( ) . await else {
98+ let Some ( source ) = codex :: CodexSource :: new ( ) else {
8299 return TranscriptIngestStats :: default ( ) ;
83100 } ;
84101 let source = source. for_user_scope ( session_id, registered_roots) ;
85- ingest_source ( & db, & source, & profile_root, None ) . await
102+ ingest_source ( & db, & source, profile_root, None ) . await
86103}
87104
88105pub async fn ingest_user_cursor_sessions ( ) -> TranscriptIngestStats {
89106 let Ok ( profile_root) = crate :: storage:: default_profile_root ( ) else {
90107 return TranscriptIngestStats :: default ( ) ;
91108 } ;
92- let Some ( db ) = open_user_session_db ( & profile_root ) . await else {
109+ let Some ( registered_roots ) = try_registered_project_roots ( ) . await else {
93110 return TranscriptIngestStats :: default ( ) ;
94111 } ;
95- let Some ( registered_roots) = try_registered_project_roots ( ) . await else {
112+ ingest_user_cursor_sessions_at ( & profile_root, registered_roots) . await
113+ }
114+
115+ async fn ingest_user_cursor_sessions_at (
116+ profile_root : & Path ,
117+ registered_roots : Vec < PathBuf > ,
118+ ) -> TranscriptIngestStats {
119+ let Some ( db) = open_user_session_db ( profile_root) . await else {
96120 return TranscriptIngestStats :: default ( ) ;
97121 } ;
98122 let ( composer_stats, owned) = if let Some ( source) = cursor_composer:: CursorComposerSource :: new ( )
@@ -123,7 +147,7 @@ pub async fn ingest_user_cursor_sessions() -> TranscriptIngestStats {
123147 let source = source
124148 . with_skip_session_ids ( owned)
125149 . for_user_scope ( & registered_roots) ;
126- composer_stats. merge ( ingest_source ( & db, & source, & profile_root, None ) . await )
150+ composer_stats. merge ( ingest_source ( & db, & source, profile_root, None ) . await )
127151}
128152
129153pub async fn ingest_user_global_sources ( ) -> TranscriptIngestStats {
@@ -138,29 +162,47 @@ fn provider_selected(scope: Option<SessionProvider>, candidate: SessionProvider)
138162/// outside an explicitly requested message-search scope.
139163pub async fn ingest_user_global_sources_for_provider (
140164 provider : Option < SessionProvider > ,
165+ ) -> TranscriptIngestStats {
166+ let Ok ( profile_root) = crate :: storage:: default_profile_root ( ) else {
167+ return TranscriptIngestStats :: default ( ) ;
168+ } ;
169+ let Some ( roots) = try_registered_project_roots ( ) . await else {
170+ return TranscriptIngestStats :: default ( ) ;
171+ } ;
172+ ingest_user_global_sources_for_provider_with_roots ( & profile_root, provider, roots) . await
173+ }
174+
175+ pub ( crate ) async fn ingest_user_global_sources_for_provider_at (
176+ profile_root : & Path ,
177+ provider : Option < SessionProvider > ,
178+ ) -> TranscriptIngestStats {
179+ let Some ( roots) = try_registered_project_roots_at ( profile_root) . await else {
180+ return TranscriptIngestStats :: default ( ) ;
181+ } ;
182+ ingest_user_global_sources_for_provider_with_roots ( profile_root, provider, roots) . await
183+ }
184+
185+ async fn ingest_user_global_sources_for_provider_with_roots (
186+ profile_root : & Path ,
187+ provider : Option < SessionProvider > ,
188+ roots : Vec < PathBuf > ,
141189) -> TranscriptIngestStats {
142190 let mut stats = TranscriptIngestStats :: default ( ) ;
143191 if provider_selected ( provider, SessionProvider :: Codex ) {
144- stats = stats. merge ( ingest_user_codex_sessions ( None ) . await ) ;
192+ stats = stats. merge ( ingest_user_codex_sessions_at ( profile_root , None , roots . clone ( ) ) . await ) ;
145193 }
146194 if provider_selected ( provider, SessionProvider :: Cursor ) {
147- stats = stats. merge ( ingest_user_cursor_sessions ( ) . await ) ;
195+ stats = stats. merge ( ingest_user_cursor_sessions_at ( profile_root , roots . clone ( ) ) . await ) ;
148196 }
149- let Ok ( profile_root) = crate :: storage:: default_profile_root ( ) else {
150- return stats;
151- } ;
152- let Some ( db) = open_user_session_db ( & profile_root) . await else {
153- return stats;
154- } ;
155- let Some ( roots) = try_registered_project_roots ( ) . await else {
197+ let Some ( db) = open_user_session_db ( profile_root) . await else {
156198 return stats;
157199 } ;
158200 if provider_selected ( provider, SessionProvider :: Hermes ) {
159201 stats = stats. merge ( hermes:: ingest_user_sessions ( & db, & roots) . await ) ;
160202 }
161203 if provider_selected ( provider, SessionProvider :: Claude ) {
162- stats = stats
163- . merge ( claude:: ingest_user_sessions ( & db, & profile_root, None , roots. clone ( ) ) . await ) ;
204+ stats =
205+ stats . merge ( claude:: ingest_user_sessions ( & db, profile_root, None , roots. clone ( ) ) . await ) ;
164206 }
165207 let mut sources: Vec < Box < dyn TranscriptSource > > = Vec :: new ( ) ;
166208 if provider_selected ( provider, SessionProvider :: Vibe )
@@ -189,7 +231,7 @@ pub async fn ingest_user_global_sources_for_provider(
189231 sources. push ( Box :: new ( source. for_user_scope ( roots) ) ) ;
190232 }
191233 for source in sources {
192- let source_stats = ingest_source ( & db, source. as_ref ( ) , & profile_root, None ) . await ;
234+ let source_stats = ingest_source ( & db, source. as_ref ( ) , profile_root, None ) . await ;
193235 stats = stats. merge ( source_stats) ;
194236 }
195237 if stats. messages_upserted > 0 {
@@ -307,20 +349,7 @@ pub async fn ingest_global_sources_for_provider(
307349 project_root : & Path ,
308350 provider : Option < SessionProvider > ,
309351) -> TranscriptIngestStats {
310- ingest_global_sources_for_provider_inner ( db, project_root, provider, true ) . await
311- }
312-
313- async fn ingest_global_sources_for_provider_inner (
314- db : & GlobalDb ,
315- project_root : & Path ,
316- provider : Option < SessionProvider > ,
317- include_user_scope : bool ,
318- ) -> TranscriptIngestStats {
319- // Keep the profile-level projectless history current alongside every
320- // project sweep while respecting an explicit provider scope.
321- if include_user_scope {
322- let _ = ingest_user_global_sources_for_provider ( provider) . await ;
323- }
352+ let _ = ingest_user_global_sources_for_provider ( provider) . await ;
324353 ingest_project_sources_for_provider ( db, project_root, provider, true ) . await
325354}
326355
@@ -415,7 +444,7 @@ pub(crate) async fn ingest_global_sources_for_startup(
415444 project_root : & Path ,
416445) -> TranscriptIngestStats {
417446 let user = ingest_user_global_sources_for_startup ( ) . await ;
418- user. merge ( ingest_global_sources_for_provider_inner ( db, project_root, None , false ) . await )
447+ user. merge ( ingest_project_sources_for_provider ( db, project_root, None , true ) . await )
419448}
420449
421450/// Runs the bounded commit-attribution sweep against the correlation store.
0 commit comments