fix: ai-agent UI polish, xterm crash guard & window/milkdown fixes#3987
Merged
Conversation
…lue gradient bars - Remove @react-three/fiber / three.js (incompatible with React 18, added 900KB) - Add src/components/react-bits/memfit-animated-bg.tsx: pure Canvas 2D implementation of the flowing vertical blue gradient bars animation, matching the memfit palette (#4373BB light / #66A2EB dark), infinite loop via requestAnimationFrame, no deps - Support both light and dark themes; theme switch reacts instantly via ref - Remove the two memfit-right.webm video assets from bundle - Commit built dist/ so teammates can use without re-building (dist removed from .gitignore) - Fix pre-existing TS error: onOkText -> okText in SoftwareBasics Bundle JS: 4.5MB -> 3.6MB (gzip 1.24GB -> 986KB) Co-authored-by: Cursor <cursoragent@cursor.com>
…imated blue gradient bars" This reverts commit 55c8292.
Contributor
PR CI 汇总状态:全部通过
由 pull_request test workflow 自动生成 |
- aiAgent.json: shorten AIAgentTabs.historyChat / HistoryChat.title to "历史" for compactness - ToolInvokerCard: enlarge copy button to 22x22 with centered icon, move padding into CSS; drop inline style on the duplicate icon - HistoryChat: wrap title in a span with ellipsis (nowrap + truncate) so long titles no longer break layout
修复 xterm.js 在 renderer 未就绪时 reset/resize 抛 "Cannot read properties of undefined (reading 'dimensions')" 的问题: - xtermUtils(renderer + engine-link-startup): 新增 isTerminalReady() 守卫(element + _renderService.hasRenderer), xtermFit/xtermClear 改用守卫并 try/catch 包裹 resize/reset - YakitXterm: open() 后 fit() 延后一帧(requestAnimationFrame)执行 并 try/catch, 规避 Viewport.syncScrollArea 时序竞态 - TerminalBox: 两处直接 terminal.reset() 改走安全的 xtermClear()
…arning
- main/index.js: 窗口默认尺寸从 minWidth/minHeight(900x650)改为更合理的
默认值 1400x880, minWidth/minHeight 仍作为下限兜底
- aiMilkdownInput/utils: setEditorValue 增加 view?.isDestroyed 守卫,
防止对已销毁的 prosemirror view dispatch
- AIReActChat: 切换会话时 setValue('') 用 queueMicrotask 延后执行,
规避 Milkdown/prosemirror-adapter 内部 flushSync 撞上 React 渲染周期
的警告, 并加 cancelled 守卫防止卸载后写入
Contributor
There was a problem hiding this comment.
Pull request overview
This PR consolidates several renderer/main-process stability and UI refinements across the AI Agent experience, xterm terminal integration, window sizing defaults, and Milkdown editor lifecycle safety.
Changes:
- Harden xterm operations (fit/resize/reset) against renderer-not-ready/disposed timing to prevent UI crashes, and route terminal clears through guarded helpers.
- Improve AI Agent UI presentation (tool-call output compaction, history title truncation, copy affordances) and reduce Milkdown-related React flushSync warnings via deferred updates.
- Adjust Electron window default size while preserving minimum constraints; add BrowserWindow/webContents destroyed guards in IPC stream send paths.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| app/renderer/src/main/src/utils/xtermUtils.ts | Adds isTerminalReady() and wraps reset/resize with guards/try-catch to avoid xterm render-service crash conditions. |
| app/renderer/engine-link-startup/src/utils/xtermUtils.ts | Mirrors the xterm safety guards in engine-link-startup utilities. |
| app/renderer/src/main/src/pages/yakRunner/BottomEditorDetails/TerminalBox/TerminalBox.tsx | Switches direct terminal.reset() calls to guarded xtermClear() usage. |
| app/renderer/src/main/src/components/yakitUI/YakitXterm/YakitXterm.tsx | Defers fit() until the next animation frame after open() to avoid renderer timing crashes. |
| app/renderer/src/main/src/pages/ai-re-act/aiReActChat/AIReActChat.tsx | Defers editor value reset with queueMicrotask + cancellation guard to avoid flushSync warnings during session switches. |
| app/renderer/src/main/src/pages/ai-agent/components/aiMilkdownInput/utils.ts | Adds a destroyed-view guard before dispatching editor transactions. |
| app/renderer/src/main/src/pages/ai-agent/historyChat/HistoryChat.tsx | Wraps title text for truncation to prevent overflow. |
| app/renderer/src/main/src/pages/ai-agent/historyChat/HistoryChat.module.scss | Adds .title-text styles for nowrap/ellipsis truncation behavior. |
| app/renderer/src/main/src/pages/ai-agent/components/ToolInvokerCard.tsx | Refactors tool result rendering into a compact “pseudo-terminal” view and adds params modal/copy interactions. |
| app/renderer/src/main/src/pages/ai-agent/components/ToolInvokerCard.module.scss | Updates styles to match the new tool output/params UI (border/status styling, copy button sizing/positioning). |
| app/renderer/src/main/src/pages/ai-agent/components/aiGroupStreamCard/AIGroupStreamCard.tsx | Wraps group card in a tooltip and adjusts layout for expand/collapse interactions. |
| app/renderer/src/main/src/pages/ai-agent/chatTemplate/AIAgentChatTemplate.module.scss | Adjusts footer padding to improve layout/spacing. |
| app/renderer/src/main/public/locales/zh/aiAgent.json | Simplifies “历史会话” labeling to “历史” in relevant keys. |
| app/main/index.js | Updates default window dimensions while keeping min constraints. |
| app/main/handlers/yakRunnerTerminal.js | Adds destroyed-window/webContents guards before sending terminal IPC events. |
| app/main/handlers/handleStreamWithContext.js | Adds destroyed-window/webContents guards for generic stream event forwarding. |
Comment on lines
+463
to
+465
| <span className={styles['params-json']} onClick={() => setOpen(true)} title={jsonStr}> | ||
| {jsonStr} | ||
| </span> |
Comment on lines
+462
to
+470
| <span className={styles['params-label']}>Params:</span> | ||
| <span className={styles['params-json']} onClick={() => setOpen(true)} title={jsonStr}> | ||
| {jsonStr} | ||
| </span> | ||
| </div> | ||
| <YakitModal | ||
| visible={open} | ||
| title="Params" | ||
| onCancel={() => setOpen(false)} |
Comment on lines
+177
to
+180
| const collapseTooltip = !expand && elements.length > 1 ? `折叠${elements.length}条信息` : '' | ||
|
|
||
| return ( | ||
| <div | ||
| className={classNames(styles.container, { | ||
| [styles['container-focus']]: isFocus, | ||
| })} | ||
| ref={containerRef} | ||
| > | ||
| <Tooltip title={collapseTooltip} mouseEnterDelay={0.3}> |
Defer YakitXterm resize fits via requestAnimationFrame with isTerminalReady checks, and avoid calling setValue when the chat textarea ref is unavailable. Co-authored-by: Cursor <cursoragent@cursor.com>
b1rdfree
approved these changes
Jul 13, 2026
EmbraceAn
approved these changes
Jul 13, 2026
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
本 PR 汇总渲染端若干修复:AI Agent 对话模块的 UI 体验优化、xterm.js 终端崩溃修复、窗口默认尺寸调整、Milkdown 编辑器卸载守卫与 flushSync 警告修复;并包含 memfit 启动右栏动画的实验性增改与回退。
改动内容 / What changed
fix: window default size, milkdown destroyed-view guard & flushSync warningsetEditorValue增加view?.isDestroyed守卫,避免对已销毁 view dispatch。flushSync 警告:AIReActChat切换会话时setValue('')用queueMicrotask延后执行,规避 Milkdown/prosemirror-adapter 内部 flushSync 撞上 React 渲染周期,并加 cancelled 守卫。fix(xterm): guard reset/resize against renderer-not-ready crashCannot read properties of undefined (reading 'dimensions'):xtermUtils(renderer + engine-link-startup)新增isTerminalReady()守卫并 try/catch 包裹resize/reset;YakitXterm的open()后fit()延后一帧(requestAnimationFrame)执行;TerminalBox两处直接terminal.reset()改走安全的xtermClear()。fix(ai-agent): refine ToolInvokerCard copy btn & history chat overflowright:24px、hover 背景;json 容器右内边距 28px 防遮挡;SVG 尺寸收敛 13×13;移除<OutlineDocumentduplicateIcon>内联 style。历史标题:新增.title-text(nowrap + ellipsis),标题包<span>截断。文案:historyChat/HistoryChat.title精简为「历史」。improve toolcall compact and chat groupfeat(memfit)+Revert产生影响 / Impact
_renderService.dimensions未就绪而抛错崩溃;reset/resize 失败被安全吞掉,后续 resize 监听会补偿。如何测试 / How to test
app/renderer/src/main下yarn electron-render。yakit-window-state.json后冷启动,确认默认窗口为 1400×880 且不能缩到小于 900×650。isDestroyed报错、无 flushSync 警告。dimensions报错或白屏;切换缓存会话确认xtermClear+writeXTerm正常回填。