@@ -1060,6 +1060,80 @@ describe("ClineProvider", () => {
10601060 expect ( new Set ( posts . map ( ( { snapshotId } ) => snapshotId ) ) . size ) . toBe ( 1 )
10611061 } )
10621062
1063+ test . each ( [ false , true ] ) (
1064+ "captures snapshot payload with its sequence before queued deltas (bumpSeq=%s)" ,
1065+ async ( bumpSeq ) => {
1066+ const messages = Array . from (
1067+ { length : 200 } ,
1068+ ( _ , index ) : ClineMessage => ( {
1069+ ts : index + 1 ,
1070+ type : "say" ,
1071+ say : "text" ,
1072+ text : `message ${ index + 1 } ` ,
1073+ images : [ "original-image" ] ,
1074+ } ) ,
1075+ )
1076+ const task = { taskId : "task-1" , clineMessages : messages }
1077+ setCurrentTask ( task )
1078+ provider [ "clineMessagesSeqByTaskId" ] . set ( task . taskId , 4 )
1079+ const postSpy = vi . spyOn ( provider , "postMessageToWebview" ) . mockResolvedValue ( undefined )
1080+ const expectedSnapshot = structuredClone ( messages )
1081+ let releaseQueue ! : ( ) => void
1082+ provider [ "clineMessagesPostQueue" ] = new Promise < void > ( ( resolve ) => {
1083+ releaseQueue = resolve
1084+ } )
1085+
1086+ const snapshot = provider . postClineMessagesSnapshot ( task . taskId , { bumpSeq } )
1087+ const appended : ClineMessage = { ts : 201 , type : "say" , say : "text" , text : "appended after snapshot" }
1088+ task . clineMessages . push ( appended )
1089+ const append = provider . postClineMessageAppended ( task . taskId , appended )
1090+ messages [ 0 ] . text = "updated after snapshot"
1091+ messages [ 0 ] . images ?. push ( "updated-image" )
1092+ const update = provider . postClineMessageUpdated ( task . taskId , messages [ 0 ] )
1093+ releaseQueue ( )
1094+ await Promise . all ( [ snapshot , append , update ] )
1095+
1096+ const snapshotSeq = bumpSeq ? 5 : 4
1097+ const snapshotId = "task-1:1"
1098+ expect ( postSpy . mock . calls . map ( ( [ message ] ) => message ) ) . toEqual ( [
1099+ {
1100+ type : "clineMessagesSnapshotStart" ,
1101+ taskId : task . taskId ,
1102+ clineMessagesSeq : snapshotSeq ,
1103+ snapshotId,
1104+ snapshotTotal : 200 ,
1105+ } ,
1106+ {
1107+ type : "clineMessagesSnapshotChunk" ,
1108+ taskId : task . taskId ,
1109+ clineMessagesSeq : snapshotSeq ,
1110+ snapshotId,
1111+ snapshotStartIndex : 0 ,
1112+ clineMessages : expectedSnapshot ,
1113+ } ,
1114+ {
1115+ type : "clineMessagesSnapshotEnd" ,
1116+ taskId : task . taskId ,
1117+ clineMessagesSeq : snapshotSeq ,
1118+ snapshotId,
1119+ snapshotTotal : 200 ,
1120+ } ,
1121+ {
1122+ type : "clineMessageAppended" ,
1123+ taskId : task . taskId ,
1124+ clineMessagesSeq : snapshotSeq + 1 ,
1125+ clineMessage : appended ,
1126+ } ,
1127+ {
1128+ type : "clineMessageUpdated" ,
1129+ taskId : task . taskId ,
1130+ clineMessagesSeq : snapshotSeq + 2 ,
1131+ clineMessage : messages [ 0 ] ,
1132+ } ,
1133+ ] )
1134+ } ,
1135+ )
1136+
10631137 test . each ( [
10641138 [ "append" , "clineMessageAppended" ] ,
10651139 [ "update" , "clineMessageUpdated" ] ,
@@ -1215,33 +1289,34 @@ describe("ClineProvider", () => {
12151289 )
12161290 } )
12171291
1218- test ( "drops a snapshot invalidated before its first post without cloning it" , async ( ) => {
1219- const task = {
1220- taskId : "task-1" ,
1221- clineMessages : [ { ts : 1 , type : "say" , say : "text" , text : "message" } ] as ClineMessage [ ] ,
1222- }
1223- setCurrentTask ( task )
1224- const postSpy = vi . spyOn ( provider , "postMessageToWebview" )
1225- let releaseQueue ! : ( ) => void
1226- Object . assign ( provider , {
1227- clineMessagesPostQueue : new Promise < void > ( ( resolve ) => {
1228- releaseQueue = resolve
1229- } ) ,
1230- } )
1292+ test . each ( [ "focus" , "generation" ] as const ) (
1293+ "drops a snapshot when %s changes before its first post" ,
1294+ async ( change ) => {
1295+ const task = {
1296+ taskId : "task-1" ,
1297+ clineMessages : [ { ts : 1 , type : "say" , say : "text" , text : "message" } ] as ClineMessage [ ] ,
1298+ }
1299+ setCurrentTask ( task )
1300+ const postSpy = vi . spyOn ( provider , "postMessageToWebview" )
1301+ let releaseQueue ! : ( ) => void
1302+ Object . assign ( provider , {
1303+ clineMessagesPostQueue : new Promise < void > ( ( resolve ) => {
1304+ releaseQueue = resolve
1305+ } ) ,
1306+ } )
12311307
1232- const structuredCloneSpy = vi . spyOn ( globalThis , "structuredClone" )
1233- try {
12341308 const snapshot = provider . postClineMessagesSnapshot ( "task-1" )
1235- task . taskId = "task-2"
1309+ if ( change === "focus" ) {
1310+ task . taskId = "task-2"
1311+ } else {
1312+ provider [ "clineMessagesTransportGeneration" ] ++
1313+ }
12361314 releaseQueue ( )
12371315 await snapshot
12381316
12391317 expect ( postSpy ) . not . toHaveBeenCalled ( )
1240- expect ( structuredCloneSpy ) . not . toHaveBeenCalled ( )
1241- } finally {
1242- structuredCloneSpy . mockRestore ( )
1243- }
1244- } )
1318+ } ,
1319+ )
12451320
12461321 test ( "uses monotonic task-scoped snapshot IDs and an empty no-task snapshot" , async ( ) => {
12471322 await provider . resolveWebviewView ( mockWebviewView )
0 commit comments