(conn: SidecarConnection)
| 547 | }; |
| 548 | |
| 549 | const createWindow = async (conn: SidecarConnection) => { |
| 550 | installBearerAuthHeader(conn.baseUrl, conn.authToken); |
| 551 | |
| 552 | const existingWindow = liveMainWindow(); |
| 553 | const window = existingWindow ?? createMainBrowserWindow({ show: false }); |
| 554 | |
| 555 | // A supervised daemon can pass the health probe and still disappear before |
| 556 | // navigation begins. Treat that as a failed connection instead of leaving the |
| 557 | // user with a visible BrowserWindow that only shows the black background. |
| 558 | // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: Electron navigation rejects when the sidecar vanishes during startup |
| 559 | try { |
| 560 | await window.loadURL(webUrlForConnection(conn)); |
| 561 | if (!window.isDestroyed() && !window.isVisible()) window.show(); |
| 562 | } catch (error) { |
| 563 | log.error("Failed to load Executor web UI", error); |
| 564 | if (!existingWindow) destroyWindow(window); |
| 565 | // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: caller decides whether to fall back or surface startup failure |
| 566 | throw error; |
| 567 | } |
| 568 | }; |
| 569 | |
| 570 | const showPortInUseDialog = async (port: number) => { |
| 571 | await dialog.showMessageBox({ |
no test coverage detected