@@ -164,7 +164,7 @@ impl SessionStore {
164164 }
165165 // Fallback: scan all workspace namespaces under ~/.claw/sessions/
166166 // so that /resume latest can find sessions from other workspaces
167- if let Some ( latest) = Self :: scan_global_sessions ( ) ?. into_iter ( ) . next ( ) {
167+ if let Some ( latest) = self . scan_global_sessions ( ) ?. into_iter ( ) . next ( ) {
168168 return Ok ( latest) ;
169169 }
170170 Err ( SessionControlError :: Format ( format_no_managed_sessions (
@@ -251,28 +251,43 @@ impl SessionStore {
251251 . map ( Path :: to_path_buf)
252252 }
253253
254- /// Scan all workspace namespaces under the global sessions root
255- /// (`~/.claw/sessions/`) to find sessions from any workspace.
256- /// Used as a fallback when the current workspace has no sessions.
257- fn scan_global_sessions ( ) -> Result < Vec < ManagedSessionSummary > , SessionControlError > {
258- let global_root = global_sessions_root ( ) ;
259- let entries = match fs:: read_dir ( & global_root) {
260- Ok ( entries) => entries,
261- Err ( err) if err. kind ( ) == std:: io:: ErrorKind :: NotFound => return Ok ( Vec :: new ( ) ) ,
262- Err ( err) => return Err ( err. into ( ) ) ,
263- } ;
254+ /// Scan all known session storage locations for sessions from any workspace.
255+ /// Checks both the global root (~/.claw/sessions/) and the project-local
256+ /// .claw/sessions/ parent directory. Used as a fallback when the current
257+ /// workspace has no sessions.
258+ #[ allow( clippy:: unnecessary_wraps) ]
259+ fn scan_global_sessions ( & self ) -> Result < Vec < ManagedSessionSummary > , SessionControlError > {
264260 let mut sessions = Vec :: new ( ) ;
265- for entry in entries {
266- let Ok ( entry) = entry else {
267- continue ;
268- } ;
269- let path = entry. path ( ) ;
270- if !path. is_dir ( ) {
271- continue ;
261+
262+ // Scan global root: ~/.claw/sessions/<fingerprint>/
263+ let global_root = global_sessions_root ( ) ;
264+ if let Ok ( entries) = fs:: read_dir ( & global_root) {
265+ for entry in entries. flatten ( ) {
266+ let path = entry. path ( ) ;
267+ if path. is_dir ( ) {
268+ let _ = Self :: collect_sessions_from_dir_unvalidated ( & path, & mut sessions) ;
269+ }
272270 }
273- // Silently ignore errors reading individual workspace dirs
274- let _ = Self :: collect_sessions_from_dir_unvalidated ( & path, & mut sessions) ;
275271 }
272+
273+ // Scan project-local parent: <cwd>/.claw/sessions/<fingerprint>/
274+ // Sessions are stored here by from_cwd(), so we must check all
275+ // fingerprint subdirs, not just the current workspace's.
276+ if let Some ( local_parent) = self . legacy_sessions_root ( ) {
277+ if let Ok ( entries) = fs:: read_dir ( & local_parent) {
278+ for entry in entries. flatten ( ) {
279+ let path = entry. path ( ) ;
280+ if path. is_dir ( ) && path != self . sessions_root {
281+ let _ = Self :: collect_sessions_from_dir_unvalidated ( & path, & mut sessions) ;
282+ } else if path == self . sessions_root {
283+ // Already searched in list_sessions(), but include here
284+ // in case this is called standalone
285+ let _ = Self :: collect_sessions_from_dir_unvalidated ( & path, & mut sessions) ;
286+ }
287+ }
288+ }
289+ }
290+
276291 sort_managed_sessions ( & mut sessions) ;
277292 Ok ( sessions)
278293 }
0 commit comments