fix(desktop): attachments on Enter, IME composition, scroll, fetchJson resets (salvage #38502) - #38677
Merged
Conversation
…fetchJson
DC2: Pass attachments to onSubmit() on direct Enter submit and call
clearComposerAttachments(). Previously attachments were silently
dropped — only text was sent while attachment pills remained visible.
DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps.
When the disclosure toggles, refs point to new DOM but the observer
wasn't reattached, breaking live-scroll preview after expand/collapse
and leaking detached DOM nodes.
DH3+DH4: Add composition tracking via composingRef (set by
compositionstart/compositionend). Guards handleEditorInput (skip
preedit state writes), handleEditorKeyDown (prefer composingRef over
unreliable isComposing), and form onSubmit (prevent IME Enter from
triggering submission). Fixes IME Enter message splitting and preedit
text leaking into app state on CJK input.
DH6: Add res.on('error', reject) to fetchJson response stream.
Without this, a TCP reset mid-transfer left the promise hanging forever,
freezing the desktop UI.
All TypeScript compiles cleanly.
…g writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair.
…connection config cache
DM9: Guard nativeTheme.on('updated') with a one-shot flag so that
multiple createWindow() calls (e.g. macOS activate after all windows
closed) don't accumulate duplicate listeners on the process-wide
singleton.
DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig.
Previously the cache was populated once and never invalidated — if an
external tool modified connection.json, the desktop ignored the change
until restart. Now re-reads when the file's mtime differs.
… JSX props Follow-up to salvaged #38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer).
Contributor
🔎 Lint report:
|
Yuki-14544869
pushed a commit
to Yuki-14544869/hermes-agent
that referenced
this pull request
Jun 4, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
davidgut1982
pushed a commit
to davidgut1982/hermes-agent
that referenced
this pull request
Jun 5, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
1 task
changman
pushed a commit
to changman/hermes-agent
that referenced
this pull request
Jun 10, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
alt-glitch
pushed a commit
that referenced
this pull request
Jun 14, 2026
…n resets (salvage #38502) (#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged #38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
kossteg
pushed a commit
to kossteg/hermes-agent
that referenced
this pull request
Jun 16, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
T02200059
pushed a commit
to T02200059/hermes-agent
that referenced
this pull request
Jun 18, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
donbowman
pushed a commit
to donbowman/hermes-agent
that referenced
this pull request
Jul 13, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
…n resets (salvage NousResearch#38502) (NousResearch#38677) * fix(desktop): critical fixes — attachments, IME composition, scroll, fetchJson DC2: Pass attachments to onSubmit() on direct Enter submit and call clearComposerAttachments(). Previously attachments were silently dropped — only text was sent while attachment pills remained visible. DH1: Add 'open' to ThinkingDisclosure ResizeObserver effect deps. When the disclosure toggles, refs point to new DOM but the observer wasn't reattached, breaking live-scroll preview after expand/collapse and leaking detached DOM nodes. DH3+DH4: Add composition tracking via composingRef (set by compositionstart/compositionend). Guards handleEditorInput (skip preedit state writes), handleEditorKeyDown (prefer composingRef over unreliable isComposing), and form onSubmit (prevent IME Enter from triggering submission). Fixes IME Enter message splitting and preedit text leaking into app state on CJK input. DH6: Add res.on('error', reject) to fetchJson response stream. Without this, a TCP reset mid-transfer left the promise hanging forever, freezing the desktop UI. All TypeScript compiles cleanly. * chore: add copii.list@gmail.com to AUTHOR_MAP (stremtec) * fix(desktop): prevent scroll snap-back during streaming, atomic config writes DH2: Defer pinToBottom() in useLayoutEffect to rAF so that browser scroll/wheel events from the current frame are processed first. Previously an immediate pinToBottom() could snap the viewport back to bottom against the user's trackpad scroll-up intent during streaming — the wheel event hadn't fired yet so stickyBottomRef was still true. DH7: Add writeFileAtomic() helper (write to .tmp then rename) and use it in writeDesktopConnectionConfig, writeDesktopUpdateConfig, and writeBootstrapMarker. Prevents partial writes on crash/power loss that would corrupt JSON config files, requiring manual repair. * fix(desktop): guard nativeTheme listener from duplicates, invalidate connection config cache DM9: Guard nativeTheme.on('updated') with a one-shot flag so that multiple createWindow() calls (e.g. macOS activate after all windows closed) don't accumulate duplicate listeners on the process-wide singleton. DM3: Add mtime-based cache invalidation to readDesktopConnectionConfig. Previously the cache was populated once and never invalidated — if an external tool modified connection.json, the desktop ignored the change until restart. Now re-reads when the file's mtime differs. * fix(desktop): widen fetchJson res.on('error') to sibling fetch + sort JSX props Follow-up to salvaged NousResearch#38502: - resourceBufferFromUrl had the same mid-stream-reset hang class as fetchJson (req.on('error') present, res.on('error') missing). Add the response-stream error handler so a TCP reset during body read rejects instead of leaving the promise unsettled. - Sort the new onComposition* JSX props to satisfy perfectionist/sort-jsx-props (was an introduced eslint error in the composer). --------- Co-authored-by: asill-livestream <copii.list@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvages @stremtec's desktop bug-fix batch (#38502) onto current main, plus a follow-up that widens one of the fixes to a sibling code path and clears an introduced lint error.
Six+ real, user-facing desktop bugs — all verified still present on main before salvage.
Changes (contributor — @stremtec)
{ attachments }+clearComposerAttachments()on the direct Enter-submit path (attachments were silently dropped while pills stayed visible)composingRef(compositionstart/end) guarding input handler, keydown, and form submit — fixes CJK preedit polluting drafts and Enter splitting messages mid-wordopento the ResizeObserver effect deps so the scroll-pin observer re-attaches after disclosure expand/collapsepinToBottom()to rAF so a trackpad scroll-up during streaming isn't snapped backres.on('error', reject)onfetchJson(mid-stream TCP reset no longer freezes the UI)writeFileAtomic()(temp+rename) for connection/update/bootstrap config writes — no more partial-JSON corruption on crashFollow-up (ours)
resourceBufferFromUrlhad the same mid-stream-reset hang class asfetchJson(req.on('error')present,res.on('error')missing). Added the response-stream handler so a reset during body read rejects instead of hanging.onComposition*JSX props (introducedperfectionist/sort-jsx-propserror).Validation
tsc -b: cleaneslinton changed files: 0 errors (only pre-existing repo-wide style warnings remain)Closes #38502. Contributor authorship preserved per-commit.
Infographic