@@ -236,6 +236,7 @@ struct RawLine {
236236 summary : Option < String > ,
237237 slug : Option < String > ,
238238 uuid : Option < String > ,
239+ cwd : Option < String > ,
239240 message : Option < RawMessage > ,
240241 timestamp : Option < String > ,
241242 #[ serde( rename = "isMeta" ) ]
@@ -649,6 +650,7 @@ async fn get_sessions_usage(project_id: String) -> Result<Vec<SessionUsageEntry>
649650struct SessionHead {
650651 title : Option < String > ,
651652 summary : Option < String > ,
653+ cwd : Option < String > ,
652654 message_count : usize ,
653655}
654656
@@ -672,12 +674,13 @@ fn read_session_head(path: &Path, max_lines: usize) -> SessionHead {
672674
673675 let file = match fs:: File :: open ( path) {
674676 Ok ( f) => f,
675- Err ( _) => return SessionHead { title : None , summary : None , message_count : 0 } ,
677+ Err ( _) => return SessionHead { title : None , summary : None , cwd : None , message_count : 0 } ,
676678 } ;
677679
678680 let reader = BufReader :: new ( file) ;
679681 let mut summary = None ;
680682 let mut slug: Option < String > = None ;
683+ let mut cwd: Option < String > = None ;
681684 let mut first_user_message: Option < String > = None ;
682685 let mut message_count = 0 ;
683686
@@ -700,6 +703,14 @@ fn read_session_head(path: &Path, max_lines: usize) -> SessionHead {
700703 }
701704 if parsed. line_type . as_deref ( ) == Some ( "user" ) {
702705 message_count += 1 ;
706+ // Capture cwd from first user message
707+ if cwd. is_none ( ) {
708+ if let Some ( c) = & parsed. cwd {
709+ if !c. is_empty ( ) {
710+ cwd = Some ( c. clone ( ) ) ;
711+ }
712+ }
713+ }
703714 // Capture first user message as fallback summary
704715 if first_user_message. is_none ( ) {
705716 if let Some ( msg) = & parsed. message {
@@ -740,7 +751,7 @@ fn read_session_head(path: &Path, max_lines: usize) -> SessionHead {
740751
741752 let title = slug. map ( |s| slug_to_title ( & s) ) ;
742753 let final_summary = summary. or ( first_user_message) . map ( |s| restore_slash_command ( & s) ) ;
743- SessionHead { title, summary : final_summary, message_count }
754+ SessionHead { title, summary : final_summary, cwd , message_count }
744755}
745756
746757/// Convert <command-message>...</command-message><command-name>/cmd</command-name> to /cmd format
@@ -867,7 +878,7 @@ async fn list_all_sessions() -> Result<Vec<Session>, String> {
867878 . map ( |d| d. as_secs ( ) )
868879 . unwrap_or ( last_modified) ;
869880
870- let display_path = decode_project_path ( project_id) ;
881+ let display_path = head . cwd . clone ( ) . unwrap_or_else ( || decode_project_path ( project_id) ) ;
871882
872883 all_sessions. push ( Session {
873884 id : session_id. clone ( ) ,
@@ -909,6 +920,7 @@ async fn list_all_sessions() -> Result<Vec<Session>, String> {
909920 }
910921
911922 let head = read_session_head ( & path, 20 ) ;
923+ let session_path = head. cwd . clone ( ) . unwrap_or_else ( || display_path. clone ( ) ) ;
912924
913925 let metadata = fs:: metadata ( & path) . ok ( ) ;
914926 let last_modified = metadata. as_ref ( )
@@ -925,7 +937,7 @@ async fn list_all_sessions() -> Result<Vec<Session>, String> {
925937 all_sessions. push ( Session {
926938 id : session_id,
927939 project_id : project_id. clone ( ) ,
928- project_path : Some ( display_path . clone ( ) ) ,
940+ project_path : Some ( session_path ) ,
929941 title : head. title ,
930942 summary : head. summary ,
931943 message_count : head. message_count ,
@@ -1014,6 +1026,7 @@ async fn list_all_chats(
10141026 let content = fs:: read_to_string ( & path) . unwrap_or_default ( ) ;
10151027
10161028 let mut session_summary: Option < String > = None ;
1029+ let mut session_cwd: Option < String > = None ;
10171030 let mut session_messages: Vec < ChatMessage > = Vec :: new ( ) ;
10181031
10191032 for line in content. lines ( ) {
@@ -1024,6 +1037,15 @@ async fn list_all_chats(
10241037 session_summary = parsed. summary ;
10251038 }
10261039
1040+ // Capture cwd from first user message
1041+ if session_cwd. is_none ( ) {
1042+ if let Some ( c) = & parsed. cwd {
1043+ if !c. is_empty ( ) {
1044+ session_cwd = Some ( c. clone ( ) ) ;
1045+ }
1046+ }
1047+ }
1048+
10271049 if line_type == Some ( "user" ) || line_type == Some ( "assistant" ) {
10281050 if let Some ( msg) = & parsed. message {
10291051 let role = msg. role . clone ( ) . unwrap_or_default ( ) ;
@@ -1048,9 +1070,11 @@ async fn list_all_chats(
10481070 }
10491071 }
10501072
1051- // Update session_summary for all messages
1073+ // Update session_summary and project_path for all messages
1074+ let resolved_path = session_cwd. unwrap_or ( project_path) ;
10521075 for msg in & mut session_messages {
10531076 msg. session_summary = session_summary. clone ( ) ;
1077+ msg. project_path = resolved_path. clone ( ) ;
10541078 }
10551079
10561080 all_chats. extend ( session_messages) ;
0 commit comments