From f37b9f63d3d1aae4b012af0ee40eafab48c24fc0 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Wed, 29 Jul 2026 20:39:54 -0700 Subject: [PATCH 1/2] fix(terminal): log pane recovery at warn, not error (#10796) * fix(terminal): log pane recovery at warn, not error STA-2373 made this path routine: every daemon death now remounts each live pane, so error level floods logs and crash telemetry with a message that reports recovery *succeeding*. The breadcrumb right below is what diagnostics actually consume. * fix(terminal): correct recovery log comment and test console spy The comment claimed error level floods telemetry; nothing forwards renderer console into telemetry, and the breadcrumb below is untouched, so this change alters telemetry volume by zero. The test's console.error spy silenced the old call site and now stubs nothing, leaking 26 stderr lines under verbose. --- .../components/terminal-pane/terminal-pane-recovery.test.ts | 2 +- .../src/components/terminal-pane/terminal-pane-recovery.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) 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', { From 38e95817583c594b48932b6bfdf92bd92f22dd81 Mon Sep 17 00:00:00 2001 From: Rod Boev Date: Wed, 29 Jul 2026 23:46:26 -0400 Subject: [PATCH 2/2] fix(editor): save rich-markdown preview edits on blur, switch, and quit before the serialize debounce (#9730) (#9823) * fix(editor): flush markdown preview saves before teardown (#9730) * fix(editor): keep rich markdown blur saves policy-safe --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> --- .../rich-markdown-editor-config.test.ts | 24 ++++++++++++++++++- .../editor/rich-markdown-editor-config.ts | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) 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