From ece81a2b717cf4f182e41923b86fcbf45c02ae78 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 3 May 2026 11:57:51 +0200 Subject: [PATCH] feat(desktop): add recovery bridge methods to preload + types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rendererReady (boot-completion ping) - getRecoveryState / onRecoveryStateChanged (recovery.html subscribers) - recoveryAction (button click dispatcher with enum action) Type declarations kept ambient (no export) to preserve window.backspace global augmentation — exporting from an ambient .d.ts converts it to a module and breaks the Window interface extension. --- packages/desktop/src/preload.ts | 19 +++++++++++++++++++ packages/web/src/platform/electron.d.ts | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/packages/desktop/src/preload.ts b/packages/desktop/src/preload.ts index ee48b765..35730519 100644 --- a/packages/desktop/src/preload.ts +++ b/packages/desktop/src/preload.ts @@ -107,4 +107,23 @@ contextBridge.exposeInMainWorld('backspace', { return () => { ipcRenderer.removeListener('keybind-hook-error', handler); }; }, checkAccessibility: () => ipcRenderer.invoke('check-accessibility'), + + // Recovery mode bridge (Task 11) + rendererReady: (): void => { + ipcRenderer.send('renderer-ready'); + }, + + getRecoveryState: (): Promise => { + return ipcRenderer.invoke('get-recovery-state'); + }, + + onRecoveryStateChanged: (cb: (state: unknown) => void): (() => void) => { + const handler = (_e: Electron.IpcRendererEvent, state: unknown) => cb(state); + ipcRenderer.on('recovery-state-changed', handler); + return () => { ipcRenderer.removeListener('recovery-state-changed', handler); }; + }, + + recoveryAction: (action: string): void => { + ipcRenderer.send('recovery-action', action); + }, }); diff --git a/packages/web/src/platform/electron.d.ts b/packages/web/src/platform/electron.d.ts index add4bca8..e6437147 100644 --- a/packages/web/src/platform/electron.d.ts +++ b/packages/web/src/platform/electron.d.ts @@ -1,5 +1,24 @@ /** Type augmentation for the Electron IPC bridge exposed by preload.ts */ +// Recovery mode types (Task 11) +type RecoveryReasonCode = 'load-failed' | 'render-gone' | 'unresponsive' | 'renderer-stalled'; +type UpdateState = 'idle' | 'checking' | 'downloading' | 'downloaded' | 'error'; +interface RecoveryState { + mode: 'normal' | 'recovery'; + reason: { code: RecoveryReasonCode; detail: string } | null; + updateState: UpdateState; + updateVersion: string | null; + lastUpdateError: { message: string; code: string | null; at: number } | null; + lastCheckResult: 'up-to-date' | 'failed' | null; +} +type RecoveryAction = + | 'reload' + | 'check-update' + | 'install-update' + | 'change-instance' + | 'open-releases' + | 'quit'; + interface ElectronScreenSource { id: string; // "screen:0:0" or "window:12345:0" name: string; // "Entire Screen" or "Firefox" @@ -63,6 +82,12 @@ interface BackspaceElectronAPI { onAccessibilityStatus: (callback: (status: { trusted: boolean }) => void) => (() => void); onKeybindHookError: (callback: (error: { message: string }) => void) => (() => void); checkAccessibility: () => Promise; + + // Recovery mode bridge (Task 11) + rendererReady: () => void; + getRecoveryState: () => Promise; + onRecoveryStateChanged: (cb: (state: RecoveryState) => void) => () => void; + recoveryAction: (action: RecoveryAction) => void; } interface Window {