diff --git a/src/renderer/src/components/editor/rich-markdown-editor-config.test.ts b/src/renderer/src/components/editor/rich-markdown-editor-config.test.ts index dd58ff40838..73c626a9ba8 100644 --- a/src/renderer/src/components/editor/rich-markdown-editor-config.test.ts +++ b/src/renderer/src/components/editor/rich-markdown-editor-config.test.ts @@ -1,7 +1,7 @@ import type { Dispatch, MutableRefObject, SetStateAction } from 'react' import type { Editor } from '@tiptap/react' import type { DocLinkMenuState } from './rich-markdown-commands' -import { describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest' import type { LinkBubbleState } from './RichMarkdownLinkBubble' import { createRichMarkdownEditorConfig, @@ -88,6 +88,10 @@ function createConfigParams(overrides: Partial = {}): Editor } describe('createRichMarkdownEditorConfig', () => { + afterEach(() => { + vi.unstubAllGlobals() + }) + it('disables browser spellcheck when the rich Markdown setting is off', () => { const config = createRichMarkdownEditorConfig( createConfigParams({ richMarkdownSpellcheckEnabled: false }) @@ -101,4 +105,22 @@ describe('createRichMarkdownEditorConfig', () => { expect(getSpellcheckAttribute(config)).toBe('true') }) + + it('flushes pending serialization when the rich editor blurs', () => { + const setMarkdownEditorFocused = vi.fn() + vi.stubGlobal('window', { + api: { ui: { setMarkdownEditorFocused } } + }) + const flushPendingSerialization = vi.fn() + const clearAnnotationTarget = vi.fn() + const config = createRichMarkdownEditorConfig( + createConfigParams({ clearAnnotationTarget, flushPendingSerialization }) + ) + + config.onBlur?.({} as never) + + expect(setMarkdownEditorFocused).toHaveBeenCalledWith(false) + expect(clearAnnotationTarget).toHaveBeenCalledOnce() + expect(flushPendingSerialization).toHaveBeenCalledOnce() + }) }) diff --git a/src/renderer/src/components/editor/rich-markdown-editor-config.ts b/src/renderer/src/components/editor/rich-markdown-editor-config.ts index 5c0f93b69f1..275720cb5ab 100644 --- a/src/renderer/src/components/editor/rich-markdown-editor-config.ts +++ b/src/renderer/src/components/editor/rich-markdown-editor-config.ts @@ -204,6 +204,7 @@ export function createRichMarkdownEditorConfig(params: EditorConfigParams): UseE onBlur: () => { window.api.ui.setMarkdownEditorFocused(false) clearAnnotationTarget() + params.flushPendingSerialization() }, onCreate: ({ editor: nextEditor }) => { // Why: normalizeEmptyListItems (not normalizeSoftBreaks) so hard-wrapped diff --git a/src/renderer/src/components/terminal-pane/terminal-pane-recovery.test.ts b/src/renderer/src/components/terminal-pane/terminal-pane-recovery.test.ts index 51ccff40901..52d82ead7bb 100644 --- a/src/renderer/src/components/terminal-pane/terminal-pane-recovery.test.ts +++ b/src/renderer/src/components/terminal-pane/terminal-pane-recovery.test.ts @@ -35,7 +35,7 @@ beforeEach(() => { vi.stubGlobal('window', { api: { pty: { hasPty: mocks.hasPty } } }) - vi.spyOn(console, 'error').mockImplementation(() => {}) + vi.spyOn(console, 'warn').mockImplementation(() => {}) }) afterEach(() => { diff --git a/src/renderer/src/components/terminal-pane/terminal-pane-recovery.ts b/src/renderer/src/components/terminal-pane/terminal-pane-recovery.ts index ca3d23daede..cecf4497fb0 100644 --- a/src/renderer/src/components/terminal-pane/terminal-pane-recovery.ts +++ b/src/renderer/src/components/terminal-pane/terminal-pane-recovery.ts @@ -276,7 +276,10 @@ export async function requestTerminalPaneRecovery(request: RecoveryRequest): Pro // would suppress input on a pane that never recovered. armTerminalInputQuarantine(request.tabId) } - console.error( + // warn, not error: this is the recovery succeeding, and the breadcrumb below is + // what diagnostics actually read. STA-2373 made this path routine (every daemon + // death remounts each live pane), so error level just floods the logs. + console.warn( `[terminal] recovering pane tab ${request.tabId} — ${request.reason} with a live PTY (${request.ptyId ?? 'unbound'}); remounting to rebuild the renderer` ) recordRendererCrashBreadcrumb('terminal_pane_recovery_remount', {