Skip to content

Commit 520961f

Browse files
committed
feat(desktop): isolate chat browser and terminal sessions
1 parent 39740df commit 520961f

66 files changed

Lines changed: 7454 additions & 992 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/desktop/build/generated-icon.icon/Assets/border.svg

Lines changed: 0 additions & 3 deletions
This file was deleted.

apps/desktop/build/generated-icon.icon/icon.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@
99
"image-name": "logo.png",
1010
"is-glass": false,
1111
"name": "Sim"
12-
},
13-
{
14-
"image-name": "border.svg",
15-
"is-glass": false,
16-
"name": "Staging Border"
1712
}
1813
],
1914
"shadow": {

apps/desktop/src/main/browser-agent/driver.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,82 @@ describe('executeTool', () => {
6565
expect(second.result).toMatchObject({ tabs: [] })
6666
})
6767

68+
it('keeps tool queues and tab state isolated by chat scope', async () => {
69+
await driver.executeTool('chat-a', 'browser_open_tab', {})
70+
await driver.executeTool('chat-a', 'browser_open_tab', {})
71+
await driver.executeTool('chat-b', 'browser_open_tab', {})
72+
73+
const chatA = await driver.executeTool('chat-a', 'browser_list_tabs', {})
74+
const chatB = await driver.executeTool('chat-b', 'browser_list_tabs', {})
75+
76+
expect(chatA).toMatchObject({
77+
ok: true,
78+
result: { scopeId: 'chat-a', activeTabId: '2', tabs: [{ tabId: '1' }, { tabId: '2' }] },
79+
})
80+
expect(chatB).toMatchObject({
81+
ok: true,
82+
result: { scopeId: 'chat-b', activeTabId: '1', tabs: [{ tabId: '1' }] },
83+
})
84+
})
85+
86+
it('adopts pending tabs over an activation-only durable destination', async () => {
87+
await driver.executeTool('pending:new-chat', 'browser_open_tab', {})
88+
driver.activateBrowserScope('chat-real')
89+
90+
expect(driver.migrateBrowserScope('pending:new-chat', 'chat-real')).toBe(true)
91+
await expect(driver.executeTool('chat-real', 'browser_list_tabs', {})).resolves.toMatchObject({
92+
ok: true,
93+
result: { scopeId: 'chat-real', tabs: [{ tabId: '1' }] },
94+
})
95+
96+
await driver.executeTool('pending:other-chat', 'browser_open_tab', {})
97+
await driver.executeTool('chat-occupied', 'browser_open_tab', {})
98+
expect(driver.migrateBrowserScope('pending:other-chat', 'chat-occupied')).toBe(false)
99+
})
100+
101+
it('keeps activation lazy, then restores and disposes through the driver API', async () => {
102+
const snapshot: session.BrowserSessionSnapshotV1 = {
103+
v: 1,
104+
tabs: [{ url: 'https://restored.example/', pinned: false }],
105+
activeIndex: 0,
106+
}
107+
const load = vi.fn(() => snapshot)
108+
const disposeScope = vi.fn()
109+
driver.initDriver(
110+
{
111+
onPageState: vi.fn(),
112+
onTabsState: vi.fn(),
113+
onSessionStatus: vi.fn(),
114+
onFillAvailability: vi.fn(),
115+
},
116+
() => null,
117+
undefined,
118+
{
119+
load,
120+
save: vi.fn(),
121+
migrateScope: vi.fn(),
122+
disposeScope,
123+
}
124+
)
125+
126+
driver.activateBrowserScope('chat-restored')
127+
expect(load).not.toHaveBeenCalled()
128+
expect(session.withBrowserScope('chat-restored', () => session.peekTabsState().tabs)).toEqual(
129+
[]
130+
)
131+
132+
const listed = driver.restoreBrowserScope('chat-restored')
133+
expect(load).toHaveBeenCalledWith('chat-restored')
134+
expect(listed).toMatchObject({
135+
tabs: [{ url: 'https://restored.example/' }],
136+
})
137+
const restoredTab = session.withBrowserScope('chat-restored', () => session.activeTab())
138+
139+
driver.disposeBrowserScope('chat-restored')
140+
expect(restoredTab?.view.webContents.close).toHaveBeenCalled()
141+
expect(disposeScope).toHaveBeenCalledWith('chat-restored')
142+
})
143+
68144
it.each(['', 'about:blank'])(
69145
'fails page tools immediately and releases queued tab listing when the URL is %j',
70146
async (url) => {

0 commit comments

Comments
 (0)