@@ -2,6 +2,7 @@ import test from 'node:test';
22import assert from 'node:assert/strict' ;
33import { createTranslator } from '../apps/web/src/i18n.ts' ;
44import { createWorkspaceSessionActions } from '../apps/web/src/features/workspace/session-actions.ts' ;
5+ import { readWorkspaceSyncVersion } from '../apps/web/src/features/workspace/workspace-sync-version.ts' ;
56import type { AppSettings , Toast } from '../apps/web/src/types/app.ts' ;
67import type { WorkbenchState } from '../apps/web/src/state/workbench.ts' ;
78
@@ -200,3 +201,134 @@ test('markSessionIdle does not trigger completion reminder for agent exit notes'
200201
201202 assert . deepEqual ( reminders , [ ] ) ;
202203} ) ;
204+
205+ test ( 'restoreSessionIntoPane bumps the workspace sync version before applying the restored session' , async ( ) => {
206+ const locale = 'en' ;
207+ const t = createTranslator ( locale ) ;
208+ const workspaceId = 'ws-restore-sync' ;
209+ const beforeVersion = readWorkspaceSyncVersion ( workspaceId ) ;
210+ const stateRef = {
211+ current : {
212+ activeTabId : workspaceId ,
213+ layout : {
214+ leftWidth : 320 ,
215+ rightWidth : 320 ,
216+ rightSplit : 64 ,
217+ showCodePanel : false ,
218+ showTerminalPanel : false ,
219+ } ,
220+ overlay : {
221+ visible : false ,
222+ mode : 'local' as const ,
223+ input : '' ,
224+ target : { type : 'native' as const } ,
225+ } ,
226+ tabs : [
227+ {
228+ id : workspaceId ,
229+ title : 'Workspace Restore' ,
230+ status : 'ready' as const ,
231+ controller : {
232+ role : 'controller' as const ,
233+ deviceId : 'device-a' ,
234+ clientId : 'client-a' ,
235+ fencingToken : 1 ,
236+ takeoverPending : false ,
237+ takeoverRequestedBySelf : false ,
238+ } ,
239+ agent : {
240+ provider : 'claude' as const ,
241+ command : 'claude' ,
242+ useWsl : false ,
243+ } ,
244+ git : { branch : 'main' , changes : 0 , lastCommit : 'abc123' } ,
245+ gitChanges : [ ] ,
246+ worktrees : [ ] ,
247+ sessions : [
248+ {
249+ id : 'draft-restore' ,
250+ title : 'Session 1' ,
251+ status : 'idle' as const ,
252+ mode : 'branch' as const ,
253+ autoFeed : true ,
254+ queue : [ ] ,
255+ messages : [ ] ,
256+ stream : '' ,
257+ unread : 0 ,
258+ lastActiveAt : 1 ,
259+ isDraft : true ,
260+ } ,
261+ ] ,
262+ activeSessionId : 'draft-restore' ,
263+ archive : [ ] ,
264+ terminals : [ ] ,
265+ activeTerminalId : '' ,
266+ fileTree : [ ] ,
267+ changesTree : [ ] ,
268+ filePreview : {
269+ path : '' ,
270+ content : '' ,
271+ mode : 'preview' as const ,
272+ originalContent : '' ,
273+ modifiedContent : '' ,
274+ dirty : false ,
275+ } ,
276+ paneLayout : {
277+ type : 'leaf' as const ,
278+ id : 'pane-draft' ,
279+ sessionId : 'draft-restore' ,
280+ } ,
281+ activePaneId : 'pane-draft' ,
282+ idlePolicy : {
283+ enabled : true ,
284+ idleMinutes : 10 ,
285+ maxActive : 3 ,
286+ pressure : true ,
287+ } ,
288+ } ,
289+ ] ,
290+ } satisfies WorkbenchState ,
291+ } ;
292+
293+ const actions = createWorkspaceSessionActions ( {
294+ appSettings : defaultAppSettings ( ) ,
295+ locale,
296+ t,
297+ stateRef,
298+ updateTab : ( tabId , updater ) => {
299+ stateRef . current = {
300+ ...stateRef . current ,
301+ tabs : stateRef . current . tabs . map ( ( tab ) => ( tab . id === tabId ? updater ( tab ) : tab ) ) ,
302+ } ;
303+ } ,
304+ withServiceFallback : async ( _operation , fallback ) => {
305+ if ( fallback === null ) {
306+ return {
307+ session : {
308+ id : 7 ,
309+ title : 'History Restore Session' ,
310+ status : 'idle' as const ,
311+ mode : 'branch' as const ,
312+ auto_feed : true ,
313+ queue : [ ] ,
314+ messages : [ ] ,
315+ stream : '' ,
316+ unread : 0 ,
317+ last_active_at : 10 ,
318+ claude_session_id : 'claude-restore-sync' ,
319+ } ,
320+ alreadyActive : false ,
321+ } ;
322+ }
323+ return fallback ;
324+ } ,
325+ addToast : ( ) => { } ,
326+ } ) ;
327+
328+ const restored = await actions . restoreSessionIntoPane ( workspaceId , '7' ) ;
329+
330+ assert . equal ( restored ?. id , 7 ) ;
331+ assert . equal ( readWorkspaceSyncVersion ( workspaceId ) , beforeVersion + 1 ) ;
332+ assert . equal ( stateRef . current . tabs [ 0 ] ?. activeSessionId , '7' ) ;
333+ assert . equal ( stateRef . current . tabs [ 0 ] ?. sessions [ 0 ] ?. title , 'History Restore Session' ) ;
334+ } ) ;
0 commit comments