@@ -10,6 +10,7 @@ import { dispatch } from "../ws/dispatch.js";
1010
1111// Import command handlers to register them
1212import "../commands/workspace.js" ;
13+ import "../commands/workspace-activity.js" ;
1314
1415describe ( "Workspace Commands" , ( ) => {
1516 let db : ReturnType < typeof openDatabase > ;
@@ -46,7 +47,9 @@ describe("Workspace Commands", () => {
4647 ctx = {
4748 db,
4849 workspaceMgr,
49- sessionMgr : { } ,
50+ sessionMgr : {
51+ get : vi . fn ( ( ) => undefined ) ,
52+ } ,
5053 terminalMgr : { } ,
5154 eventBus,
5255 broadcaster : { broadcast : ( ) => { } } ,
@@ -202,4 +205,115 @@ describe("Workspace Commands", () => {
202205 } ) ;
203206 } ) ;
204207 } ) ;
208+
209+ describe ( "workspace.lastViewedTarget" , ( ) => {
210+ it ( "persists and returns the global workspace last-viewed target" , async ( ) => {
211+ const dir = join ( tmpdir ( ) , `workspace-target-test-${ Date . now ( ) } ` ) ;
212+ await mkdir ( dir ) ;
213+
214+ const openResult = await dispatch (
215+ {
216+ kind : "command" ,
217+ id : "open-workspace-target" ,
218+ op : "workspace.open" ,
219+ args : { path : dir } ,
220+ } ,
221+ ctx
222+ ) ;
223+
224+ expect ( openResult . ok ) . toBe ( true ) ;
225+ const workspaceId = ( openResult . data as { id : string } ) . id ;
226+
227+ const writeResult = await dispatch (
228+ {
229+ kind : "command" ,
230+ id : "set-last-viewed-target" ,
231+ op : "workspace.lastViewedTarget.set" ,
232+ args : {
233+ workspaceId,
234+ sessionId : "sess-123" ,
235+ } ,
236+ } ,
237+ ctx
238+ ) ;
239+
240+ expect ( writeResult . ok ) . toBe ( true ) ;
241+ expect ( writeResult . data ) . toMatchObject ( {
242+ workspaceId,
243+ sessionId : undefined ,
244+ } ) ;
245+ expect ( ( writeResult . data as { updatedAt : number } ) . updatedAt ) . toEqual ( expect . any ( Number ) ) ;
246+
247+ const readResult = await dispatch (
248+ {
249+ kind : "command" ,
250+ id : "get-last-viewed-target" ,
251+ op : "workspace.lastViewedTarget.get" ,
252+ args : { } ,
253+ } ,
254+ ctx
255+ ) ;
256+
257+ expect ( readResult . ok ) . toBe ( true ) ;
258+ expect ( readResult . data ) . toMatchObject ( {
259+ workspaceId,
260+ sessionId : undefined ,
261+ } ) ;
262+ expect ( ( readResult . data as { updatedAt : number } ) . updatedAt ) . toEqual ( expect . any ( Number ) ) ;
263+ } ) ;
264+
265+ it ( "drops an out-of-workspace session id while preserving the workspace target" , async ( ) => {
266+ const dir = join ( tmpdir ( ) , `workspace-target-mismatch-${ Date . now ( ) } ` ) ;
267+ await mkdir ( dir ) ;
268+
269+ const openResult = await dispatch (
270+ {
271+ kind : "command" ,
272+ id : "open-workspace-target-mismatch" ,
273+ op : "workspace.open" ,
274+ args : { path : dir } ,
275+ } ,
276+ ctx
277+ ) ;
278+
279+ expect ( openResult . ok ) . toBe ( true ) ;
280+ const workspaceId = ( openResult . data as { id : string } ) . id ;
281+
282+ const result = await dispatch (
283+ {
284+ kind : "command" ,
285+ id : "set-last-viewed-target-mismatch" ,
286+ op : "workspace.lastViewedTarget.set" ,
287+ args : {
288+ workspaceId,
289+ sessionId : "sess-missing" ,
290+ } ,
291+ } ,
292+ ctx
293+ ) ;
294+
295+ expect ( result . ok ) . toBe ( true ) ;
296+ expect ( result . data ) . toMatchObject ( {
297+ workspaceId,
298+ sessionId : undefined ,
299+ } ) ;
300+ } ) ;
301+
302+ it ( "returns workspace_not_found when writing a target for a missing workspace" , async ( ) => {
303+ const result = await dispatch (
304+ {
305+ kind : "command" ,
306+ id : "set-last-viewed-target-missing-workspace" ,
307+ op : "workspace.lastViewedTarget.set" ,
308+ args : {
309+ workspaceId : "ws-missing" ,
310+ } ,
311+ } ,
312+ ctx
313+ ) ;
314+
315+ expect ( result . ok ) . toBe ( false ) ;
316+ expect ( result . error ?. code ) . toBe ( "workspace_not_found" ) ;
317+ } ) ;
318+ } ) ;
205319} ) ;
0 commit comments