diff --git a/apps/server/src/preview/ServerBrowser.test.ts b/apps/server/src/preview/ServerBrowser.test.ts index 3925baa1a426e..97d75c2c4ecb0 100644 --- a/apps/server/src/preview/ServerBrowser.test.ts +++ b/apps/server/src/preview/ServerBrowser.test.ts @@ -1961,6 +1961,47 @@ it.effect("a stalled desktop viewer still gets its size, control and reconnect", ).pipe(Effect.provide(layer)), ); +it.live("the tab the desktop shows is visible and picked for agents without a tab", () => + Effect.scoped( + Effect.gen(function* () { + const broker = yield* Broker.PreviewAutomationBroker; + const manager = yield* Manager.PreviewManager; + yield* ServerBrowser.ServerBrowser; + yield* Effect.yieldNow; + const openDesktopTab = Effect.fn("openDesktopTab")(function* (url: string) { + desktopRendersNext = true; + const opened = yield* manager.open({ + threadId: scope.thread.threadId, + url, + runtime: "server", + }); + const tabId = PreviewTabId.make(opened.tabId); + yield* broker.invoke({ scope, tabId, operation: "status", input: {} }); + return tabId; + }); + const recentTab = yield* openDesktopTab("http://localhost:5173/recent"); + const shownTab = yield* openDesktopTab("http://localhost:5173/shown"); + // Opened first and used last, so recency or insertion order alone picks it. + yield* broker.invoke({ scope, tabId: recentTab, operation: "status", input: {} }); + + shownDesktopTabs.add(shownTab); + const status = yield* broker.invoke({ + scope: asSession("agent-b"), + operation: "status", + input: {}, + }); + expect(status).toMatchObject({ + tabId: shownTab, + visible: true, + tabs: [ + expect.objectContaining({ tabId: recentTab, visible: false }), + expect.objectContaining({ tabId: shownTab, visible: true }), + ], + }); + }), + ).pipe(Effect.provide(layer)), +); + it.live("agents read a human's tab with no arguments and act on it only while nobody drives", () => Effect.scoped( Effect.gen(function* () { diff --git a/apps/server/src/preview/ServerBrowser.ts b/apps/server/src/preview/ServerBrowser.ts index 7f128dc5d4eb7..2f681d0c151c9 100644 --- a/apps/server/src/preview/ServerBrowser.ts +++ b/apps/server/src/preview/ServerBrowser.ts @@ -1511,8 +1511,7 @@ const make = Effect.gen(function* () { .sort((left, right) => right.createdAt - left.createdAt)[0] ?? threadTabs.sort( (left, right) => - Number(right.viewers.size > 0) - Number(left.viewers.size > 0) || - right.usedAt - left.usedAt, + Number(isVisible(right)) - Number(isVisible(left)) || right.usedAt - left.usedAt, )[0] ); }; @@ -1621,7 +1620,7 @@ const make = Effect.gen(function* () { const viewport = tab.desktop ? await layoutSize(tab) : tab.page.viewportSize(); const status = { available: true, - visible: tab.viewers.size > 0, + visible: isVisible(tab), tabId: tab.tabId, url: url === "about:blank" ? null : url, title: null, @@ -1648,7 +1647,7 @@ const make = Effect.gen(function* () { ...(candidate.openerTabId === undefined ? {} : { openerTabId: candidate.openerTabId }), owner: tabOwner(candidate), ownedByCaller: candidate.control.agentId === agentSessionId, - visible: candidate.viewers.size > 0, + visible: isVisible(candidate), ...(candidate.profileId === undefined ? {} : { profileId: candidate.profileId }), })), ...profileStatus(),