@@ -734,6 +734,7 @@ describe("useThreadActions", () => {
734734 type : "setThreads" ,
735735 workspaceId : "ws-1" ,
736736 sortKey : "updated_at" ,
737+ preserveAnchors : true ,
737738 threads : [
738739 {
739740 id : "thread-1" ,
@@ -1095,6 +1096,84 @@ describe("useThreadActions", () => {
10951096 } ) ;
10961097 } ) ;
10971098
1099+ it ( "matches windows namespace-prefixed workspace threads client-side" , async ( ) => {
1100+ const windowsWorkspace : WorkspaceInfo = {
1101+ ...workspace ,
1102+ path : "C:\\Dev\\CodexMon" ,
1103+ } ;
1104+ vi . mocked ( listThreads ) . mockResolvedValue ( {
1105+ result : {
1106+ data : [
1107+ {
1108+ id : "thread-win-ns-1" ,
1109+ cwd : "\\\\?\\C:\\Dev\\CodexMon" ,
1110+ preview : "Windows namespace thread" ,
1111+ updated_at : 5000 ,
1112+ } ,
1113+ ] ,
1114+ nextCursor : null ,
1115+ } ,
1116+ } ) ;
1117+ vi . mocked ( getThreadTimestamp ) . mockReturnValue ( 5000 ) ;
1118+
1119+ const { result, dispatch } = renderActions ( ) ;
1120+
1121+ await act ( async ( ) => {
1122+ await result . current . listThreadsForWorkspace ( windowsWorkspace ) ;
1123+ } ) ;
1124+
1125+ expect ( dispatch ) . toHaveBeenCalledWith ( {
1126+ type : "setThreads" ,
1127+ workspaceId : "ws-1" ,
1128+ sortKey : "updated_at" ,
1129+ threads : [
1130+ {
1131+ id : "thread-win-ns-1" ,
1132+ name : "Windows namespace thread" ,
1133+ updatedAt : 5000 ,
1134+ createdAt : 0 ,
1135+ } ,
1136+ ] ,
1137+ } ) ;
1138+ } ) ;
1139+
1140+ it ( "matches nested workspace threads client-side" , async ( ) => {
1141+ vi . mocked ( listThreads ) . mockResolvedValue ( {
1142+ result : {
1143+ data : [
1144+ {
1145+ id : "thread-nested-1" ,
1146+ cwd : "/tmp/codex/subdir/project" ,
1147+ preview : "Nested thread" ,
1148+ updated_at : 5000 ,
1149+ } ,
1150+ ] ,
1151+ nextCursor : null ,
1152+ } ,
1153+ } ) ;
1154+ vi . mocked ( getThreadTimestamp ) . mockReturnValue ( 5000 ) ;
1155+
1156+ const { result, dispatch } = renderActions ( ) ;
1157+
1158+ await act ( async ( ) => {
1159+ await result . current . listThreadsForWorkspace ( workspace ) ;
1160+ } ) ;
1161+
1162+ expect ( dispatch ) . toHaveBeenCalledWith ( {
1163+ type : "setThreads" ,
1164+ workspaceId : "ws-1" ,
1165+ sortKey : "updated_at" ,
1166+ threads : [
1167+ {
1168+ id : "thread-nested-1" ,
1169+ name : "Nested thread" ,
1170+ updatedAt : 5000 ,
1171+ createdAt : 0 ,
1172+ } ,
1173+ ] ,
1174+ } ) ;
1175+ } ) ;
1176+
10981177 it ( "preserves list state when requested" , async ( ) => {
10991178 vi . mocked ( listThreads ) . mockResolvedValue ( {
11001179 result : {
@@ -1313,6 +1392,52 @@ describe("useThreadActions", () => {
13131392 } ) ;
13141393 } ) ;
13151394
1395+ it ( "matches nested workspace threads when loading older threads" , async ( ) => {
1396+ vi . mocked ( listThreads ) . mockResolvedValue ( {
1397+ result : {
1398+ data : [
1399+ {
1400+ id : "thread-nested-older" ,
1401+ cwd : "/tmp/codex/subdir/project" ,
1402+ preview : "Nested older preview" ,
1403+ updated_at : 4000 ,
1404+ } ,
1405+ ] ,
1406+ nextCursor : null ,
1407+ } ,
1408+ } ) ;
1409+ vi . mocked ( getThreadTimestamp ) . mockImplementation ( ( thread ) => {
1410+ const value = ( thread as Record < string , unknown > ) . updated_at as number ;
1411+ return value ?? 0 ;
1412+ } ) ;
1413+
1414+ const { result, dispatch } = renderActions ( {
1415+ threadsByWorkspace : {
1416+ "ws-1" : [ { id : "thread-1" , name : "Agent 1" , updatedAt : 6000 } ] ,
1417+ } ,
1418+ threadListCursorByWorkspace : { "ws-1" : "cursor-1" } ,
1419+ } ) ;
1420+
1421+ await act ( async ( ) => {
1422+ await result . current . loadOlderThreadsForWorkspace ( workspace ) ;
1423+ } ) ;
1424+
1425+ expect ( dispatch ) . toHaveBeenCalledWith ( {
1426+ type : "setThreads" ,
1427+ workspaceId : "ws-1" ,
1428+ sortKey : "updated_at" ,
1429+ threads : [
1430+ { id : "thread-1" , name : "Agent 1" , updatedAt : 6000 } ,
1431+ {
1432+ id : "thread-nested-older" ,
1433+ name : "Nested older preview" ,
1434+ updatedAt : 4000 ,
1435+ createdAt : 0 ,
1436+ } ,
1437+ ] ,
1438+ } ) ;
1439+ } ) ;
1440+
13161441 it ( "detects model metadata from list responses" , async ( ) => {
13171442 vi . mocked ( listThreads ) . mockResolvedValue ( {
13181443 result : {
0 commit comments