diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index 1a9d28c5e..289a62b7c 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -6965,6 +6965,7 @@ async function startHermes() { } const message = error instanceof Error ? error.message : String(error) + // Only latch LOCAL boot failures. A remote failure (lapsed session / mint // timeout / host briefly unreachable across sleep) is transient and has no // child 'exit' handler to clear the cache — latching it would wedge the app @@ -6973,6 +6974,7 @@ async function startHermes() { if (shouldLatchBackendStartFailure({ attemptedRemote })) { backendStartFailure = error instanceof Error ? error : new Error(message) } + updateBootProgress( { error: message, diff --git a/apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx b/apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx index 46fc10290..f27d7fa46 100644 --- a/apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx +++ b/apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx @@ -106,7 +106,9 @@ function Harness({ activeSessionId?: null | string createBackendSessionForSend?: () => Promise }) { - const localActiveSessionIdRef = useRef(activeSessionId === undefined ? RUNTIME_SESSION_ID : activeSessionId) + const localActiveSessionIdRef = useRef( + activeSessionId === undefined ? RUNTIME_SESSION_ID : activeSessionId + ) const activeSessionIdRef = activeSessionIdRefProp ?? localActiveSessionIdRef const selectedStoredSessionIdRef: MutableRefObject = selectedStoredSessionIdRefProp ?? { @@ -162,7 +164,14 @@ function Harness({ submitText: (...args: Parameters) => act(async () => actions.submitText(...args)) as Promise }) - }, [actions.cancelRun, actions.restoreToMessage, actions.steerPrompt, actions.submitText, activeSessionIdRef, onReady]) + }, [ + actions.cancelRun, + actions.restoreToMessage, + actions.steerPrompt, + actions.submitText, + activeSessionIdRef, + onReady + ]) return null } @@ -553,7 +562,8 @@ describe('usePromptActions submit / queue drain semantics', () => { it('a fromQueue drain sends to its queued session even after the active session changes', async () => { $busy.set(false) - const updates: { sessionId: string; state: Record; storedSessionId: null | string | undefined }[] = [] + const updates: { sessionId: string; state: Record; storedSessionId: null | string | undefined }[] = + [] const requestGateway = vi.fn(async () => ({}) as never) let handle: HarnessHandle | null = null @@ -1224,7 +1234,10 @@ describe('usePromptActions sleep/wake session recovery', () => { expect(ok).toBe(true) expect(calls.map(c => c.method)).toEqual(['prompt.submit', 'session.resume', 'prompt.submit']) - expect(calls[0]?.params).toEqual({ session_id: 'rt-background-stale', text: 'queued background message after wake' }) + expect(calls[0]?.params).toEqual({ + session_id: 'rt-background-stale', + text: 'queued background message after wake' + }) expect(calls[1]?.params).toEqual({ session_id: STORED_SESSION_ID, source: 'desktop' }) expect(calls[2]?.params).toEqual({ session_id: RECOVERED_SESSION_ID, diff --git a/apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts b/apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts index a973f82f4..709652dce 100644 --- a/apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts +++ b/apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts @@ -462,10 +462,7 @@ export function useSubmitPrompt(deps: SubmitPromptDeps) { } catch (firstErr) { const recoverStoredSessionId = targetStoredSessionId ?? selectedStoredSessionIdRef.current - if ( - (isSessionNotFoundError(firstErr) || isGatewayTimeoutError(firstErr)) && - recoverStoredSessionId - ) { + if ((isSessionNotFoundError(firstErr) || isGatewayTimeoutError(firstErr)) && recoverStoredSessionId) { // Re-register the session in the gateway and get a fresh live ID. // Timeouts recover the same way as "session not found": a starved // backend loop (#55578 symptom d) rejects the submit even though