Skip to content

Commit 97ef2af

Browse files
committed
Desktop app ui cleanup
1 parent d41919d commit 97ef2af

17 files changed

Lines changed: 124 additions & 477 deletions

File tree

‎apps/desktop/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ src/main/ # main process (bundled to dist/main.cjs)
2323
updater.ts # electron-updater wiring, channels, downgrade/block guards
2424
menu.ts # role-based macOS menus
2525
src/preload/ # contextBridge IPC bridge (bundled to dist/preload.cjs)
26-
static/ # bundled local pages (offline.html, settings.html)
26+
static/ # bundled local pages (offline.html)
2727
e2e/ # Playwright _electron smoke suite
2828
```
2929

‎apps/desktop/src/main/index.ts‎

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ import {
2323
handleConnectIntercept,
2424
tearDownSession,
2525
} from '@/main/session-lifecycle'
26-
import { closeSettingsWindow, openSettingsWindow } from '@/main/settings-window'
27-
import { createLauncherShortcutManager, LAUNCHER_SHORTCUT_PRESETS } from '@/main/shortcuts'
26+
import { createLauncherShortcutManager } from '@/main/shortcuts'
2827
import { attachTelemetryPolicy } from '@/main/telemetry-policy'
29-
import { installTray, type TrayHandle } from '@/main/tray'
28+
import { installTray, settingsRoute, type TrayHandle } from '@/main/tray'
3029
import { checkForUpdatesInteractive, initUpdater } from '@/main/updater'
3130
import { createMainWindow, setupPermissionHandlers } from '@/main/window'
3231
import { attachWindowOpenPolicy, isPopupContents } from '@/main/windows'
@@ -185,8 +184,9 @@ function main(): void {
185184
void win.loadURL(`${origin}${route}`).catch(() => {})
186185
}
187186

187+
/** Opens the Sim app's settings page in the main window. */
188188
function openSettings(): void {
189-
openSettingsWindow({ preloadPath, isPackaged: app.isPackaged, getMainWindow })
189+
void openMainWindowAt(settingsRoute(config.get('lastRoute')))
190190
}
191191

192192
/**
@@ -229,32 +229,6 @@ function main(): void {
229229

230230
const launcherShortcut = createLauncherShortcutManager(toggleLauncher)
231231

232-
async function applyOrigin(raw: string) {
233-
const previousOrigin = appOrigin()
234-
const result = config.setOrigin(raw)
235-
if (!result.ok) {
236-
return result
237-
}
238-
closeSettingsWindow()
239-
if (result.origin === previousOrigin) {
240-
return result
241-
}
242-
logger.info('Server origin changed; recreating window')
243-
events.record('origin_changed')
244-
await localFilesystem.forgetAll()
245-
handoff.clear()
246-
// The launcher window is bound to the old origin's partition; the next
247-
// summon recreates it against the new origin.
248-
launcher.destroy()
249-
const win = getMainWindow()
250-
if (win) {
251-
mainWindow = null
252-
win.destroy()
253-
}
254-
await createAndLoadMainWindow()
255-
return result
256-
}
257-
258232
async function signOutFromMenu(): Promise<void> {
259233
await localFilesystem.forgetAll()
260234
const ses = session.fromPartition(partitionForOrigin(appOrigin()))
@@ -316,9 +290,6 @@ function main(): void {
316290
appOrigin,
317291
allowHttpLocalhost,
318292
retryLoad: () => loadHealth?.retry(),
319-
openSettings,
320-
closeSettings: closeSettingsWindow,
321-
applyOrigin,
322293
localFilesystem,
323294
beginOAuthConnect: (providerId, scope) => connectFlow.beginConnectHandoff(providerId, scope),
324295
launcher: {
@@ -336,22 +307,6 @@ function main(): void {
336307
hide: () => launcher.hide(),
337308
resize: (height) => launcher.resize(height),
338309
},
339-
launcherShortcut: {
340-
get: () => ({
341-
shortcut: launcherShortcut.current(),
342-
presets: [...LAUNCHER_SHORTCUT_PRESETS],
343-
status: launcherShortcut.status(),
344-
}),
345-
set: (raw) => {
346-
const status = launcherShortcut.apply(raw)
347-
config.set('launcherShortcut', launcherShortcut.current())
348-
return {
349-
shortcut: launcherShortcut.current(),
350-
presets: [...LAUNCHER_SHORTCUT_PRESETS],
351-
status,
352-
}
353-
},
354-
},
355310
})
356311
await createAndLoadMainWindow()
357312
installApplicationMenu({
@@ -372,7 +327,6 @@ function main(): void {
372327
appOrigin,
373328
lastRoute: () => config.get('lastRoute'),
374329
openMainWindow: (route) => void openMainWindowAt(route),
375-
openSettings,
376330
})
377331
}
378332
initUpdater({ getWindow: getMainWindow, events })

‎apps/desktop/src/main/ipc.test.ts‎

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function collectHandlers() {
2222
return { invoke, on }
2323
}
2424

25-
const fileEvent = { senderFrame: { url: 'file:///app/static/settings.html' } }
25+
const fileEvent = { senderFrame: { url: 'file:///app/static/offline.html' } }
2626
const appEvent = { senderFrame: { url: `${APP}/workspace/ws1` } }
2727
const evilEvent = { senderFrame: { url: 'https://evil.example/page' } }
2828

@@ -38,9 +38,6 @@ describe('registerIpcHandlers', () => {
3838
allowHttpLocalhost: () => false,
3939
retryLoad: vi.fn(),
4040
beginOAuthConnect: vi.fn(async () => true),
41-
openSettings: vi.fn(),
42-
closeSettings: vi.fn(),
43-
applyOrigin: vi.fn(async () => ({ ok: true as const, origin: 'https://sim.ai' })),
4441
localFilesystem: new LocalFilesystemService({
4542
chooseDirectory: vi.fn(async () => null),
4643
}),
@@ -50,18 +47,6 @@ describe('registerIpcHandlers', () => {
5047
hide: vi.fn(),
5148
resize: vi.fn(),
5249
},
53-
launcherShortcut: {
54-
get: vi.fn(() => ({
55-
shortcut: 'Alt+Space',
56-
presets: ['Alt+Space'],
57-
status: 'registered' as const,
58-
})),
59-
set: vi.fn(() => ({
60-
shortcut: 'Control+Space',
61-
presets: ['Alt+Space'],
62-
status: 'registered' as const,
63-
})),
64-
},
6550
}
6651
registerIpcHandlers(deps)
6752
})
@@ -86,9 +71,9 @@ describe('registerIpcHandlers', () => {
8671

8772
// Chip-initiated connects carry workspace/credential scope; malformed
8873
// scopes (wrong types, unsafe ids) are rejected before the handoff.
89-
expect(
90-
await handler?.(appEvent, 'slack', { workspaceId: 'ws1', credentialId: 'cred_1' })
91-
).toBe(true)
74+
expect(await handler?.(appEvent, 'slack', { workspaceId: 'ws1', credentialId: 'cred_1' })).toBe(
75+
true
76+
)
9277
expect(deps.beginOAuthConnect).toHaveBeenCalledWith('slack', {
9378
workspaceId: 'ws1',
9479
credentialId: 'cred_1',
@@ -107,36 +92,19 @@ describe('registerIpcHandlers', () => {
10792
).toEqual({ ok: true, data: { mounts: [] } })
10893
})
10994

110-
it('restricts shell-control channels to bundled local pages', async () => {
111-
const { invoke, on } = collectHandlers()
95+
it('restricts shell-control channels to bundled local pages', () => {
96+
const { on } = collectHandlers()
11297

11398
on.get('offline:retry')?.(appEvent)
11499
expect(deps.retryLoad).not.toHaveBeenCalled()
115100
on.get('offline:retry')?.(fileEvent)
116101
expect(deps.retryLoad).toHaveBeenCalledTimes(1)
117-
118-
on.get('settings:open')?.(evilEvent)
119-
expect(deps.openSettings).not.toHaveBeenCalled()
120-
on.get('settings:open')?.(fileEvent)
121-
expect(deps.openSettings).toHaveBeenCalledTimes(1)
122-
123-
expect(await invoke.get('settings:get')?.(appEvent)).toBeNull()
124-
expect(await invoke.get('settings:get')?.(fileEvent)).toEqual({
125-
origin: 'https://sim.ai',
126-
isDefault: true,
127-
})
128-
129-
expect(await invoke.get('settings:save')?.(appEvent, 'https://other.example')).toEqual({
130-
ok: false,
131-
error: 'Not allowed',
132-
})
133-
await invoke.get('settings:save')?.(fileEvent, 'https://other.example')
134-
expect(deps.applyOrigin).toHaveBeenCalledWith('https://other.example')
135102
})
136103

137104
it('handles a missing senderFrame safely', async () => {
138105
const { invoke } = collectHandlers()
139-
expect(await invoke.get('settings:get')?.({ senderFrame: null })).toBeNull()
106+
expect(await invoke.get('desktop:oauth-connect')?.({ senderFrame: null }, 'slack')).toBe(false)
107+
expect(deps.beginOAuthConnect).not.toHaveBeenCalled()
140108
})
141109

142110
it('restricts browser-agent tool execution to the app origin and known tools', async () => {
@@ -208,19 +176,4 @@ describe('registerIpcHandlers', () => {
208176
on.get('launcher:resize')?.(appEvent, 400)
209177
expect(deps.launcher.resize).toHaveBeenCalledWith(400)
210178
})
211-
212-
it('restricts launcher shortcut settings to bundled local pages', async () => {
213-
const { invoke } = collectHandlers()
214-
expect(await invoke.get('settings:launcher-shortcut-get')?.(appEvent)).toBeNull()
215-
expect(await invoke.get('settings:launcher-shortcut-get')?.(fileEvent)).toMatchObject({
216-
shortcut: 'Alt+Space',
217-
status: 'registered',
218-
})
219-
expect(await invoke.get('settings:launcher-shortcut-set')?.(appEvent, 'Control+Space')).toBe(
220-
null
221-
)
222-
expect(await invoke.get('settings:launcher-shortcut-set')?.(fileEvent, 42)).toBeNull()
223-
await invoke.get('settings:launcher-shortcut-set')?.(fileEvent, 'Control+Space')
224-
expect(deps.launcherShortcut.set).toHaveBeenCalledWith('Control+Space')
225-
})
226179
})

‎apps/desktop/src/main/ipc.ts‎

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import { isBrowserToolName } from '@sim/browser-protocol'
2-
import type { LauncherShortcutSettings } from '@sim/desktop-bridge'
32
import type { IpcMainEvent, IpcMainInvokeEvent } from 'electron'
43
import { ipcMain } from 'electron'
54
import { executeTool, handlePanelAction } from '@/main/browser-agent/driver'
65
import { setPanelBounds } from '@/main/browser-agent/session'
7-
import type { OriginValidation } from '@/main/config'
8-
import { DEFAULT_ORIGIN } from '@/main/config'
96
import type { LocalFilesystemService } from '@/main/local-filesystem'
107
import { openExternalSafe } from '@/main/navigation'
118

@@ -99,9 +96,6 @@ export interface IpcDeps {
9996
appOrigin: () => string
10097
allowHttpLocalhost: () => boolean
10198
retryLoad: () => void
102-
openSettings: () => void
103-
closeSettings: () => void
104-
applyOrigin: (raw: string) => Promise<OriginValidation>
10599
localFilesystem: LocalFilesystemService
106100
beginOAuthConnect: (providerId: string, scope: OAuthConnectScope) => Promise<boolean>
107101
launcher: {
@@ -110,16 +104,12 @@ export interface IpcDeps {
110104
hide: () => void
111105
resize: (height: number) => void
112106
}
113-
launcherShortcut: {
114-
get: () => LauncherShortcutSettings
115-
set: (shortcut: string) => LauncherShortcutSettings
116-
}
117107
}
118108

119109
/**
120110
* Who may call a channel:
121111
* - `app-origin`: only the remote app origin (main window / launcher pages).
122-
* - `local-page`: only bundled `file:` pages (settings, offline) — shell control.
112+
* - `local-page`: only bundled `file:` pages (offline) — shell control.
123113
* - `any`: sender-independent channels that validate their input instead.
124114
*/
125115
type ChannelGate = 'app-origin' | 'local-page' | 'any'
@@ -226,36 +216,6 @@ export function registerIpcHandlers(deps: IpcDeps): void {
226216
},
227217
},
228218
'offline:retry': { kind: 'send', gate: 'local-page', handler: () => deps.retryLoad() },
229-
'settings:open': { kind: 'send', gate: 'local-page', handler: () => deps.openSettings() },
230-
'settings:close': { kind: 'send', gate: 'local-page', handler: () => deps.closeSettings() },
231-
'settings:get': {
232-
kind: 'invoke',
233-
gate: 'local-page',
234-
denied: null,
235-
handler: () => {
236-
const origin = deps.appOrigin()
237-
return { origin, isDefault: origin === DEFAULT_ORIGIN }
238-
},
239-
},
240-
'settings:save': {
241-
kind: 'invoke',
242-
gate: 'local-page',
243-
denied: { ok: false, error: 'Not allowed' },
244-
handler: (raw) =>
245-
typeof raw === 'string' ? deps.applyOrigin(raw) : { ok: false, error: 'Not allowed' },
246-
},
247-
'settings:launcher-shortcut-get': {
248-
kind: 'invoke',
249-
gate: 'local-page',
250-
denied: null,
251-
handler: () => deps.launcherShortcut.get(),
252-
},
253-
'settings:launcher-shortcut-set': {
254-
kind: 'invoke',
255-
gate: 'local-page',
256-
denied: null,
257-
handler: (raw) => (typeof raw === 'string' ? deps.launcherShortcut.set(raw) : null),
258-
},
259219
'launcher:open-chat': {
260220
kind: 'send',
261221
gate: 'app-origin',

‎apps/desktop/src/main/settings-window.ts‎

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

0 commit comments

Comments
 (0)