feat(chat): 回复末尾「已编辑文件」卡片——文件引用富渲染,支持打开文件 / 文件树定位 / 查看 Diff#200
Merged
Conversation
…e actions Co-authored-by: Cursor <cursoragent@cursor.com>
Bsyy95
force-pushed
the
feat/changed-files-card
branch
from
July 21, 2026 10:17
eb39c05 to
b82d1f1
Compare
…-type icons, two-line header, scrollable list Co-authored-by: Cursor <cursoragent@cursor.com>
…e transcript Add overscroll-contain to the card's inner scroll container in both frontends; also restore the web copy's comment that had been mojibake-corrupted in the previous commit.
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.
背景
Agent 一轮回复里改了哪些文件,目前只能逐个展开 Write/Edit 工具卡片查看。这个 PR 为消息渲染补上"文件引用"这层富交互:在 Agent 回复末尾展示一张可交互的「已编辑 N 个文件」卡片(类似 Cursor 的 Changed Files 卡),并让工具卡片里的文件路径变为可点击的文件引用。
功能
回复末尾的 Changed Files 卡片(GUI + WebUI 双端):
Write/Edit/Delete成功结果:按路径去重(跨 round 合并、忽略正反斜杠与大小写漂移),每个文件复用与工具栏折叠徽标同一 diff 引擎的 +增/−删行数,头部显示总计;Delete标记「已删除」,其后再Write视为重建redactToolContent时不渲染卡片;无动作上下文时降级为纯数据列表文件引用可点击:Write/Edit 工具卡片展开后的
path字段变为可点击引用,点击直接打开工作区编辑器(与卡片同一动作通道)。实现方式
lib/chat/.../changedFiles.ts(双端同内容):纯函数collectChangedFiles(rounds),路径取toolResult.details.displayPath → relativePath → path → arguments.path;行数复用现有deriveFileChangeStats(真 diff + 截断回退),并用 WeakMap 缓存每个 toolCall 的 diff,流式期间零重复计算components/chat/ChangedFilesCard.tsx(双端同内容):卡片 +ChangedFilesActionsContext——动作经 React context 注入而非 props 下钻,转录行的 memo 边界零改动RightDockContext新增git.focusRequest { path, nonce } / onFocusRequestHandled;RightDockPanel透传新 props;useGitReviewData在面板激活且仓库状态就绪后切到 changes 视图并selectPath(path)加载该文件 diff,用 handled 回调 retire 请求,保证换项目/重挂载后绝不重放openRightDockSingletonTab("fileTree")+updateRightDockFileTreeState({ selectedPath, expandedPaths: 现有∪祖先, bumpRevision }),与 Git Review 面板里的 "Reveal in File Tree" 行为一致ChatPage/GatewayApp各自注入三个动作(打开文件走既有handleOpenWorkspaceFile),并挂载 Provider 包住转录组件变更清单
crates/{agent-gui/src/lib/chat/messages,agent-gateway/web/src/lib/chat}/changedFiles.tscrates/{agent-gui,agent-gateway/web}/src/components/chat/ChangedFilesCard.tsxAssistantBubble(双端):回复末尾挂载卡片;FileToolArgs(双端):路径可点击RightDockContext.tsx/RightDockPanel.tsx/git-review/useGitReviewData.ts(聚焦通道,字节级同步)ChatPage.tsx/GatewayApp.tsx:动作接线 + Provider + gitReview 聚焦状态chat.changedFiles.*)changed-files.test.mjs(5 例:跨 round 聚合与合计、失败/未完成剔除、Delete 标记与重建、参数回退、displayPath 优先与去重)+ WebUIchanged-files.test.mjs(双端契约一致性)验证
pnpm build/pnpm lint(0 错误)/pnpm test:frontend(1071 全过,含新增 5 例)pnpm build/pnpm lint(0 错误)/pnpm test(368 全过,含新增 1 例)node scripts/check-mirror.mjs(87 个镜像文件一致);git diff --check干净;未改动 Rust / Go基点说明
分支基于 #178 合并点切出(提交用的 PAT 无
workflowscope,无法把上游后续含 CI 工作流的提交推到 fork)。git merge-tree与最新main预演:与 #190(stream-retry details)在crates/agent-gui/.../AssistantBubble.tsx和crates/agent-gateway/web/src/app/GatewayApp.tsx各有一处相邻插入的轻微文本冲突(import/props 追加,均 <10 行),其余文件干净。fork 的 main 同步后我可以随时 rebase 重推消除冲突,也欢迎在合并时顺手解决。已知边界