()
| 560 | }; |
| 561 | |
| 562 | const restartSidecarAndReload = async (): Promise<DesktopServerConnection> => { |
| 563 | // A supervised daemon owns its own process lifetime. Re-installing the unit |
| 564 | // rewrites settings such as the configured port, then launchd restarts it. |
| 565 | if (connection?.supervisedDaemon) { |
| 566 | const port = getServerSettings().port; |
| 567 | await installSupervisedService({ |
| 568 | port, |
| 569 | dataDir: DESKTOP_DATA_DIR, |
| 570 | }); |
| 571 | const next = await waitForSupervisedAttach(30_000, { port }); |
| 572 | if (!next) { |
| 573 | // oxlint-disable-next-line executor/no-error-constructor, executor/no-try-catch-or-throw -- boundary: surfaces to renderer as a rejected IPC call |
| 574 | throw new Error("Supervised daemon failed to restart — see Settings"); |
| 575 | } |
| 576 | connection = next; |
| 577 | installBearerAuthHeader(next.baseUrl, next.authToken); |
| 578 | const window = liveMainWindow(); |
| 579 | if (window) await window.loadURL(webUrlForConnection(next)); |
| 580 | return toDesktopServerConnection(next); |
| 581 | } |
| 582 | if (connection) { |
| 583 | await stopConnection(connection); |
| 584 | connection = null; |
| 585 | } |
| 586 | const next = await startWithCurrentSettings(); |
| 587 | if (!next) { |
| 588 | // oxlint-disable-next-line executor/no-try-catch-or-throw, executor/no-error-constructor -- boundary: surfaces to renderer as a rejected IPC call |
| 589 | throw new Error("Sidecar failed to restart — see Settings"); |
| 590 | } |
| 591 | connection = next; |
| 592 | // A restart can adopt a daemon that already owns the data dir (the |
| 593 | // attach-on-conflict fallback). An adopted daemon has no child process, so |
| 594 | // onUnexpectedSidecarExit can't see it die — watch it with the supervised |
| 595 | // monitor instead. A freshly spawned sidecar keeps the child-exit path. |
| 596 | if (next.supervisedDaemon) armSupervisedMonitor(); |
| 597 | else stopSupervisedMonitor(); |
| 598 | installBearerAuthHeader(next.baseUrl, next.authToken); |
| 599 | const window = liveMainWindow(); |
| 600 | if (window) await window.loadURL(webUrlForConnection(next)); |
| 601 | return toDesktopServerConnection(next); |
| 602 | }; |
| 603 | |
| 604 | // The renderer's connection carries NO auth: the main process injects the |
| 605 | // bearer header at the session layer (installBearerAuthHeader), so the token |
no test coverage detected