Skip to content

feat(agent): 显示 Agent 思考、计划与斜杠命令补全 - #1016

Merged
1lck merged 6 commits into
1lck:previewfrom
Mucheen:feat/agent-acp-session-updates
Oct 2, 2026
Merged

1lck merged 6 commits into
1lck:previewfrom
Mucheen:feat/agent-acp-session-updates

Conversation

@Mucheen

@Mucheen Mucheen commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

概述

参考 jetbrains-cc-gui 的对话体验,补齐 macOS Agent 面板对四类标准 ACP 会话更新的展示:思考过程、执行计划、斜杠命令补全、模式同步。

共享 Host(lithe-agent-host)一直把 ACP SessionUpdate 原样转发给 Swift,但 AgentConnectionModel.apply 之前只处理消息、工具、标题、配置和用量,下面这四类更新都落进 default: break 被丢弃了。本 PR 不改 Rust Host、C ABI 或 fixture 结构,只在 macOS 功能模型和视图层补上解析与展示。

改动内容

1. 思考块(agent_thought_chunk)

  • 新增消息角色 .thought,思考内容单独成一条消息,不再并入 Agent 回复。
  • 流式缓冲从“每会话一段文本”改为“每会话一段 + 角色”:角色切换时先刷新上一段,所以“思考 → 回复 → 工具 → 思考”交替到达时顺序正确、文本不会混在一起。
  • 新视图 AgentThoughtRow:正在流式输出的最后一段思考默认展开(显示“思考中…”),回复或工具到达后自动收起为“思考过程”;用户手动展开/收起后保持;搜索命中时临时展开,即使此前手动收起也能看到命中文字,搜索期间保持可见,清空搜索后恢复原来的手动选择。偏好由对话视图按会话 ID+消息 ID 保存,过滤移除、重建思考行和切换会话后仍保留;关闭会话或移除实际消息时清理。
  • 导出 Markdown 时思考以 > 引用块输出,和回复区分;历史列表的消息数只统计用户和 Agent 回复,不计思考。
  • 思考消息会把相邻工具调用分成两组时间线,保持原始顺序。

2. 执行计划(plan)

  • 新类型 AgentPlan(AgentSessionGuidance.swift)。ACP 规定每次发送完整计划,所以整体替换;空列表清除计划;格式错误的更新忽略;最多保留 100 条;未知状态的条目丢弃而不是猜测。
  • 新视图 AgentPlanView 固定在活动统计栏上方:折叠时显示“计划 已完成/总数 · 当前步骤”,展开后逐条显示待办 / 进行中 / 已完成。
  • session/load 回放历史时计划自然恢复。

3. 斜杠命令补全(available_commands_update)

  • 新类型 AgentCommand,按会话保存 Agent 上报的命令列表(最多 200 条)。

  • 输入框以 / 开头、且命令名中还没有空白时弹出 AgentCommandSuggestionList,显示名称、说明和参数提示;前缀匹配排在包含匹配之前。

  • 选择后只把 /name 填入草稿,命令仍作为普通 prompt 原样发送,由 Agent 自己解释。Lithe 不内置命令表,也不扫描 SKILL.md,列表与 Agent 真实能力保持一致。

  • Codex Skill 兼容:实测 codex-acp 1.13.1 把 Skill 以 $pdf 形式放进同一个命令列表,但它的命令解析会跳过 /$pdf。因此 $ 开头的命令补全为 $name (不加 /);输入 $ 只列 Skill;Agent 没有上报 Skill 时 $ 仍是普通字符,不会被拦截。

  • 键盘:Return 在命令名未输完时补全、输完时发送;macOS 14+ 支持 ↑↓ 和 Tab 导航(onKeyPress 需要 macOS 14,macOS 13 保留鼠标选择和 Return);Esc 先关闭补全,回复中再按 Esc 才停止。

  • 补全布局修复:AgentComposerDraftArea 优先保留 36pt 的可编辑输入行,空结果、短列表和长列表按实际内容与剩余高度分配空间。最小输入区放不下一整行命令时,使用对话布局内的锚点浮层,让列表既可见也能鼠标点击;浮层不改变输入焦点,不向会话模型发布几何尺寸,也不新增全局监听。

4. 模式同步(current_mode_update)

  • Agent 自己切换模式(例如 Claude 退出计划模式)时,更新 category == "mode" 且包含该值的配置选项,不向上游回发设置请求;选项中没有的模式 ID 忽略,不显示原始 ID。

5. 本地化补齐

  • 模型层原本硬编码英文的文案改为 String(localized:) 并补齐 zh-Hans:Tool call、Allow the Agent to continue?、The Agent request failed.、三条 stopReason 提示(token 上限 / 请求次数上限 / 拒绝继续)。
  • 工具证据标题 Output / Content / Diff / Terminal / Unsupported content 本地化。
  • 新增思考、计划、命令相关文案的中文翻译。

6. 契约、文档与矩阵

  • shared/fixtures/agent/acp-events-v1.json 新增 agentThoughtChunk、plan、availableCommands、currentModeUpdate 四个事件样例,并加入 Rust 往返测试 serialized_events_match_the_shared_fixture,证明它们是官方 ACP SDK 可原样往返的合法格式(Windows 后续接入可直接复用)。
  • Agent Note 2026-09-25-shared-acp-agent-conversation.md 新增“思考、计划、斜杠命令与模式通知”一节,记录处理规则、正反例和资源边界。
  • 功能矩阵新增 4 行:agent-reasoning-display、agent-plan-display、agent-slash-commands、agent-mode-sync(macOS implemented / pending,Windows missing),并重新生成 Markdown/CSV 视图。

7. 按审查意见修正

  • 为 current_mode_update 新增独立功能矩阵行 agent-mode-sync,补齐 AgentConnectionModel.swift、测试与 fixture 证据;从斜杠命令行移除模式同步验收语句并重新生成 Markdown/CSV。macOS 保持 implemented/pending,Windows 保持 missing/not-applicable。
  • 输入区最小高度按上下栏、外边距及 36pt 可编辑行计算(122pt);附带文件后增加附件行(156pt)。附件有无通过局部视图偏好更新分隔容器,命令列表与逐帧几何尺寸不进入会话模型。测试改为覆盖实际对话容器和生产输入布局。
  • 上游同名命令只保留首条定义,避免 ForEach/scrollTo 重复 ID;断连时清空全部会话旧命令,重连后等待新进程上报。
  • 活跃思考块仍显示“思考中…”,底部等待行改为“回复中…”并保留计时,补齐中英文;取消继续显示“正在停止…”。
  • Return、Esc、↑↓、Tab 共用视图局部补全状态并增加自动化测试;Esc 隐藏建议后,编辑草稿重新显示,即使再改回原前缀也不继续隐藏。
  • 思考行改用绑定,展开偏好由 AgentTranscriptView 的视图局部内存按会话 ID+消息 ID 保存。搜索过滤不会删除偏好;关闭会话或移除未过滤消息时清理,不写入功能模型、Host 或历史文件。
  • 新增三个原生容器回归:搜索隐藏后销毁/重建列表仍保留展开、命中时临时展开且清空后恢复折叠、会话切换独立及关闭后重新加载的默认状态。以真实鼠标事件和同一宿主的完整画面验证,每次等待最多两秒;成功和失败路径都关闭窗口、停止功能模型。
  • 合入最新 preview 7248ba10,保留已合并 统一 Agent 权限及思考强度的上游名称与图标 #1008 的权限菜单与上游英文思考强度显示;解决功能矩阵生成文档冲突,未强推或改写原 PR 历史。

主要文件

文件 说明
macos/Sources/LitheAgentConversationModule/Application/AgentSessionGuidance.swift 新增:AgentPlan、AgentCommand 及解析、补全过滤
macos/Sources/LitheAgentConversationModule/Application/AgentConnectionModel.swift 处理四类新更新;流式缓冲按角色切分;文案本地化
macos/Sources/LitheAgentConversationModule/Application/AgentConversationState.swift .thought 角色;会话增加 plan、availableCommands
macos/Sources/Lithe/Views/Agent/AgentSessionGuidanceViews.swift 新增:思考块、计划栏、命令补全列表视图
macos/Sources/Lithe/Views/Agent/AgentComposerView.swift 命令补全交互与键盘导航
macos/Sources/Lithe/Views/Agent/AgentComposerDraftArea.swift 补全高度分配、可编辑输入行与可点击浮层
macos/Sources/Lithe/Views/Agent/AgentTranscriptView.swift 渲染思考块和计划栏

测试与验证

自动化测试(已合入 preview 7248ba10;当前修复提交 9cdcb3ed)

  • macOS:test-stability-macos.sh -- --filter Agent,12 个套件 108 项通过,1 项原有集成测试默认跳过;覆盖:
    • interleavedReasoningAndReplyBecomeSeparateMessagesInArrivalOrder:思考/回复交替时的切分、顺序与导出格式
    • planUpdatesReplaceTheWholePlanAndAnEmptyPlanClearsIt:整体替换、未知状态丢弃、空计划清除、格式错误忽略
    • advertisedCommandsArePerSessionAndFilterOnlyWhileTypingAName:按会话隔离、前缀优先过滤、$ Skill 补全规则、命令原样发送
    • agentReportedModeChangeMovesOnlyTheMatchingModeSelector:只更新模式选择器、不回发请求、忽略未知模式
    • reasoningSplitsToolTimelinesAndIsSearchableButNotCountedAsAMessage:思考分隔工具组、可搜索、不计入消息数
    • planReasoningAndCommandListsFitNarrowAndWidePanelsInBothAppearances:窄(280pt)/宽(620pt)面板 × 深/浅主题布局(已人工查看截图,长文本正常截断)
    • thoughtSearchRevealsAManuallyCollapsedMatchAndRestoresItsPreference:手动收起后搜索仍展开,搜索期间保持可见,清空后恢复选择
    • thoughtStreamingCollapsesAutomaticallyButKeepsManualExpansion:流式结束自动收起、手动展开仍保持
    • commandSuggestionsKeepAWritingLineAtDefaultAndMinimumComposerHeights:在真实 AgentConversationLayout 中托管生产 AgentComposerContent 与原生 TextField,覆盖 400/700pt 对话高度、280/620pt 宽度、有无附件、0/1/40/200 条命令;验证默认输入区与最小输入区、输入滚动容器至少 36pt、TextField 可见且在 sized pane 内、完整命令行、浮层位置和对话范围
    • commandKeysCompleteWithoutSendingAndSubmitFullInvocations:方向键循环选择、Tab/Return 只补全、完整命令 Return 发送及 $Skill 格式
    • escapeDismissesSuggestionsBeforeCancellingAndEditingReopensThem:Esc 先隐藏建议、再次停止,编辑草稿重新显示,空匹配列表也遵守优先级
    • unavailableCommandKeysLeaveOrdinaryTypingAndChangedListsUsable:普通文字、无匹配、未上报 Skill 的 $ 和命令参数不拦截导航;列表缩短或断连清空时安全处理
    • activeThoughtKeepsOneThinkingLabelAndTheWaitingTimer:活跃思考时等待行显示“回复中…”,取消优先显示“正在停止…”
    • duplicateAdvertisedCommandsKeepTheFirstDefinitionAndUniqueRowIdentities:同名命令保留首条定义,ID 唯一,读取最多前 200 条
    • AgentThoughtTranscriptTests 三个原生容器回归:搜索不匹配 → 进入空会话销毁真实列表 → 返回并清空搜索,手动展开仍保留;搜索命中保持可见,清空后恢复手动折叠;会话切换不串用偏好,关闭后重新加载使用默认状态。最慢新增测试 60ms,完整比较同一宿主的渲染画面,没有固定字体/系统快照基线。
    • 回归有效性:临时恢复行内 @State 的旧所有权后,同一容器测试在“恢复手动展开”步骤失败;恢复修复后上述 Agent 全套通过。
    • 已扩展 agentExitKeepsTranscriptAndRequiresReloadAfterReconnect:所有会话断连清空旧命令,重连加载后只显示新进程能力,显式 stop 同样清空
  • Rust:cargo test -p lithe-agent-host 71 个测试通过,cargo fmt --check 通过。
  • 检查脚本:verify-platform-feature-matrix、verify-platform-feature-matrix-change、verify-agent-notes、verify-shared-contracts、verify-runtime-bundle-immutability、测试稳定性静态检查均通过。

真实 Agent 协议验证

用临时探针按 ACP 直连本机安装的 adapter,各建会话发一条消息(工具权限一律拒绝,未修改任何文件):

Codex(codex-acp 1.13.1 / CLI 0.157.1) Claude(claude-agent-acp 0.81.2 / Claude Code 2.1.286)
available_commands_update ✅ 11 个内置命令 + 约 38 个 $xxx Skill ✅ 收到 2 次,大多带参数提示
agent_thought_chunk 本次未触发 ✅ 收到 39 段
plan / current_mode_update 本次未触发 本次未触发

上述协议探针没有覆盖所有更新。已核对两个 adapter 源码:Codex 的计划来自 turn plan 事件;Claude 的计划来自 TodoWrite/任务工具,退出计划模式时依次发送 current_mode_update 和 config_option_update。推送格式与 fixture 一致。探针还发现了上面的 /$name 问题,已在本 PR 修复。

真实界面验证(本次修复):生产预览连接本机 Claude 配置,显示 Opus 4.6,取得会话实际上报的命令列表。默认和拖到最小输入区时输入区域均保留 36pt;方向键选中最后一条后列表滚动跟随,Tab 填入命令;真实鼠标点击浮出的 /design 后填入 /design ;Esc 关闭建议并保留草稿。验证只补全,没有执行这些命令或发送模型请求。思考块另用编译当前生产视图及状态代码的原生探针验证“手动收起 → 搜索展开 → 清空后恢复收起”,只替换样式依赖。

真实思考、计划与模式同步的完整端到端验证仍未完成,功能矩阵继续标为 pending。应用、探针及关联子进程均已退出,临时探针注销并归档。

已知问题(与本 PR 无关)

  • 当前服务商配置下,真实 ACP prompt 曾在 150 秒内未返回回复、思考或计划;直接 API 和 Claude CLI 的简单请求能返回。原因尚未定位,本次界面修复没有修改 Host 或服务商链路,不将补全验证当作完整对话链路验证。
  • verify-service-boundaries.sh 因 AppModel+RunConfiguration.swift 为 616 行(上限 600)而失败,preview 基线上同样失败,本 PR 未触及该文件。
  • 并行运行完整 test-macos.sh 时约 20 个 Git / 文档 / 回滚相关的并发测试失败,preview 基线上同样失败;串行(--no-parallel)重跑全部通过。

不在本 PR 范围

Windows 端尚未接入 Agent 对话 UI(矩阵中标为 missing)。后续计划另开 PR:流式渲染性能、块级 Markdown 与代码高亮、输入框排队与 @ 文件补全、ACP fs / terminal 客户端能力。

Windows CI 安装失败修复(cd7315bf)

原失败发生在 tree-sitter-cli 下载超时:Bun 返回失败后,并行生命周期脚本仍占用 tree-sitter-kotlin 目录,导致冷重试的清理阶段再次失败。原失败任务重跑已通过,另外补上进程清理保证:

  • 每次安装由独立 PowerShell worker 执行,启动 Bun 前加入 Windows Job Object;worker 正常退出、失败、超时或被取消时,系统清理其安装子进程。每次尝试默认 300 秒本地期限,超时返回 124。
  • 释放进程树后清理部分依赖、缓存和临时文件;文件锁释放重试有 10 秒期限,只冷重试一次,永久错误仍明确失败。清缓存时撤销旧 verified 标记,成功后重新生成完整性清单。
  • 新增四个无外网 Windows 回归场景,用真实子进程占用目录并通过 IPC 确认顺序:失败后成功恢复、两次失败、成功后残留子进程、安装卡住超时。接入 Windows frontend CI 和逐项计时报告。
  • CI 分类覆盖新 worker 和测试;资源复用清单明确排除 node_modules、两个 workspace 的依赖目录与 .artifacts/bun-tmp,复用脚本测试、CI 文档与工程决策笔记同步更新。

本地缓存校验、资源复用测试(7 项)、测试稳定性、Windows 边界、bundle 只读、Agent Notes 和矩阵检查通过。新安装回归用例在 macOS 明确跳过,已由 本次 Windows frontend CI 在 Windows 执行并全部通过(4 项,最慢 9.484 秒)。真实安装一次成功(1,595 个包、175.4 秒),类型检查和前端测试全部通过。下载的前端计时报告共 1,018 条通过记录,含重复验证;最新提交的 6 个工作流、20 项 CI 检查全部成功(包含 macOS Swift、Rust/Swift 桥接、双架构打包、数据库、插件、Agent Notes 和矩阵)。

当前 9cdcb3ed 已重新触发 CI;之前 20 项全绿的结论对应 cd7315bf,不能作为新提交的 CI 结果。

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。
@ghfind-review ghfind-review Bot added the review: medium ghfind author score; see https://ghfind.com label Oct 1, 2026
为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

@1lck 1lck left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review 结论

⚠️ 建议修改(无阻塞问题)

Findings

[P2] 命令补全列表会把输入框挤没

位置: macos/Sources/Lithe/Views/Agent/AgentComposerView.swift:48-54,AgentSessionGuidanceViews.swift:175-176

实际影响:

  • 补全列表放在输入区内部,.frame(maxHeight: 168)。输入区默认高度约 210pt,扣掉上下栏(contextBar 30、toolbar 38、padding)后,ScrollView 容纳 TextField 的空间会被压到 0。
  • 在 Codex 这类有大量命令的 Agent(11 个内置 + 约 38 个 $Skill)里输入 /,用户看不到自己在输入什么。剩余约 46pt 的溢出会盖住分隔条或把工具栏推出边界。
  • 附带文件时还要再占 34pt。

触发条件: 连接命令很多的 Agent,输入框保持默认高度或更矮,输入 / 或 $。

修复建议:

  • 把补全列表改成锚定在输入区上方的 overlay(alignment: .top) 或 popover,向上浮在 transcript 上,不占输入区高度。
  • 或者按输入区可用高度动态限制列表高度(例如最多 可用高度 − 输入框最小行高),并保证 TextField 至少保留一行。
  • 加一条布局测试:在默认和最小高度的 AgentConversationLayout 中渲染带 10 条以上命令的 composer,断言 TextField 高度大于 0,且内容不超出 sized pane。

[P3] 模式同步能力被并进斜杠命令矩阵行

位置: shared/platform-feature-matrix.json:344-366

实际影响:

  • current_mode_update 同步权限模式选择器是可独立验收的能力,但只出现在 agent-slash-commands 行验证文案的最后一句。
  • 该行 evidence 没有列出真正实现它的 AgentConnectionModel.swift。
  • 和 develop-lithe 里每行对应一个可独立验证的能力的规则不一致。

修复建议:

  • 为 current_mode_update 单独加一行矩阵(例如 agent-mode-sync),evidence 写 AgentConnectionModel.swift 和对应测试,然后重新生成 Markdown/CSV。
  • 或者把这句验证移到已有的 agent-acp-conversation 行(模型/权限配置所在行),并补上 evidence。

观察项(不阻塞)

  • 思考流式输出期间会同时出现两个思考中…:AgentThoughtRow 标题和底部等待行 AgentThinkingRow。文案一样,但语义不同。可以考虑在有活跃思考块时调整其中一个的措辞。
  • AgentCommand.id 直接用 name。如果上游列表里出现同名命令,ForEach 和 scrollTo 会遇到重复 ID。
  • 输入框的补全交互(Return 补全或发送、Esc 优先关闭、↑↓/Tab)没有自动化测试,只测了模型层的 suggestions(for:in:)。建议在真实界面走查时重点覆盖。
  • 断开连接后,未附着会话仍保留上一个进程上报的 availableCommands,输入 / 会显示旧列表。发送时会先触发 load,由新进程重新上报,实际影响有限。

Summary

模型层改动集中、正确,状态都落在 LitheAgentConversationModule/Application,视图不解析原始更新,符合 Note 规定的边界。fixture 加 Rust 往返测试把四类更新锁定为合法 ACP。主要缺口在输入区内补全列表的布局:大命令列表在默认高度下会挤掉输入框,现有截图测试没覆盖这种组合。

CI 全绿。思考块、计划栏和模式同步还没在真实界面上走查过,Windows 端也还没接入(矩阵标为 pending/missing)。

@Mucheen

Mucheen commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator Author

已在 8c1cc49d、ccc5dbbd 处理本次 review,逐项结果如下:

  • P2:补全挤掉输入框:先保留 36pt 的可编辑行,再按剩余高度限制建议列表;放不下完整命令行时,在整个对话布局的锚点浮层中显示,保持鼠标可点击。最小输入区包含固定上下栏和外边距(122pt),附带文件后增加附件行(156pt),避免附件再次挤掉输入。commandSuggestionsKeepAWritingLineAtDefaultAndMinimumComposerHeights 现在直接托管 AgentConversationLayout、生产 AgentComposerContent 和原生 TextField,覆盖窄/宽、默认/最小输入区、有/无附件、0/1/40/200 条命令;断言输入可见且在 sized pane 内、编辑滚动区至少 36pt、命令行完整且不覆盖输入。
  • P3:模式同步矩阵归属:新增独立 agent-mode-sync 行,证据包含 AgentConnectionModel.swift、对应模式同步测试和 ACP fixture;从 agent-slash-commands 验收说明移除模式同步,并重新生成 Markdown/CSV。
  • 重复“思考中…”:活跃思考块保留“思考中…”,底部等待行改为“回复中…”并保留计时;取消优先显示“正在停止…”,补齐中英文和状态测试。
  • 重复命令 ID:解析上游列表时同名命令只保留首条定义,名称、说明和参数提示保持一致;新增 ID 唯一性和 200 条输入上限测试。
  • 键盘交互验证:Return、Esc、↑↓、Tab 共用视图局部的补全状态。新增自动化测试覆盖导航循环、Tab/Return 补全而不发送、完整命令 Return 发送、Esc 先关闭再取消、编辑后重新出现、无匹配/普通输入不拦截及列表缩短时安全处理。此前真实界面已走查方向键滚动、Tab、浮层鼠标选择和 Esc;自动化交互测试验证状态与动作,不将其称为完整 Agent 端到端测试。
  • 断连后旧列表:断连和显式 stop 清空所有会话 availableCommands;重连加载后等待新进程上报。已扩展断连/重连测试,验证旧记录保留而旧能力清空、新列表恢复。

本地 Swift 6.3.3 运行 Agent 测试:102 项通过、1 项原有集成测试默认跳过;矩阵、Agent Notes、共享契约和 bundle 只读检查通过。已合入最新 preview 并解决生成文档冲突。

真实 Agent 思考、计划、模式同步的完整端到端仍待验收,矩阵继续保持 pending;Windows Agent 对话 UI 仍为 missing。未把代码和合成测试结果标成实机验收完成。

CI 修复补充(cd7315bf)

原失败是 tree-sitter-cli 下载超时后,Bun 安装脚本子进程残留,占用目录,导致冷重试无法清理。已把每次安装放进独立 PowerShell worker,通过 Windows Job Object 在结束时清理所属子进程,再清理目录并冷重试;每次安装有 300 秒本地期限,文件锁释放重试有 10 秒期限,永久失败仍报错。缓存清理同时撤销旧 verified 标记。资源复用清单、排除测试、CI 分类与文档一并更新。

最新 Windows frontend job 已通过:真实安装一次完成(1,595 个包、175.4 秒),类型检查与前端测试成功。新增四项 Windows 回归测试全部通过,分别验证失败后恢复、永久失败、成功后残留子进程以及卡住超时;最慢 9.484 秒,均低于 30 秒预算。Windows 整个工作流已通过,包括 Rust 与真实 JDT;最新提交的 macOS Swift、Rust/Swift 桥接、arm64/x86_64 打包、数据库、插件、Agent Notes 和功能矩阵检查也全部成功。当前 PR 的全部 CI 检查 已通过。

@1lck 1lck left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lithe Review|修复后复审

结论:原 P2/P3 已修复,未发现需要阻塞合并的问题;另有一项非阻塞 P2 建议。
范围:preview afb7a76 → cd7315b,结合原审查、作者回复,复核当前 35 个变更文件和直接调用链。

原审查复核

  • 输入区优先保留 36pt 编辑区;空间不足时通过整个对话布局的锚点浮层显示补全,最小高度计入附件与固定栏。实际容器测试覆盖不同尺寸和命令数量。
  • 模式同步已拆成独立 agent-mode-sync 矩阵行。
  • 重复命令去重、断连后清空旧能力、等待文案区分、Return/Esc/方向键/Tab 状态回归均已加入。

[P2] 思考行被搜索过滤后,手动展开偏好仍会丢失
位置:AgentSessionGuidanceViews.swift:6–12,以及 AgentTranscriptView.swift:80–87、130–146。
触发:手动展开一条已结束的思考 → 搜索不匹配该行的文字 → 清空搜索。
新增展开偏好只放在行内 @State;搜索先过滤 transcript 再交给 ForEach,行被移除后重新出现会重建状态,userExpanded 回到 nil,已结束的思考重新收起。这是本次新增思考行状态与过滤调用链组合导致的有限 UI 问题,不影响消息内容。
建议将手动偏好放到不随过滤销毁的视图局部所有者,按会话 ID+消息 ID 保存,并补真实过滤容器回归。现有 AgentConversationPresentationTests.swift:160–174 始终持有同一个 AgentThoughtExpansion 值,未覆盖移除/重建生命周期。

var body: some View {
let conversation = feature.selectedConversation
let messages = conversation?.messages ?? []
let transcript = AgentTranscriptItem.grouped(messages, turns: conversation?.completedTurns ?? [])
.filter { $0.matches(searchText) }
// Only reasoning that is still streaming opens by default.
let liveThoughtID = conversation?.isResponding == true && messages.last?.role == .thought
? messages.last?.id : nil
VStack(spacing: 0) {
if conversation?.isLoading != true && messages.isEmpty && feature.pendingNewConversationPrompt == nil {
AgentHeroView(agentName: agentName, agentVersion: agentVersion) {
showsAgentPicker = true
}
.popover(isPresented: $showsAgentPicker, arrowEdge: .bottom) {
VStack(alignment: .leading, spacing: 2) {
ForEach(agents) { agent in
Button {
showsAgentPicker = false
onSelectAgent(agent.id)
} label: {
HStack {
Text(agent.name)
Spacer()
if agent.name == agentName { Image(systemName: "checkmark") }
}
.padding(.horizontal, 10)
.frame(height: 26)
.contentShape(Rectangle())
}
.buttonStyle(.litheNoPress)
.litheRowHover()
}
}
.padding(6)
.frame(width: 180)
}
} else {
ScrollViewReader { proxy in
ScrollView {
LazyVStack(alignment: .leading, spacing: 14) {
if conversation?.isLoading == true {
HStack(spacing: 8) {
ProgressView().controlSize(.small)
Text("Loading conversation…").foregroundStyle(LitheTheme.secondaryText)
}
}
if !searchText.isEmpty && transcript.isEmpty {
Text("No matching messages")
.foregroundStyle(AgentPanelStyle.secondary)
}
ForEach(transcript) { item in
Group {
switch item {
case .message(let message):
AgentMessageRow(
message: message,
isStreamingThought: liveThoughtID == message.id,
isSearching: !searchText.isEmpty,
onOpenFile: onOpenFile
)
case .toolGroup(let tools):
AgentToolGroupView(messages: tools, searchText: searchText, onOpenFile: onOpenFile)
case .turnSummary(let turn):
AgentTurnStatisticsView(statistics: turn)
}
}
.id(item.id)

Scope Check
ACP 更新继续复用协议和共享 Host,解析在功能模型,交互在视图层。Windows 安装器的独立 worker、Job Object 清理、本地期限、清理后冷重试和 verified 标记撤销也已静态检查,未发现阻塞项。

Verification
当前 HEAD 关联的六项工作流、20 个 check-runs 均成功,CI 实际运行的是该 HEAD 合入 base 的测试合并提交。Swift 新布局测试通过;Windows frontend 日志确认四项安装生命周期回归及真实安装通过。
本轮只读静态审查及已有 CI 日志核对,未运行脚本、测试或原生界面;上面 P2 是调用链分析,未宣称现场复现。外部取消 worker 的路径也只有静态核查。
完整真实 Agent 思考/计划/模式端到端验收仍 pending;Windows Agent 对话 UI 仍 missing,不能用安装器 CI 通过替代。

@Mucheen

Mucheen commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

已处理本轮 P2,提交 9cdcb3ed,已推送到原 PR。

  • AgentThoughtRow 改为接收绑定;手动偏好由 AgentTranscriptView 在局部内存按 会话 ID+消息 ID 保存,搜索过滤移除/重建行后不会重置。
  • 搜索命中仍临时展开,搜索期间不能收起命中文字;清空搜索恢复手动选择。切换会话保留各自选择,关闭会话或移除实际消息时清理;清理使用未过滤的消息,不把搜索结果当成消息删除。
  • 新增 3 个挂载生产对话视图的原生容器回归,使用真实鼠标事件和同一宿主的完整画面:搜索隐藏后进入空会话销毁列表,再返回并清空搜索;命中时保持可见及清空后恢复折叠;会话隔离及关闭重载。每次等待最多 2 秒,窗口/模型在成功、失败路径都清理。
  • 临时改回行内 @State 所有权时,同一回归在“恢复手动展开”步骤失败;恢复修复后完整 Agent 回归 108 项通过,1 项原有真实集成测试默认跳过。新增用例最慢 60ms,已生成 HTML/JUnit 逐项计时报告。
  • 同步更新已有 Agent Note、思考功能矩阵和生成文档;准确 PR base/head、最新 preview/head 的矩阵门禁均通过,测试稳定性、共享契约、Windows 边界和 bundle 只读检查通过。服务边界检查仍因 preview 已有的 AppModel+RunConfiguration.swift 616 行超限失败,本次未修改该文件。

已合入 preview 7248ba10 并保留 #1008 的已合并改动,正常快进推送,没有强推。新提交 CI 正在运行;完整真实 Agent 思考/计划/模式端到端验收仍 pending,Windows Agent 对话 UI 仍 missing。

@1lck 1lck left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lithe Review|思考展开偏好修复复核

已复核 cd7315b → 9cdcb3e 中本轮修复,可将“搜索过滤后丢失思考展开偏好”的 P2 标记为已解决。本次限定增量未发现需要阻塞合并的问题。

手动偏好现在由 AgentTranscriptView 按会话 ID+消息 ID 保存,行通过 Binding 访问;清理使用未过滤消息和打开会话列表,不会把搜索隐藏当成删除。生产父视图也没有按当前会话重建这个容器。

.onChange(of: feature.openSessionIDs) { sessionIDs in
thoughtExpansions = thoughtExpansions.filter { sessionIDs.contains($0.key) }
}
.onChange(of: messages.map(\.id)) { messageIDs in
// Use unfiltered messages: changing the search must never discard preferences.
guard let sessionID = feature.selectedSessionID, let preferences = thoughtExpansions[sessionID] else { return }
let retainedIDs = Set(messageIDs)
thoughtExpansions[sessionID] = preferences.filter { retainedIDs.contains($0.key) }
}
}
private func thoughtExpansion(for messageID: String) -> Binding<AgentThoughtExpansion> {
guard let sessionID = feature.selectedSessionID else { return .constant(AgentThoughtExpansion()) }
return Binding(
get: { thoughtExpansions[sessionID]?[messageID] ?? AgentThoughtExpansion() },
set: { thoughtExpansions[sessionID, default: [:]][messageID] = $0 }
)

新增三项回归挂载生产视图,通过原生鼠标事件和同宿主完整画面比较,覆盖过滤后销毁/重建列表、搜索临时展开与恢复、会话切换和关闭重载;等待有两秒期限,窗口及模型包含成功/失败清理。

@Test
func manualExpansionSurvivesNonmatchingSearchRemovingAndRecreatingTheRow() async throws {
try await withTranscript { feature, host, window in
renderFrame(host)
let collapsed = try snapshot(host)
try record(host, name: "collapsed")
try pressThought(in: host, window: window)
try await renderUntil(host, expected: "expanded thought") { try snapshot(host) != collapsed }
let expanded = try snapshot(host)
try record(host, name: "expanded")
host.rootView = transcript(feature, search: "no matching thought")
try await renderUntil(host, expected: "filtered row") { try snapshot(host) != expanded && snapshot(host) != collapsed }
try record(host, name: "filtered")
// Visiting a new empty session disposes the real scroll subtree while search remains active.
// Returning must retain this session's choice even after SwiftUI's lazy row cache is gone.
let filtered = try snapshot(host)
feature.selectSession("empty")
try await renderUntil(host, expected: "empty conversation") { try snapshot(host) != filtered }
feature.selectSession("first")
host.rootView = transcript(feature)
try await renderUntil(host, expected: "restored manual expansion") { try snapshot(host) == expanded }
try record(host, name: "restored")
}
}
@Test
func matchingSearchRevealsACollapsedThoughtWithoutReplacingItsPreference() async throws {
try await withTranscript { feature, host, window in
renderFrame(host)
let collapsed = try snapshot(host)
try pressThought(in: host, window: window)
try await renderUntil(host, expected: "manual expansion") { try snapshot(host) != collapsed }
let expanded = try snapshot(host)
try pressThought(in: host, window: window)
try await renderUntil(host, expected: "manual collapse") { try snapshot(host) == collapsed }
host.rootView = transcript(feature, search: "manifest")
try await renderUntil(host, expected: "matching thought text") { try snapshot(host) == expanded }
try pressThought(in: host, window: window)
renderFrame(host)
#expect(try snapshot(host) == expanded, "Searching must keep the matched reasoning visible after a click")
host.rootView = transcript(feature)
try await renderUntil(host, expected: "original manual collapse") { try snapshot(host) == collapsed }
}
}
@Test
func switchingSessionsKeepsIndependentPreferencesAndClosingResetsThem() async throws {
try await withTranscript { feature, host, window in
seedThought(in: feature, sessionID: "second")
renderFrame(host)
let collapsed = try snapshot(host)
try pressThought(in: host, window: window)
try await renderUntil(host, expected: "first session expanded") { try snapshot(host) != collapsed }
let expanded = try snapshot(host)
feature.selectSession("second")
host.rootView = transcript(feature)
try await renderUntil(host, expected: "second session default collapse") { try snapshot(host) == collapsed }
feature.selectSession("first")
host.rootView = transcript(feature)
try await renderUntil(host, expected: "first session retained expansion") { try snapshot(host) == expanded }
feature.closeConversation("first")
host.rootView = transcript(feature)
try await renderUntil(host, expected: "remaining session") { try snapshot(host) == collapsed }
// Reopening the session with replayed messages must use the fresh row's default.
seedThought(in: feature, sessionID: "first")
feature.selectSession("first")
host.rootView = transcript(feature)
try await renderUntil(host, expected: "reopened session default") { try snapshot(host) == collapsed }
}
}
private func withTranscript(
_ run: (AgentConnectionModel, NSHostingView<AnyView>, NSWindow) async throws -> Void
) async throws {
let feature = AgentConnectionModel(transport: UnusedThoughtTransport())
seedThought(in: feature, sessionID: "first")
feature.selectSession("first")
let host = NSHostingView(rootView: transcript(feature))
let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 360, height: 300),
styleMask: [.borderless], backing: .buffered, defer: false)
window.isReleasedWhenClosed = false
defer { window.contentView = nil; window.close() }
window.contentView = host
host.frame.size = NSSize(width: 360, height: 300)
window.orderFront(nil)
do {
try await run(feature, host, window)
await feature.stop()
} catch {
await feature.stop()
throw error
}

09:00 UTC 核对该 HEAD 时,Windows、Database、Plugin、Agent Notes、功能矩阵已成功;macOS CI 的 Swift、桥接及双架构打包仍在运行,不能称为全部通过。
本轮仅静态复审及已有 CI 状态核对,未独立运行测试或应用。作者的 108 项通过、1 项跳过及反向验证未在本轮重跑。真实 Agent 思考/计划/模式端到端仍 pending,Windows Agent 对话 UI 仍 missing。

@1lck
1lck merged commit 513ff63 into 1lck:preview Oct 2, 2026
23 of 25 checks passed
1lck added a commit that referenced this pull request Oct 2, 2026
* feat(windows): 共用 UI 组件补齐 IDEA 风格交互基础能力

- 滚动条:修复 ScrollArea 滑块带 flex-1 被拉满整条轨道的问题,改由
  Base UI 按可视比例计算滑块长度(全局所有滚动区域受益)
- 触控板:ScrollArea 的滚轮转发支持横向滑动,仅横向可滚动的容器才
  处理,纵向列表行为不变
- 树行 SidebarTreeRow:
  - 新增 leadingAction 左侧操作位(位于展开箭头之后、图标之前),
    渲染在行按钮外并按缩进定位,避免按钮嵌套交互元素
  - 新增 variant="idea":16px 细线 chevron(IDEA expui 路径、
    tree-chevron 颜色、悬停不变色),箭头/复选框/图标/文字 4px 间距,
    图标与文字垂直居中
  - 文字区增加 data-sidebar-tree-label 供横向滚动测量
- 复选框:支持 indeterminate 半选状态,显示短横
- 拖动会话 document-resize-session:新增 axis: "y",可驱动纵向高度
- 新增对应单测(横向滑动、纵向拖动)

* feat(windows): 默认主题 Git 状态配色与表单控件 token 对齐 IDEA

配色取自 intellij-community expUI 明暗配色方案(FILESTATUS_* 与 *_LINES_COLOR):
- modified / renamed:#0033B3 / #70AEFF;暂存修改为浅蓝派生 #2652BE / #85BAFF
- added:#067D17 / #73BD79;untracked:#B23247 / #E88F89
- 新增可选 token git-file-deleted(删除文件灰 #6C707E / #6F737A);
  git-deleted 仍为红色,继续用于 diff 删除行与 -N 计数
- 新增可选 token git-gutter-added/modified/deleted,编辑器 gutter 使用
  IDEA 浅色行标记(#7FC784/#88ADF7/#767A8A,暗色 #549159/#375FAD/#868A91)
- 变更列表、提交文件树、文件树的状态颜色统一走 git-* token,
  不再使用 text-info / 灰色 / 红色临时映射
- 新增 IDEA 表单控件 token:control-border、checkbox-border、
  checkbox-background、tree-chevron
- 以上新 token 在其他主题中未定义时,均回退到原有颜色
- rebase / patch / 历史改写对话框的警告文案与操作横幅由误用的
  text-git-modified 改回 text-warning,避免随 modified 变蓝

* feat(windows): Commit 面板对齐 IntelliJ(提交区、变更列表、Amend 与视图选项)

面板与入口
- 侧栏 git 入口与面板标题由 Changes / Source Control 更名为 Commit(提交),
  图标换为 IntelliJ commit 图标;中英文案、tooltip、aria 同步
- 移除面板内 Changes / History 标签栏与 git-commit-history 组件,提交历史
  统一通过底部 Git Log 工具窗浏览;命令面板去掉 "Git: Show History"
- 清理仅服务于标签的设置 rememberLastGitPanelMode / gitLastPanelMode /
  gitSidebarTabOrder,并加入 RETIRED_SETTINGS_KEYS 清理升级用户的残留键
- Git 数据控制器不再读取 `git log --all`;"与提交比较"选择器打开时才按需
  加载最近 50 条提交

提交区(对齐 NonModalCommitPanel / CommitInputBorder / CommitLegendComponent)
- 布局:顶部左侧 Amend、右侧已选文件图例(N 添加 / N 修改 / N 删除,未跟踪
  计入添加并显示为“新增+未跟踪”,重命名计入修改,按状态着色);中间提交
  说明框;底部 Commit 与 Commit and Push... 线框按钮,右侧推送/拉取计数、
  AI 与设置
- 与变更列表之间只有一条分割线、无外框;拖动分割线或聚焦后按上/下方向键
  调整说明框高度(变更列表至少 96px,说明框最小 48px),松手后持久化
- 说明框:占位文字 "Commit Message / 提交说明";4px 圆角、1px 控件边框,
  聚焦 2px 强调色,出错时错误色
- 按钮不再因未选文件或说明为空而置灰;点击后按 IntelliJ CommitProgressPanel
  文案提示(请选择要提交的文件 / 请填写提交说明 / 二者合并),修正后消失;
  焦点在提交区内时 Commit 变为蓝色默认按钮
- Amend:勾选时读取当前 HEAD 的完整说明(标题 + 正文,新增
  getHeadCommitMessage,不再取 `git log --all` 列表首条);空草稿自动载入、
  不覆盖已输入内容、取消勾选且未编辑时恢复原草稿;HEAD 无提交时提示;
  Amend 模式下主按钮显示 Amend Commit,Commit and Push... 禁用(修正后
  需要强制推送),多仓库确认对话框按钮同步

变更列表
- 分组改为 IntelliJ 的 "Changes / 更改" 与 "Unversioned Files / 未版本控制
  的文件" 两个可展开树节点,节点名后显示灰色 "N 个文件"
- 文件、文件夹、分组节点的包含复选框移到左侧(箭头之后、图标之前),
  IDEA 新 UI 样式,分组与文件夹支持三态;文件夹名后紧跟灰色文件数
- 去掉文件行末尾的暂存 +/- 按钮及其工具代码
- 长文件名不截断,改为横向滚动:按文字真实小数宽度判断截断并留 1px 余量,
  面板从隐藏切回显示、侧栏改宽或字体加载完成后重新测量;状态刷新不再重置宽度
- 参考 IntelliJ ExpandableItemsHandler:名称超出可视右边缘时,悬停该行在
  行上方弹出完整名称(含文件数或目录),移开、滚动或点击即消失
- 工具栏新增 View Options(眼睛图标),菜单直接列出 "Directory / 目录" 与
  "Flat List / 平铺显示" 并勾选当前项,两次点击切换

其他
- 新增/更新单测:提交面板 Amend 与提示、拖动高度、分组节点与三态、复选框
  位置、行宽测量、悬停提示判断、视图选项切换、数据控制器不读取历史
- 更新 platform-feature-matrix 的 git-status-commit、git-history 行,新增
  git-status-colors-idea-alignment 行,并重新生成视图

* feat(windows): 活动栏、标题栏菜单与 Run 面板图标替换为 IDEA 图标

- 活动栏 Project / Git Log / Terminal / Run / Diagnostics 改用 IntelliJ expui toolwindows 图标
  (project、vcs、terminal、run、problems),亮色与暗色各一套
- 标题栏紧凑菜单开关新增 MenuIcon(expui/general/menu),不影响其他使用 ListIcon 的位置
- 新增 RunToolWindowIcon / ProblemsToolWindowIcon,避免改动全局 25 处使用的 WarningIcon
- Run 面板标题、空状态与命令面板统一使用 RunToolWindowIcon,移除自绘 RunIcon
- generate-idea-icons.ts 支持映射项 destination 字段,用于终端图标这类
  位于 platform/icons/src 之外(Jewel showcase 资源)的素材
- 更新 icons.test.tsx 的导出数量与双色渲染断言

* test(windows): svg-editor 测试结束后还原 locale-provider mock

bun 的 mock.module 在同一进程内会泄漏到后续测试文件。svg-editor.test.tsx
把 @/i18n/locale-provider 替换成只含 useTranslation 的桩且不还原,导致全量运行时
Commit 面板等依赖真实 LocaleProvider 的测试拿到桩而失败。

在安装 happy-dom 之前保存真实模块,并在 afterAll 中还原。buffer.store 的 mock
无法同样处理(导入真实模块会触发 Tauri 窗口 API),保持不变。

* fix(windows): Amend 按实际暂存仓库读取 HEAD,提交说明分隔条从显示高度起算

- Amend 目标由有暂存文件的仓库决定,而不是活动仓库:单仓库参与时读取该仓库的 HEAD,
  多仓库同时有暂存文件时禁用 Amend 并给出提示;目标仓库变化时撤销已加载的说明,
  并在说明未被修改时恢复原草稿
- 提交说明编辑框最多显示视口的 60%,拖动与方向键调整改为从实际显示高度开始,
  渲染与交互共用同一上限常量
- 补充 A 活动 / B 暂存、活动仓库无 HEAD、多仓库禁用、目标变化,以及窗口缩小后
  拖动与键盘调整的回归测试

* fix(git): Amend 绑定到明确的仓库与 HEAD,由 Core 拒绝多仓库改写

Core 建立提交计划时会重新读取所有仓库的暂存状态,而界面只基于缓存的状态读取
并展示了某一个仓库的提交说明。若读取之后又有别的仓库被暂存(例如外部终端,
且关闭了自动刷新),一个全局 amend 会让两个仓库共用同一条说明并同时被改写。

- Core: amend 时有暂存更改的仓库最多一个,否则 invalid_request 且不写入
- Core: 新增可选 amendTarget{repositoryId, expectedHead},拒绝未知目标、
  不一致的暂存仓库以及 HEAD 已移动(新提交或切分支)的请求;重试时目标
  已提交则跳过 HEAD 检查
- Core: 约束只在 prepare 校验,不写入 Plan,避免 macOS 的计划模型丢弃未知
  字段后 amend 悄悄变成普通提交;validate_session 兜底拒绝涉及多个暂存仓库的
  amend 续接。缺省 amendTarget 时保持单仓库下限,macOS 无需改动
- Windows: getHeadCommitMessage 同时返回 HEAD hash;面板记录读取说明的仓库与
  hash,提交与重试时转换为仓库标识发送,无法确认时提示重新加载
- 补充 Rust 单元与真实 Git 集成回归、前端面板与 API 测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* fix(git): 重试沿用计划记录的 Amend 仓库,父仓库不再被误改写

子仓库 Amend 成功而父仓库提交被钩子拒绝后,父仓库已暂存了新的子模块引用。
重试时 Core 根据当前暂存区重新推断 Amend 目标,会把它当作唯一的暂存仓库并
改写其原 HEAD,用户确认的“新增父引用提交”变成了历史改写。

- Core: Plan 新增 amendRepositoryId,首次建立计划时确定;step 只 Amend 该
  仓库,其余仓库(含只记录子模块引用的父仓库)做普通提交
- Core: 重试沿用 previous.plan 记录的仓库,指定不同 amendTarget 时拒绝;
  validate_session 拒绝指向未知仓库或非 Amend 计划的续接
- Core: 字段缺失(丢弃未知字段的客户端)时退回按暂存路径判断并限制为一个仓库,
  行为与此前一致
- Windows: 重试不再根据组件 ref 推断目标,直接交还上一次计划
- 补充真实 Git 回归(子 Amend 成功、父钩子失败、恢复后重试)及单元、前端测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* revert(windows): 移除 Commit 面板的 Amend 功能

Amend 在多仓库工作区里需要把“每个仓库的提交意图”做成 Swift 与 Rust 共享的
模型,当前 PR 内无法在 macOS 缺少构建验证的情况下安全完成,且反复引入回归。
本次先移除,Windows 提交面板恢复为只做普通提交。

- Windows: 删除 Amend 复选框、HEAD 说明读取、目标仓库推断、重试目标处理,
  以及确认框的 Amend Commit 文案和相关 i18n 键
- Core: workspace_commit 及其测试、共享契约与 Agent Note 还原为与 preview 一致,
  macOS 的 amend 布尔字段保持不变,Swift 无需改动
- 测试: 删除全部 Amend 用例,新增“提交始终为普通提交且不显示 Amend”断言
- 矩阵: 去掉功能说明中的 Amend 描述并重新生成
- 保留与 Amend 无关的修复:提交说明分隔条按实际显示高度调整、图标替换、
  svg-editor 测试的 locale mock 还原

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

---------

Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: lick <2188718831@qq.com>
1lck added a commit that referenced this pull request Oct 2, 2026
* fix(agent): 统一权限菜单与英文思考强度显示 (#1008)

* Merge pull request #1023 from Mucheen/fix/agent-selector-labels

fix(macos): 收紧 Agent 配置菜单并修复双行说明裁剪

* fix:macOS 项目树支持多选与批量文件操作 (#991)

* fix(macOS): 支持项目树多选与批量文件操作 (#987)

* docs: 记录 #987 macOS 项目树手动验证结果

* docs: 添加 #987 项目树多选手动验证截图

* fix(macOS): 处理 #991 审查意见并补齐项目树批量操作边界

- 批量删除:每项删除前重新检查未保存文档;废纸篓操作期间被改脏的文档保持打开,
  仅关闭未修改的文档;中途失败或被未保存文档阻止时提示剩余项目未移动。
- 快捷键归属:点击项目树后若键盘焦点移到文本框(如全局搜索)或其他控件,
  ⌘A/⌘C/⌘V 交还给当前焦点,不再误复制或粘贴文件。
- Control 点击恢复为 macOS 右键菜单,⌘ 点击负责增减选择;移除为此新增的
  litheContextMenu(capturesControlClick:) 参数。
- 单选高亮跟随活动编辑器文档;去掉 ProjectFileTreeContent 中冗余的可见节点比较。
- 中文“拷贝”与“复制(创建副本)”区分;补齐粘贴校验和批量删除提示的中英文案。
- 新增单元、焦点与应用级集成测试;功能矩阵改回待验证。

* fix(macOS): 项目树快捷键被处理后不再同时传给编辑器

本地事件监听里的 `self?.handle(event) ?? event` 会把表示“已处理”的 nil
展平成原事件,导致 ⌘A/⌘C/⌘V 在项目树处理后仍传给编辑器:⌘A 同时全选编辑器文本,
⌘V 同时把剪贴板文本粘进编辑器。改为直接返回 handle 的结果并补回归测试。

粘贴完成的提示由“已复制文件”改为“已粘贴文件”,避免复制和粘贴各弹一条相同提示。

* fix(macOS): 项目树 ⌘A 按焦点所在目录全选

焦点在展开的子目录内时,⌘A 只选中该目录下的可见项目;焦点在项目顶层时选中项目下全部可见项目(含子目录及其展开内容,不含根行);焦点在根行或无焦点时选中整棵可见树。重复 ⌘A 保持同一范围,并补充同名前缀目录不被误选的测试。

* fix(macOS): 项目树 ⌘A 选中焦点项的同级项目

点击文件夹后按 ⌘A,选中与该文件夹同级的项目,而不是它的内容;焦点在文件上时选中同目录文件;无焦点或焦点在项目行时选中项目顶层项目。同级关系按显示的树结构计算,压缩显示的 Java 包也使用其显示父节点。批量操作会自动包含已选文件夹的内容。

* fix(macOS): 已选文件夹下的展开内容同时显示为选中

文件夹被选中时,其下展开的文件和子目录也显示选中高亮,与批量操作会包含文件夹内容保持一致。这些子项只用于显示,不会重复加入操作集合;在多选组内右键这些子项仍保持整组,单独选中一个文件夹时右键其中的文件则以该文件为目标。

* ci: 重新触发 macOS Plugin CI

上次运行在 960 秒时限内仍在冷编译 LitheTests(Rust 4m39s,正常约 3m),尚未进入测试执行。同一提交的 macOS 主 Swift lane 已通过,本地按相同过滤条件运行 59 项插件测试全部通过。

* fix(macOS): 项目树 Shift/⌘ 点击从鼠标按下事件读取修饰键

SwiftUI Button 的动作在鼠标抬起后才执行,此时 NSApp.currentEvent 已不再是这次点击,
读到的修饰键为空,Shift 点击因此退化成普通单选、范围不生效。

- 新增 ProjectTreeModifiedClick 覆盖在每一行上:只在带 ⌘/Shift 的左键按下时命中,
  直接用该 mouseDown 事件的修饰键更新选择,并且不再传给 Button,因此不会打开文件或折叠目录。
- 普通点击和 Control 点击(右键菜单)都穿透到原有的 Button 和右键捕获视图,行为不变。
- selectRow 改为接收修饰键参数,Button 动作只做普通单选。
- 新增窗口级回归测试,覆盖 Shift 正向/反向范围选择、⌘ 取消选择、修饰点击不触发打开,以及 Control+Shift 不被捕获。

* test(macOS): 项目树修饰点击回归改为经窗口命中测试分发

审查指出原测试直接调用 overlay.mouseDown,绕过 hitTest 和窗口分发,即使
生产 hitTest 恒返回 nil 也会通过。

- 测试改为把合成的鼠标按下/抬起事件交给 NSWindow.sendEvent,由窗口命中测试
  决定交给覆盖层还是底层 Button;覆盖新增普通点击建立锚点、Shift 正反向范围、
  ⌘ 增减选择、修饰点击不触发 Button(不打开文件、不折叠目录)以及 Control
  点击穿透到底层行。
- ProjectTreeModifiedClickView 的当前事件来源改为可替换的 currentEvent,默认仍是
  NSApp.currentEvent。测试进程里经 NSApp 事件队列取出事件会让 swift-testing 的
  主队列提前退出,后续测试不再执行,所以测试只替换这一处查询。
- 反向验证:hitTest 恒返回 nil、或捕获 Control 点击时,新测试均失败。

* fix(macOS): 批量文件操作在整批结束前持有操作锁

处理 #991 审查的 P2/P3:

- 批量创建副本和批量移到废纸篓原来逐项调用单项入口,每项结束后都会先释放
  isPerformingProjectItemOperation 再 await 刷新。刷新期间用户可以启动别的文件操作,
  原批次的后续项随后被入口守卫静默跳过。现在由外层批次持有操作锁直到整批结束,
  内层拆成不自行加锁、不刷新的单项实现,整批完成后只刷新一次。
- 单项粘贴和单项删除仍通过同一实现,行为不变。
- 中文“Copied files”改为“已拷贝文件”,与菜单“拷贝”一致。
- 新增回归:第一组复制暂停时操作锁保持占用、插入的粘贴被拒绝,批量复制和
  批量删除各只在最后一项完成后刷新一次。恢复旧实现时该测试失败。

---------

Co-authored-by: Lichenkang <2188718831@qq.com>

* fix(agent): 修复 Claude 鉴权、会话切换和品牌图标 (#1007)

* fix(agent): 修复 Claude 鉴权、会话切换和品牌图标

通过 Claude 适配器公开会话参数传递 API Key 路由,同时覆盖新建与历史恢复,清除冲突鉴权并保留 Codex gateway 行为。
直接观察所选 Agent 连接,等待会话设置确认后展示模型,防止旧配置闪现及准备期间提交。
统一底栏、模型入口与 Agent 菜单品牌图标,保留原生单选勾选,并补充回归、共享契约、Agent Note 与功能矩阵。

* test(git): bound graph frame sampling to visible viewports

修复 PR #1007 CI:原用例重复绘制完整 1000 行历史,CI 耗时 11.791 秒超过未调整的 10 秒上限。改为开头、中段、末段 40 行视口采样,校验实际像素,保留完整结构、单帧预算与 Release 基线;同步 CI 文档和中文工程笔记。

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

* feat(windows): 活动栏/标题栏/Run 面板图标替换为 IDEA 图标,并对齐 Commit 面板与共用控件 (#1025)

* feat(windows): 共用 UI 组件补齐 IDEA 风格交互基础能力

- 滚动条:修复 ScrollArea 滑块带 flex-1 被拉满整条轨道的问题,改由
  Base UI 按可视比例计算滑块长度(全局所有滚动区域受益)
- 触控板:ScrollArea 的滚轮转发支持横向滑动,仅横向可滚动的容器才
  处理,纵向列表行为不变
- 树行 SidebarTreeRow:
  - 新增 leadingAction 左侧操作位(位于展开箭头之后、图标之前),
    渲染在行按钮外并按缩进定位,避免按钮嵌套交互元素
  - 新增 variant="idea":16px 细线 chevron(IDEA expui 路径、
    tree-chevron 颜色、悬停不变色),箭头/复选框/图标/文字 4px 间距,
    图标与文字垂直居中
  - 文字区增加 data-sidebar-tree-label 供横向滚动测量
- 复选框:支持 indeterminate 半选状态,显示短横
- 拖动会话 document-resize-session:新增 axis: "y",可驱动纵向高度
- 新增对应单测(横向滑动、纵向拖动)

* feat(windows): 默认主题 Git 状态配色与表单控件 token 对齐 IDEA

配色取自 intellij-community expUI 明暗配色方案(FILESTATUS_* 与 *_LINES_COLOR):
- modified / renamed:#0033B3 / #70AEFF;暂存修改为浅蓝派生 #2652BE / #85BAFF
- added:#067D17 / #73BD79;untracked:#B23247 / #E88F89
- 新增可选 token git-file-deleted(删除文件灰 #6C707E / #6F737A);
  git-deleted 仍为红色,继续用于 diff 删除行与 -N 计数
- 新增可选 token git-gutter-added/modified/deleted,编辑器 gutter 使用
  IDEA 浅色行标记(#7FC784/#88ADF7/#767A8A,暗色 #549159/#375FAD/#868A91)
- 变更列表、提交文件树、文件树的状态颜色统一走 git-* token,
  不再使用 text-info / 灰色 / 红色临时映射
- 新增 IDEA 表单控件 token:control-border、checkbox-border、
  checkbox-background、tree-chevron
- 以上新 token 在其他主题中未定义时,均回退到原有颜色
- rebase / patch / 历史改写对话框的警告文案与操作横幅由误用的
  text-git-modified 改回 text-warning,避免随 modified 变蓝

* feat(windows): Commit 面板对齐 IntelliJ(提交区、变更列表、Amend 与视图选项)

面板与入口
- 侧栏 git 入口与面板标题由 Changes / Source Control 更名为 Commit(提交),
  图标换为 IntelliJ commit 图标;中英文案、tooltip、aria 同步
- 移除面板内 Changes / History 标签栏与 git-commit-history 组件,提交历史
  统一通过底部 Git Log 工具窗浏览;命令面板去掉 "Git: Show History"
- 清理仅服务于标签的设置 rememberLastGitPanelMode / gitLastPanelMode /
  gitSidebarTabOrder,并加入 RETIRED_SETTINGS_KEYS 清理升级用户的残留键
- Git 数据控制器不再读取 `git log --all`;"与提交比较"选择器打开时才按需
  加载最近 50 条提交

提交区(对齐 NonModalCommitPanel / CommitInputBorder / CommitLegendComponent)
- 布局:顶部左侧 Amend、右侧已选文件图例(N 添加 / N 修改 / N 删除,未跟踪
  计入添加并显示为“新增+未跟踪”,重命名计入修改,按状态着色);中间提交
  说明框;底部 Commit 与 Commit and Push... 线框按钮,右侧推送/拉取计数、
  AI 与设置
- 与变更列表之间只有一条分割线、无外框;拖动分割线或聚焦后按上/下方向键
  调整说明框高度(变更列表至少 96px,说明框最小 48px),松手后持久化
- 说明框:占位文字 "Commit Message / 提交说明";4px 圆角、1px 控件边框,
  聚焦 2px 强调色,出错时错误色
- 按钮不再因未选文件或说明为空而置灰;点击后按 IntelliJ CommitProgressPanel
  文案提示(请选择要提交的文件 / 请填写提交说明 / 二者合并),修正后消失;
  焦点在提交区内时 Commit 变为蓝色默认按钮
- Amend:勾选时读取当前 HEAD 的完整说明(标题 + 正文,新增
  getHeadCommitMessage,不再取 `git log --all` 列表首条);空草稿自动载入、
  不覆盖已输入内容、取消勾选且未编辑时恢复原草稿;HEAD 无提交时提示;
  Amend 模式下主按钮显示 Amend Commit,Commit and Push... 禁用(修正后
  需要强制推送),多仓库确认对话框按钮同步

变更列表
- 分组改为 IntelliJ 的 "Changes / 更改" 与 "Unversioned Files / 未版本控制
  的文件" 两个可展开树节点,节点名后显示灰色 "N 个文件"
- 文件、文件夹、分组节点的包含复选框移到左侧(箭头之后、图标之前),
  IDEA 新 UI 样式,分组与文件夹支持三态;文件夹名后紧跟灰色文件数
- 去掉文件行末尾的暂存 +/- 按钮及其工具代码
- 长文件名不截断,改为横向滚动:按文字真实小数宽度判断截断并留 1px 余量,
  面板从隐藏切回显示、侧栏改宽或字体加载完成后重新测量;状态刷新不再重置宽度
- 参考 IntelliJ ExpandableItemsHandler:名称超出可视右边缘时,悬停该行在
  行上方弹出完整名称(含文件数或目录),移开、滚动或点击即消失
- 工具栏新增 View Options(眼睛图标),菜单直接列出 "Directory / 目录" 与
  "Flat List / 平铺显示" 并勾选当前项,两次点击切换

其他
- 新增/更新单测:提交面板 Amend 与提示、拖动高度、分组节点与三态、复选框
  位置、行宽测量、悬停提示判断、视图选项切换、数据控制器不读取历史
- 更新 platform-feature-matrix 的 git-status-commit、git-history 行,新增
  git-status-colors-idea-alignment 行,并重新生成视图

* feat(windows): 活动栏、标题栏菜单与 Run 面板图标替换为 IDEA 图标

- 活动栏 Project / Git Log / Terminal / Run / Diagnostics 改用 IntelliJ expui toolwindows 图标
  (project、vcs、terminal、run、problems),亮色与暗色各一套
- 标题栏紧凑菜单开关新增 MenuIcon(expui/general/menu),不影响其他使用 ListIcon 的位置
- 新增 RunToolWindowIcon / ProblemsToolWindowIcon,避免改动全局 25 处使用的 WarningIcon
- Run 面板标题、空状态与命令面板统一使用 RunToolWindowIcon,移除自绘 RunIcon
- generate-idea-icons.ts 支持映射项 destination 字段,用于终端图标这类
  位于 platform/icons/src 之外(Jewel showcase 资源)的素材
- 更新 icons.test.tsx 的导出数量与双色渲染断言

* test(windows): svg-editor 测试结束后还原 locale-provider mock

bun 的 mock.module 在同一进程内会泄漏到后续测试文件。svg-editor.test.tsx
把 @/i18n/locale-provider 替换成只含 useTranslation 的桩且不还原,导致全量运行时
Commit 面板等依赖真实 LocaleProvider 的测试拿到桩而失败。

在安装 happy-dom 之前保存真实模块,并在 afterAll 中还原。buffer.store 的 mock
无法同样处理(导入真实模块会触发 Tauri 窗口 API),保持不变。

* fix(windows): Amend 按实际暂存仓库读取 HEAD,提交说明分隔条从显示高度起算

- Amend 目标由有暂存文件的仓库决定,而不是活动仓库:单仓库参与时读取该仓库的 HEAD,
  多仓库同时有暂存文件时禁用 Amend 并给出提示;目标仓库变化时撤销已加载的说明,
  并在说明未被修改时恢复原草稿
- 提交说明编辑框最多显示视口的 60%,拖动与方向键调整改为从实际显示高度开始,
  渲染与交互共用同一上限常量
- 补充 A 活动 / B 暂存、活动仓库无 HEAD、多仓库禁用、目标变化,以及窗口缩小后
  拖动与键盘调整的回归测试

* fix(git): Amend 绑定到明确的仓库与 HEAD,由 Core 拒绝多仓库改写

Core 建立提交计划时会重新读取所有仓库的暂存状态,而界面只基于缓存的状态读取
并展示了某一个仓库的提交说明。若读取之后又有别的仓库被暂存(例如外部终端,
且关闭了自动刷新),一个全局 amend 会让两个仓库共用同一条说明并同时被改写。

- Core: amend 时有暂存更改的仓库最多一个,否则 invalid_request 且不写入
- Core: 新增可选 amendTarget{repositoryId, expectedHead},拒绝未知目标、
  不一致的暂存仓库以及 HEAD 已移动(新提交或切分支)的请求;重试时目标
  已提交则跳过 HEAD 检查
- Core: 约束只在 prepare 校验,不写入 Plan,避免 macOS 的计划模型丢弃未知
  字段后 amend 悄悄变成普通提交;validate_session 兜底拒绝涉及多个暂存仓库的
  amend 续接。缺省 amendTarget 时保持单仓库下限,macOS 无需改动
- Windows: getHeadCommitMessage 同时返回 HEAD hash;面板记录读取说明的仓库与
  hash,提交与重试时转换为仓库标识发送,无法确认时提示重新加载
- 补充 Rust 单元与真实 Git 集成回归、前端面板与 API 测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* fix(git): 重试沿用计划记录的 Amend 仓库,父仓库不再被误改写

子仓库 Amend 成功而父仓库提交被钩子拒绝后,父仓库已暂存了新的子模块引用。
重试时 Core 根据当前暂存区重新推断 Amend 目标,会把它当作唯一的暂存仓库并
改写其原 HEAD,用户确认的“新增父引用提交”变成了历史改写。

- Core: Plan 新增 amendRepositoryId,首次建立计划时确定;step 只 Amend 该
  仓库,其余仓库(含只记录子模块引用的父仓库)做普通提交
- Core: 重试沿用 previous.plan 记录的仓库,指定不同 amendTarget 时拒绝;
  validate_session 拒绝指向未知仓库或非 Amend 计划的续接
- Core: 字段缺失(丢弃未知字段的客户端)时退回按暂存路径判断并限制为一个仓库,
  行为与此前一致
- Windows: 重试不再根据组件 ref 推断目标,直接交还上一次计划
- 补充真实 Git 回归(子 Amend 成功、父钩子失败、恢复后重试)及单元、前端测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* revert(windows): 移除 Commit 面板的 Amend 功能

Amend 在多仓库工作区里需要把“每个仓库的提交意图”做成 Swift 与 Rust 共享的
模型,当前 PR 内无法在 macOS 缺少构建验证的情况下安全完成,且反复引入回归。
本次先移除,Windows 提交面板恢复为只做普通提交。

- Windows: 删除 Amend 复选框、HEAD 说明读取、目标仓库推断、重试目标处理,
  以及确认框的 Amend Commit 文案和相关 i18n 键
- Core: workspace_commit 及其测试、共享契约与 Agent Note 还原为与 preview 一致,
  macOS 的 amend 布尔字段保持不变,Swift 无需改动
- 测试: 删除全部 Amend 用例,新增“提交始终为普通提交且不显示 Amend”断言
- 矩阵: 去掉功能说明中的 Amend 描述并重新生成
- 保留与 Amend 无关的修复:提交说明分隔条按实际显示高度调整、图标替换、
  svg-editor 测试的 locale mock 还原

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

---------

Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: lick <2188718831@qq.com>

* refactor(matrix): split capability records and generate views in CI (#1026)

---------

Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: sinth <2235390062@qq.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: 若水 <frankw.wang@qq.com>
1lck added a commit that referenced this pull request Oct 3, 2026
* fix(macos): show full-height Markdown outline by default (#1002)

* fix(agent): 统一权限菜单与英文思考强度显示 (#1008)

* Merge pull request #1023 from Mucheen/fix/agent-selector-labels

fix(macos): 收紧 Agent 配置菜单并修复双行说明裁剪

* fix:macOS 项目树支持多选与批量文件操作 (#991)

* fix(macOS): 支持项目树多选与批量文件操作 (#987)

* docs: 记录 #987 macOS 项目树手动验证结果

* docs: 添加 #987 项目树多选手动验证截图

* fix(macOS): 处理 #991 审查意见并补齐项目树批量操作边界

- 批量删除:每项删除前重新检查未保存文档;废纸篓操作期间被改脏的文档保持打开,
  仅关闭未修改的文档;中途失败或被未保存文档阻止时提示剩余项目未移动。
- 快捷键归属:点击项目树后若键盘焦点移到文本框(如全局搜索)或其他控件,
  ⌘A/⌘C/⌘V 交还给当前焦点,不再误复制或粘贴文件。
- Control 点击恢复为 macOS 右键菜单,⌘ 点击负责增减选择;移除为此新增的
  litheContextMenu(capturesControlClick:) 参数。
- 单选高亮跟随活动编辑器文档;去掉 ProjectFileTreeContent 中冗余的可见节点比较。
- 中文“拷贝”与“复制(创建副本)”区分;补齐粘贴校验和批量删除提示的中英文案。
- 新增单元、焦点与应用级集成测试;功能矩阵改回待验证。

* fix(macOS): 项目树快捷键被处理后不再同时传给编辑器

本地事件监听里的 `self?.handle(event) ?? event` 会把表示“已处理”的 nil
展平成原事件,导致 ⌘A/⌘C/⌘V 在项目树处理后仍传给编辑器:⌘A 同时全选编辑器文本,
⌘V 同时把剪贴板文本粘进编辑器。改为直接返回 handle 的结果并补回归测试。

粘贴完成的提示由“已复制文件”改为“已粘贴文件”,避免复制和粘贴各弹一条相同提示。

* fix(macOS): 项目树 ⌘A 按焦点所在目录全选

焦点在展开的子目录内时,⌘A 只选中该目录下的可见项目;焦点在项目顶层时选中项目下全部可见项目(含子目录及其展开内容,不含根行);焦点在根行或无焦点时选中整棵可见树。重复 ⌘A 保持同一范围,并补充同名前缀目录不被误选的测试。

* fix(macOS): 项目树 ⌘A 选中焦点项的同级项目

点击文件夹后按 ⌘A,选中与该文件夹同级的项目,而不是它的内容;焦点在文件上时选中同目录文件;无焦点或焦点在项目行时选中项目顶层项目。同级关系按显示的树结构计算,压缩显示的 Java 包也使用其显示父节点。批量操作会自动包含已选文件夹的内容。

* fix(macOS): 已选文件夹下的展开内容同时显示为选中

文件夹被选中时,其下展开的文件和子目录也显示选中高亮,与批量操作会包含文件夹内容保持一致。这些子项只用于显示,不会重复加入操作集合;在多选组内右键这些子项仍保持整组,单独选中一个文件夹时右键其中的文件则以该文件为目标。

* ci: 重新触发 macOS Plugin CI

上次运行在 960 秒时限内仍在冷编译 LitheTests(Rust 4m39s,正常约 3m),尚未进入测试执行。同一提交的 macOS 主 Swift lane 已通过,本地按相同过滤条件运行 59 项插件测试全部通过。

* fix(macOS): 项目树 Shift/⌘ 点击从鼠标按下事件读取修饰键

SwiftUI Button 的动作在鼠标抬起后才执行,此时 NSApp.currentEvent 已不再是这次点击,
读到的修饰键为空,Shift 点击因此退化成普通单选、范围不生效。

- 新增 ProjectTreeModifiedClick 覆盖在每一行上:只在带 ⌘/Shift 的左键按下时命中,
  直接用该 mouseDown 事件的修饰键更新选择,并且不再传给 Button,因此不会打开文件或折叠目录。
- 普通点击和 Control 点击(右键菜单)都穿透到原有的 Button 和右键捕获视图,行为不变。
- selectRow 改为接收修饰键参数,Button 动作只做普通单选。
- 新增窗口级回归测试,覆盖 Shift 正向/反向范围选择、⌘ 取消选择、修饰点击不触发打开,以及 Control+Shift 不被捕获。

* test(macOS): 项目树修饰点击回归改为经窗口命中测试分发

审查指出原测试直接调用 overlay.mouseDown,绕过 hitTest 和窗口分发,即使
生产 hitTest 恒返回 nil 也会通过。

- 测试改为把合成的鼠标按下/抬起事件交给 NSWindow.sendEvent,由窗口命中测试
  决定交给覆盖层还是底层 Button;覆盖新增普通点击建立锚点、Shift 正反向范围、
  ⌘ 增减选择、修饰点击不触发 Button(不打开文件、不折叠目录)以及 Control
  点击穿透到底层行。
- ProjectTreeModifiedClickView 的当前事件来源改为可替换的 currentEvent,默认仍是
  NSApp.currentEvent。测试进程里经 NSApp 事件队列取出事件会让 swift-testing 的
  主队列提前退出,后续测试不再执行,所以测试只替换这一处查询。
- 反向验证:hitTest 恒返回 nil、或捕获 Control 点击时,新测试均失败。

* fix(macOS): 批量文件操作在整批结束前持有操作锁

处理 #991 审查的 P2/P3:

- 批量创建副本和批量移到废纸篓原来逐项调用单项入口,每项结束后都会先释放
  isPerformingProjectItemOperation 再 await 刷新。刷新期间用户可以启动别的文件操作,
  原批次的后续项随后被入口守卫静默跳过。现在由外层批次持有操作锁直到整批结束,
  内层拆成不自行加锁、不刷新的单项实现,整批完成后只刷新一次。
- 单项粘贴和单项删除仍通过同一实现,行为不变。
- 中文“Copied files”改为“已拷贝文件”,与菜单“拷贝”一致。
- 新增回归:第一组复制暂停时操作锁保持占用、插入的粘贴被拒绝,批量复制和
  批量删除各只在最后一项完成后刷新一次。恢复旧实现时该测试失败。

---------

Co-authored-by: Lichenkang <2188718831@qq.com>

* fix(agent): 修复 Claude 鉴权、会话切换和品牌图标 (#1007)

* fix(agent): 修复 Claude 鉴权、会话切换和品牌图标

通过 Claude 适配器公开会话参数传递 API Key 路由,同时覆盖新建与历史恢复,清除冲突鉴权并保留 Codex gateway 行为。
直接观察所选 Agent 连接,等待会话设置确认后展示模型,防止旧配置闪现及准备期间提交。
统一底栏、模型入口与 Agent 菜单品牌图标,保留原生单选勾选,并补充回归、共享契约、Agent Note 与功能矩阵。

* test(git): bound graph frame sampling to visible viewports

修复 PR #1007 CI:原用例重复绘制完整 1000 行历史,CI 耗时 11.791 秒超过未调整的 10 秒上限。改为开头、中段、末段 40 行视口采样,校验实际像素,保留完整结构、单帧预算与 Release 基线;同步 CI 文档和中文工程笔记。

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

* feat(windows): 活动栏/标题栏/Run 面板图标替换为 IDEA 图标,并对齐 Commit 面板与共用控件 (#1025)

* feat(windows): 共用 UI 组件补齐 IDEA 风格交互基础能力

- 滚动条:修复 ScrollArea 滑块带 flex-1 被拉满整条轨道的问题,改由
  Base UI 按可视比例计算滑块长度(全局所有滚动区域受益)
- 触控板:ScrollArea 的滚轮转发支持横向滑动,仅横向可滚动的容器才
  处理,纵向列表行为不变
- 树行 SidebarTreeRow:
  - 新增 leadingAction 左侧操作位(位于展开箭头之后、图标之前),
    渲染在行按钮外并按缩进定位,避免按钮嵌套交互元素
  - 新增 variant="idea":16px 细线 chevron(IDEA expui 路径、
    tree-chevron 颜色、悬停不变色),箭头/复选框/图标/文字 4px 间距,
    图标与文字垂直居中
  - 文字区增加 data-sidebar-tree-label 供横向滚动测量
- 复选框:支持 indeterminate 半选状态,显示短横
- 拖动会话 document-resize-session:新增 axis: "y",可驱动纵向高度
- 新增对应单测(横向滑动、纵向拖动)

* feat(windows): 默认主题 Git 状态配色与表单控件 token 对齐 IDEA

配色取自 intellij-community expUI 明暗配色方案(FILESTATUS_* 与 *_LINES_COLOR):
- modified / renamed:#0033B3 / #70AEFF;暂存修改为浅蓝派生 #2652BE / #85BAFF
- added:#067D17 / #73BD79;untracked:#B23247 / #E88F89
- 新增可选 token git-file-deleted(删除文件灰 #6C707E / #6F737A);
  git-deleted 仍为红色,继续用于 diff 删除行与 -N 计数
- 新增可选 token git-gutter-added/modified/deleted,编辑器 gutter 使用
  IDEA 浅色行标记(#7FC784/#88ADF7/#767A8A,暗色 #549159/#375FAD/#868A91)
- 变更列表、提交文件树、文件树的状态颜色统一走 git-* token,
  不再使用 text-info / 灰色 / 红色临时映射
- 新增 IDEA 表单控件 token:control-border、checkbox-border、
  checkbox-background、tree-chevron
- 以上新 token 在其他主题中未定义时,均回退到原有颜色
- rebase / patch / 历史改写对话框的警告文案与操作横幅由误用的
  text-git-modified 改回 text-warning,避免随 modified 变蓝

* feat(windows): Commit 面板对齐 IntelliJ(提交区、变更列表、Amend 与视图选项)

面板与入口
- 侧栏 git 入口与面板标题由 Changes / Source Control 更名为 Commit(提交),
  图标换为 IntelliJ commit 图标;中英文案、tooltip、aria 同步
- 移除面板内 Changes / History 标签栏与 git-commit-history 组件,提交历史
  统一通过底部 Git Log 工具窗浏览;命令面板去掉 "Git: Show History"
- 清理仅服务于标签的设置 rememberLastGitPanelMode / gitLastPanelMode /
  gitSidebarTabOrder,并加入 RETIRED_SETTINGS_KEYS 清理升级用户的残留键
- Git 数据控制器不再读取 `git log --all`;"与提交比较"选择器打开时才按需
  加载最近 50 条提交

提交区(对齐 NonModalCommitPanel / CommitInputBorder / CommitLegendComponent)
- 布局:顶部左侧 Amend、右侧已选文件图例(N 添加 / N 修改 / N 删除,未跟踪
  计入添加并显示为“新增+未跟踪”,重命名计入修改,按状态着色);中间提交
  说明框;底部 Commit 与 Commit and Push... 线框按钮,右侧推送/拉取计数、
  AI 与设置
- 与变更列表之间只有一条分割线、无外框;拖动分割线或聚焦后按上/下方向键
  调整说明框高度(变更列表至少 96px,说明框最小 48px),松手后持久化
- 说明框:占位文字 "Commit Message / 提交说明";4px 圆角、1px 控件边框,
  聚焦 2px 强调色,出错时错误色
- 按钮不再因未选文件或说明为空而置灰;点击后按 IntelliJ CommitProgressPanel
  文案提示(请选择要提交的文件 / 请填写提交说明 / 二者合并),修正后消失;
  焦点在提交区内时 Commit 变为蓝色默认按钮
- Amend:勾选时读取当前 HEAD 的完整说明(标题 + 正文,新增
  getHeadCommitMessage,不再取 `git log --all` 列表首条);空草稿自动载入、
  不覆盖已输入内容、取消勾选且未编辑时恢复原草稿;HEAD 无提交时提示;
  Amend 模式下主按钮显示 Amend Commit,Commit and Push... 禁用(修正后
  需要强制推送),多仓库确认对话框按钮同步

变更列表
- 分组改为 IntelliJ 的 "Changes / 更改" 与 "Unversioned Files / 未版本控制
  的文件" 两个可展开树节点,节点名后显示灰色 "N 个文件"
- 文件、文件夹、分组节点的包含复选框移到左侧(箭头之后、图标之前),
  IDEA 新 UI 样式,分组与文件夹支持三态;文件夹名后紧跟灰色文件数
- 去掉文件行末尾的暂存 +/- 按钮及其工具代码
- 长文件名不截断,改为横向滚动:按文字真实小数宽度判断截断并留 1px 余量,
  面板从隐藏切回显示、侧栏改宽或字体加载完成后重新测量;状态刷新不再重置宽度
- 参考 IntelliJ ExpandableItemsHandler:名称超出可视右边缘时,悬停该行在
  行上方弹出完整名称(含文件数或目录),移开、滚动或点击即消失
- 工具栏新增 View Options(眼睛图标),菜单直接列出 "Directory / 目录" 与
  "Flat List / 平铺显示" 并勾选当前项,两次点击切换

其他
- 新增/更新单测:提交面板 Amend 与提示、拖动高度、分组节点与三态、复选框
  位置、行宽测量、悬停提示判断、视图选项切换、数据控制器不读取历史
- 更新 platform-feature-matrix 的 git-status-commit、git-history 行,新增
  git-status-colors-idea-alignment 行,并重新生成视图

* feat(windows): 活动栏、标题栏菜单与 Run 面板图标替换为 IDEA 图标

- 活动栏 Project / Git Log / Terminal / Run / Diagnostics 改用 IntelliJ expui toolwindows 图标
  (project、vcs、terminal、run、problems),亮色与暗色各一套
- 标题栏紧凑菜单开关新增 MenuIcon(expui/general/menu),不影响其他使用 ListIcon 的位置
- 新增 RunToolWindowIcon / ProblemsToolWindowIcon,避免改动全局 25 处使用的 WarningIcon
- Run 面板标题、空状态与命令面板统一使用 RunToolWindowIcon,移除自绘 RunIcon
- generate-idea-icons.ts 支持映射项 destination 字段,用于终端图标这类
  位于 platform/icons/src 之外(Jewel showcase 资源)的素材
- 更新 icons.test.tsx 的导出数量与双色渲染断言

* test(windows): svg-editor 测试结束后还原 locale-provider mock

bun 的 mock.module 在同一进程内会泄漏到后续测试文件。svg-editor.test.tsx
把 @/i18n/locale-provider 替换成只含 useTranslation 的桩且不还原,导致全量运行时
Commit 面板等依赖真实 LocaleProvider 的测试拿到桩而失败。

在安装 happy-dom 之前保存真实模块,并在 afterAll 中还原。buffer.store 的 mock
无法同样处理(导入真实模块会触发 Tauri 窗口 API),保持不变。

* fix(windows): Amend 按实际暂存仓库读取 HEAD,提交说明分隔条从显示高度起算

- Amend 目标由有暂存文件的仓库决定,而不是活动仓库:单仓库参与时读取该仓库的 HEAD,
  多仓库同时有暂存文件时禁用 Amend 并给出提示;目标仓库变化时撤销已加载的说明,
  并在说明未被修改时恢复原草稿
- 提交说明编辑框最多显示视口的 60%,拖动与方向键调整改为从实际显示高度开始,
  渲染与交互共用同一上限常量
- 补充 A 活动 / B 暂存、活动仓库无 HEAD、多仓库禁用、目标变化,以及窗口缩小后
  拖动与键盘调整的回归测试

* fix(git): Amend 绑定到明确的仓库与 HEAD,由 Core 拒绝多仓库改写

Core 建立提交计划时会重新读取所有仓库的暂存状态,而界面只基于缓存的状态读取
并展示了某一个仓库的提交说明。若读取之后又有别的仓库被暂存(例如外部终端,
且关闭了自动刷新),一个全局 amend 会让两个仓库共用同一条说明并同时被改写。

- Core: amend 时有暂存更改的仓库最多一个,否则 invalid_request 且不写入
- Core: 新增可选 amendTarget{repositoryId, expectedHead},拒绝未知目标、
  不一致的暂存仓库以及 HEAD 已移动(新提交或切分支)的请求;重试时目标
  已提交则跳过 HEAD 检查
- Core: 约束只在 prepare 校验,不写入 Plan,避免 macOS 的计划模型丢弃未知
  字段后 amend 悄悄变成普通提交;validate_session 兜底拒绝涉及多个暂存仓库的
  amend 续接。缺省 amendTarget 时保持单仓库下限,macOS 无需改动
- Windows: getHeadCommitMessage 同时返回 HEAD hash;面板记录读取说明的仓库与
  hash,提交与重试时转换为仓库标识发送,无法确认时提示重新加载
- 补充 Rust 单元与真实 Git 集成回归、前端面板与 API 测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* fix(git): 重试沿用计划记录的 Amend 仓库,父仓库不再被误改写

子仓库 Amend 成功而父仓库提交被钩子拒绝后,父仓库已暂存了新的子模块引用。
重试时 Core 根据当前暂存区重新推断 Amend 目标,会把它当作唯一的暂存仓库并
改写其原 HEAD,用户确认的“新增父引用提交”变成了历史改写。

- Core: Plan 新增 amendRepositoryId,首次建立计划时确定;step 只 Amend 该
  仓库,其余仓库(含只记录子模块引用的父仓库)做普通提交
- Core: 重试沿用 previous.plan 记录的仓库,指定不同 amendTarget 时拒绝;
  validate_session 拒绝指向未知仓库或非 Amend 计划的续接
- Core: 字段缺失(丢弃未知字段的客户端)时退回按暂存路径判断并限制为一个仓库,
  行为与此前一致
- Windows: 重试不再根据组件 ref 推断目标,直接交还上一次计划
- 补充真实 Git 回归(子 Amend 成功、父钩子失败、恢复后重试)及单元、前端测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* revert(windows): 移除 Commit 面板的 Amend 功能

Amend 在多仓库工作区里需要把“每个仓库的提交意图”做成 Swift 与 Rust 共享的
模型,当前 PR 内无法在 macOS 缺少构建验证的情况下安全完成,且反复引入回归。
本次先移除,Windows 提交面板恢复为只做普通提交。

- Windows: 删除 Amend 复选框、HEAD 说明读取、目标仓库推断、重试目标处理,
  以及确认框的 Amend Commit 文案和相关 i18n 键
- Core: workspace_commit 及其测试、共享契约与 Agent Note 还原为与 preview 一致,
  macOS 的 amend 布尔字段保持不变,Swift 无需改动
- 测试: 删除全部 Amend 用例,新增“提交始终为普通提交且不显示 Amend”断言
- 矩阵: 去掉功能说明中的 Amend 描述并重新生成
- 保留与 Amend 无关的修复:提交说明分隔条按实际显示高度调整、图标替换、
  svg-editor 测试的 locale mock 还原

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

---------

Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: lick <2188718831@qq.com>

* refactor(matrix): split capability records and generate views in CI (#1026)

* Merge pull request #1029 from 1lck/fix/macos-release-reliability

fix(release): 修复 macOS 发布超时与 Sparkle 基线下载重试

* Merge pull request #1004 from 1lck/codex/plugin-package-signing

feat(macos): 修复 PHP 插件下载逻辑问题——Part1

---------

Co-authored-by: Xiaoyumuxi <3075514079@qq.com>
Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: Lichenkang <2188718831@qq.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: 若水 <frankw.wang@qq.com>
1lck added a commit that referenced this pull request Oct 3, 2026
* feat(windows): add explorer Git context menu for diff, add and commit (#975)

Add an IDEA-style Git submenu to the project file tree context menu on
Windows, reusing the existing git-diff/git-status API layer without any
new Tauri commands:

- Files with Git changes get a Git submenu: Show Diff opens the file's
  working-tree (or staged) diff buffer, Add stages the file, and Commit
  File… stages it and focuses the Source Control commit panel.
- Directories inside a repository get Show Diff, which routes to the
  owning repository's changes panel.
- Menu visibility is driven by the file's real Git status via async
  repository discovery (nested repositories supported); clean files show
  no Git entries.
- Pure menu capability/builder logic lives in
  file-context-menu-git-file-items.ts with unit tests.
- Adds the git-explorer-context-actions platform feature matrix entry
  (Windows implemented / macOS partial) and an implemented agent note.

* test(windows): cover explorer Git context menu wiring contracts (#975)

Extract the context menu wiring invariants into the lib and pin them
with unit tests:

- hasGitDiffContent guards the empty-diff fallback chain.
- buildGitFileDiffBuffer pins the diff://<staged|unstaged>/<encoded>
  virtual buffer contract shared with use-git-diff-data.ts; changing
  either side would silently break stage/unstage inside the diff view.
- findGitStatusFileForPath covers status entry matching, including
  repositoryRelativePath preference over decorated paths and Windows
  separator normalization.
- isVirtualWorkspacePath keeps remote/wsl/diff paths Git-free.

The hook now consumes these helpers instead of local duplicates.
19 tests total, up from 8.

* docs(notes): 精简 Windows 文件树 Git 右键菜单笔记 (#975)

* fix(windows): dev 文件监视器忽略 Rust target 目录

tauri dev 启动时 vite watcher 会监视 src-tauri/target 下的构建产物,
与 cargo 并发写入在 Windows 上触发 EBUSY 使 watcher 崩溃、拽死 beforeDevCommand。
为 server.watch 增加 **/target/** 忽略,与 test.exclude 的既有排除意图一致。

* fix(windows): 文件树 Git 菜单改用幂等打开源代码管理面板 (#975)

按 PR #989 review 意见:Commit File… 与目录"显示差异"原先调用
toggleSourceControlSidebar(),在 Git 面板已打开的场景会把它反向关闭。
改为直接 setIsSidebarVisible(true) + setActiveView("git") 的幂等打开,
顺序为先 visible 后 view,保证工作区会话快照记录打开状态。
快捷键 Ctrl+Shift+G 的 toggle 语义不受影响。

* fix(windows): Git 菜单动作更名为暂存并打开提交以对齐语义 (#975)

按 PR #989 review 意见①(方案 B):提交面板提交的是当前暂存区全部
内容,无法保证只提交右键的单个文件,故菜单动作由 Commit File…
更名为 Stage and Open Commit…(暂存并打开提交…),行为零改动。
同步修正原注释中"暂存区即只含此文件"的不实表述,并更新功能矩阵
条目与 Agent Note 的措辞。

* fix(windows): Show Diff 改用携带仓库身份的 workingTreeTargets 缓冲 (#975)

按 PR #989 review 意见③:原实现的 diff://staged|unstaged/<相对路径>
buffer 不携带所属仓库,后续刷新/切换会误用工作区根目录,嵌套/多
仓库场景可能读错仓库。改用与 Git 面板单文件 diff 一致的
createSingleFileWorkingTreeDiff 载荷(workingTreeTargets 显式携带
repoPath),刷新按 target.repoPath 重读。取数与 staged 回退链不变,
仅替换打开段;lib 中 buildGitFileDiffBuffer 由
buildWorkingTreeDiffTarget 取代,测试同步 20 个。

* feat(macos): 文件树右键新增 Git 菜单(Add / Stage and Open Commit…)(#975)

按 reviewer 邀请对齐 Windows 端实现,只新增不改既有:
- GitFileContextMenuPlan 纯逻辑判定可见性(无变更不显示;已暂存或
  canToggleStaging=false 隐藏 Add),附 swift-testing 单测 5 例;
- ProjectTreeActions 追加 stageChange / stageAndOpenCommit(复用
  setStaging 与 selectedSidebar=.changes 既有 API);
- fileContextMenuItems 追加 Git 子菜单(Add / Stage and Open Commit…),
  Show Diff 复用既有独立菜单项不重复;目录端已有 Show Git Diff 不动。
矩阵 git-explorer-context-actions 的 macos 由 partial 更新为
implemented(verification 保持 pending,待 macOS CI 与实机验证)。

* feat(windows): add Git gutter with inline diff peek for editor (#1018)

Adds visual Git change markers in the editor gutter with click-to-peek inline diff viewer for Windows.

**New components:**
- GitGutterController: manages gutter decorations, peek widget lifecycle, and Monaco integration
- GitGutterPeekWidget: inline diff viewer with prev/next navigation, displays HEAD vs working tree
- git-gutter-changes: computes line-level diff markers (added/modified/deleted) from Git status and file diff
- use-git-gutter-base: React hook providing gutter data and navigation actions

**Settings:**
- New toggle "git.showGutterChanges" (default true) in Git Settings panel
- Search index updated for "gutter" and "inline diff" keywords

**Behavior:**
- Green bar: added lines; Blue bar: modified lines; Red triangle: deleted lines
- Click marker opens inline diff at that change
- Up/Down arrows navigate between changes
- Widget closes on Escape, editor blur, or file change
- Peek models disposed on widget close to prevent leaks

**Not included (for follow-up):**
- Revert/stage actions in peek widget (depends on PR #1015 merge)
- macOS implementation (Windows-only for now)

Refs #681

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: update README WeChat group QR code (#1020)

* fix(agent): 统一权限菜单与英文思考强度显示 (#1008)

* Merge pull request #1023 from Mucheen/fix/agent-selector-labels

fix(macos): 收紧 Agent 配置菜单并修复双行说明裁剪

* fix:macOS 项目树支持多选与批量文件操作 (#991)

* fix(macOS): 支持项目树多选与批量文件操作 (#987)

* docs: 记录 #987 macOS 项目树手动验证结果

* docs: 添加 #987 项目树多选手动验证截图

* fix(macOS): 处理 #991 审查意见并补齐项目树批量操作边界

- 批量删除:每项删除前重新检查未保存文档;废纸篓操作期间被改脏的文档保持打开,
  仅关闭未修改的文档;中途失败或被未保存文档阻止时提示剩余项目未移动。
- 快捷键归属:点击项目树后若键盘焦点移到文本框(如全局搜索)或其他控件,
  ⌘A/⌘C/⌘V 交还给当前焦点,不再误复制或粘贴文件。
- Control 点击恢复为 macOS 右键菜单,⌘ 点击负责增减选择;移除为此新增的
  litheContextMenu(capturesControlClick:) 参数。
- 单选高亮跟随活动编辑器文档;去掉 ProjectFileTreeContent 中冗余的可见节点比较。
- 中文“拷贝”与“复制(创建副本)”区分;补齐粘贴校验和批量删除提示的中英文案。
- 新增单元、焦点与应用级集成测试;功能矩阵改回待验证。

* fix(macOS): 项目树快捷键被处理后不再同时传给编辑器

本地事件监听里的 `self?.handle(event) ?? event` 会把表示“已处理”的 nil
展平成原事件,导致 ⌘A/⌘C/⌘V 在项目树处理后仍传给编辑器:⌘A 同时全选编辑器文本,
⌘V 同时把剪贴板文本粘进编辑器。改为直接返回 handle 的结果并补回归测试。

粘贴完成的提示由“已复制文件”改为“已粘贴文件”,避免复制和粘贴各弹一条相同提示。

* fix(macOS): 项目树 ⌘A 按焦点所在目录全选

焦点在展开的子目录内时,⌘A 只选中该目录下的可见项目;焦点在项目顶层时选中项目下全部可见项目(含子目录及其展开内容,不含根行);焦点在根行或无焦点时选中整棵可见树。重复 ⌘A 保持同一范围,并补充同名前缀目录不被误选的测试。

* fix(macOS): 项目树 ⌘A 选中焦点项的同级项目

点击文件夹后按 ⌘A,选中与该文件夹同级的项目,而不是它的内容;焦点在文件上时选中同目录文件;无焦点或焦点在项目行时选中项目顶层项目。同级关系按显示的树结构计算,压缩显示的 Java 包也使用其显示父节点。批量操作会自动包含已选文件夹的内容。

* fix(macOS): 已选文件夹下的展开内容同时显示为选中

文件夹被选中时,其下展开的文件和子目录也显示选中高亮,与批量操作会包含文件夹内容保持一致。这些子项只用于显示,不会重复加入操作集合;在多选组内右键这些子项仍保持整组,单独选中一个文件夹时右键其中的文件则以该文件为目标。

* ci: 重新触发 macOS Plugin CI

上次运行在 960 秒时限内仍在冷编译 LitheTests(Rust 4m39s,正常约 3m),尚未进入测试执行。同一提交的 macOS 主 Swift lane 已通过,本地按相同过滤条件运行 59 项插件测试全部通过。

* fix(macOS): 项目树 Shift/⌘ 点击从鼠标按下事件读取修饰键

SwiftUI Button 的动作在鼠标抬起后才执行,此时 NSApp.currentEvent 已不再是这次点击,
读到的修饰键为空,Shift 点击因此退化成普通单选、范围不生效。

- 新增 ProjectTreeModifiedClick 覆盖在每一行上:只在带 ⌘/Shift 的左键按下时命中,
  直接用该 mouseDown 事件的修饰键更新选择,并且不再传给 Button,因此不会打开文件或折叠目录。
- 普通点击和 Control 点击(右键菜单)都穿透到原有的 Button 和右键捕获视图,行为不变。
- selectRow 改为接收修饰键参数,Button 动作只做普通单选。
- 新增窗口级回归测试,覆盖 Shift 正向/反向范围选择、⌘ 取消选择、修饰点击不触发打开,以及 Control+Shift 不被捕获。

* test(macOS): 项目树修饰点击回归改为经窗口命中测试分发

审查指出原测试直接调用 overlay.mouseDown,绕过 hitTest 和窗口分发,即使
生产 hitTest 恒返回 nil 也会通过。

- 测试改为把合成的鼠标按下/抬起事件交给 NSWindow.sendEvent,由窗口命中测试
  决定交给覆盖层还是底层 Button;覆盖新增普通点击建立锚点、Shift 正反向范围、
  ⌘ 增减选择、修饰点击不触发 Button(不打开文件、不折叠目录)以及 Control
  点击穿透到底层行。
- ProjectTreeModifiedClickView 的当前事件来源改为可替换的 currentEvent,默认仍是
  NSApp.currentEvent。测试进程里经 NSApp 事件队列取出事件会让 swift-testing 的
  主队列提前退出,后续测试不再执行,所以测试只替换这一处查询。
- 反向验证:hitTest 恒返回 nil、或捕获 Control 点击时,新测试均失败。

* fix(macOS): 批量文件操作在整批结束前持有操作锁

处理 #991 审查的 P2/P3:

- 批量创建副本和批量移到废纸篓原来逐项调用单项入口,每项结束后都会先释放
  isPerformingProjectItemOperation 再 await 刷新。刷新期间用户可以启动别的文件操作,
  原批次的后续项随后被入口守卫静默跳过。现在由外层批次持有操作锁直到整批结束,
  内层拆成不自行加锁、不刷新的单项实现,整批完成后只刷新一次。
- 单项粘贴和单项删除仍通过同一实现,行为不变。
- 中文“Copied files”改为“已拷贝文件”,与菜单“拷贝”一致。
- 新增回归:第一组复制暂停时操作锁保持占用、插入的粘贴被拒绝,批量复制和
  批量删除各只在最后一项完成后刷新一次。恢复旧实现时该测试失败。

---------

Co-authored-by: Lichenkang <2188718831@qq.com>

* fix(agent): 修复 Claude 鉴权、会话切换和品牌图标 (#1007)

* fix(agent): 修复 Claude 鉴权、会话切换和品牌图标

通过 Claude 适配器公开会话参数传递 API Key 路由,同时覆盖新建与历史恢复,清除冲突鉴权并保留 Codex gateway 行为。
直接观察所选 Agent 连接,等待会话设置确认后展示模型,防止旧配置闪现及准备期间提交。
统一底栏、模型入口与 Agent 菜单品牌图标,保留原生单选勾选,并补充回归、共享契约、Agent Note 与功能矩阵。

* test(git): bound graph frame sampling to visible viewports

修复 PR #1007 CI:原用例重复绘制完整 1000 行历史,CI 耗时 11.791 秒超过未调整的 10 秒上限。改为开头、中段、末段 40 行视口采样,校验实际像素,保留完整结构、单帧预算与 Release 基线;同步 CI 文档和中文工程笔记。

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

* feat(windows): 活动栏/标题栏/Run 面板图标替换为 IDEA 图标,并对齐 Commit 面板与共用控件 (#1025)

* feat(windows): 共用 UI 组件补齐 IDEA 风格交互基础能力

- 滚动条:修复 ScrollArea 滑块带 flex-1 被拉满整条轨道的问题,改由
  Base UI 按可视比例计算滑块长度(全局所有滚动区域受益)
- 触控板:ScrollArea 的滚轮转发支持横向滑动,仅横向可滚动的容器才
  处理,纵向列表行为不变
- 树行 SidebarTreeRow:
  - 新增 leadingAction 左侧操作位(位于展开箭头之后、图标之前),
    渲染在行按钮外并按缩进定位,避免按钮嵌套交互元素
  - 新增 variant="idea":16px 细线 chevron(IDEA expui 路径、
    tree-chevron 颜色、悬停不变色),箭头/复选框/图标/文字 4px 间距,
    图标与文字垂直居中
  - 文字区增加 data-sidebar-tree-label 供横向滚动测量
- 复选框:支持 indeterminate 半选状态,显示短横
- 拖动会话 document-resize-session:新增 axis: "y",可驱动纵向高度
- 新增对应单测(横向滑动、纵向拖动)

* feat(windows): 默认主题 Git 状态配色与表单控件 token 对齐 IDEA

配色取自 intellij-community expUI 明暗配色方案(FILESTATUS_* 与 *_LINES_COLOR):
- modified / renamed:#0033B3 / #70AEFF;暂存修改为浅蓝派生 #2652BE / #85BAFF
- added:#067D17 / #73BD79;untracked:#B23247 / #E88F89
- 新增可选 token git-file-deleted(删除文件灰 #6C707E / #6F737A);
  git-deleted 仍为红色,继续用于 diff 删除行与 -N 计数
- 新增可选 token git-gutter-added/modified/deleted,编辑器 gutter 使用
  IDEA 浅色行标记(#7FC784/#88ADF7/#767A8A,暗色 #549159/#375FAD/#868A91)
- 变更列表、提交文件树、文件树的状态颜色统一走 git-* token,
  不再使用 text-info / 灰色 / 红色临时映射
- 新增 IDEA 表单控件 token:control-border、checkbox-border、
  checkbox-background、tree-chevron
- 以上新 token 在其他主题中未定义时,均回退到原有颜色
- rebase / patch / 历史改写对话框的警告文案与操作横幅由误用的
  text-git-modified 改回 text-warning,避免随 modified 变蓝

* feat(windows): Commit 面板对齐 IntelliJ(提交区、变更列表、Amend 与视图选项)

面板与入口
- 侧栏 git 入口与面板标题由 Changes / Source Control 更名为 Commit(提交),
  图标换为 IntelliJ commit 图标;中英文案、tooltip、aria 同步
- 移除面板内 Changes / History 标签栏与 git-commit-history 组件,提交历史
  统一通过底部 Git Log 工具窗浏览;命令面板去掉 "Git: Show History"
- 清理仅服务于标签的设置 rememberLastGitPanelMode / gitLastPanelMode /
  gitSidebarTabOrder,并加入 RETIRED_SETTINGS_KEYS 清理升级用户的残留键
- Git 数据控制器不再读取 `git log --all`;"与提交比较"选择器打开时才按需
  加载最近 50 条提交

提交区(对齐 NonModalCommitPanel / CommitInputBorder / CommitLegendComponent)
- 布局:顶部左侧 Amend、右侧已选文件图例(N 添加 / N 修改 / N 删除,未跟踪
  计入添加并显示为“新增+未跟踪”,重命名计入修改,按状态着色);中间提交
  说明框;底部 Commit 与 Commit and Push... 线框按钮,右侧推送/拉取计数、
  AI 与设置
- 与变更列表之间只有一条分割线、无外框;拖动分割线或聚焦后按上/下方向键
  调整说明框高度(变更列表至少 96px,说明框最小 48px),松手后持久化
- 说明框:占位文字 "Commit Message / 提交说明";4px 圆角、1px 控件边框,
  聚焦 2px 强调色,出错时错误色
- 按钮不再因未选文件或说明为空而置灰;点击后按 IntelliJ CommitProgressPanel
  文案提示(请选择要提交的文件 / 请填写提交说明 / 二者合并),修正后消失;
  焦点在提交区内时 Commit 变为蓝色默认按钮
- Amend:勾选时读取当前 HEAD 的完整说明(标题 + 正文,新增
  getHeadCommitMessage,不再取 `git log --all` 列表首条);空草稿自动载入、
  不覆盖已输入内容、取消勾选且未编辑时恢复原草稿;HEAD 无提交时提示;
  Amend 模式下主按钮显示 Amend Commit,Commit and Push... 禁用(修正后
  需要强制推送),多仓库确认对话框按钮同步

变更列表
- 分组改为 IntelliJ 的 "Changes / 更改" 与 "Unversioned Files / 未版本控制
  的文件" 两个可展开树节点,节点名后显示灰色 "N 个文件"
- 文件、文件夹、分组节点的包含复选框移到左侧(箭头之后、图标之前),
  IDEA 新 UI 样式,分组与文件夹支持三态;文件夹名后紧跟灰色文件数
- 去掉文件行末尾的暂存 +/- 按钮及其工具代码
- 长文件名不截断,改为横向滚动:按文字真实小数宽度判断截断并留 1px 余量,
  面板从隐藏切回显示、侧栏改宽或字体加载完成后重新测量;状态刷新不再重置宽度
- 参考 IntelliJ ExpandableItemsHandler:名称超出可视右边缘时,悬停该行在
  行上方弹出完整名称(含文件数或目录),移开、滚动或点击即消失
- 工具栏新增 View Options(眼睛图标),菜单直接列出 "Directory / 目录" 与
  "Flat List / 平铺显示" 并勾选当前项,两次点击切换

其他
- 新增/更新单测:提交面板 Amend 与提示、拖动高度、分组节点与三态、复选框
  位置、行宽测量、悬停提示判断、视图选项切换、数据控制器不读取历史
- 更新 platform-feature-matrix 的 git-status-commit、git-history 行,新增
  git-status-colors-idea-alignment 行,并重新生成视图

* feat(windows): 活动栏、标题栏菜单与 Run 面板图标替换为 IDEA 图标

- 活动栏 Project / Git Log / Terminal / Run / Diagnostics 改用 IntelliJ expui toolwindows 图标
  (project、vcs、terminal、run、problems),亮色与暗色各一套
- 标题栏紧凑菜单开关新增 MenuIcon(expui/general/menu),不影响其他使用 ListIcon 的位置
- 新增 RunToolWindowIcon / ProblemsToolWindowIcon,避免改动全局 25 处使用的 WarningIcon
- Run 面板标题、空状态与命令面板统一使用 RunToolWindowIcon,移除自绘 RunIcon
- generate-idea-icons.ts 支持映射项 destination 字段,用于终端图标这类
  位于 platform/icons/src 之外(Jewel showcase 资源)的素材
- 更新 icons.test.tsx 的导出数量与双色渲染断言

* test(windows): svg-editor 测试结束后还原 locale-provider mock

bun 的 mock.module 在同一进程内会泄漏到后续测试文件。svg-editor.test.tsx
把 @/i18n/locale-provider 替换成只含 useTranslation 的桩且不还原,导致全量运行时
Commit 面板等依赖真实 LocaleProvider 的测试拿到桩而失败。

在安装 happy-dom 之前保存真实模块,并在 afterAll 中还原。buffer.store 的 mock
无法同样处理(导入真实模块会触发 Tauri 窗口 API),保持不变。

* fix(windows): Amend 按实际暂存仓库读取 HEAD,提交说明分隔条从显示高度起算

- Amend 目标由有暂存文件的仓库决定,而不是活动仓库:单仓库参与时读取该仓库的 HEAD,
  多仓库同时有暂存文件时禁用 Amend 并给出提示;目标仓库变化时撤销已加载的说明,
  并在说明未被修改时恢复原草稿
- 提交说明编辑框最多显示视口的 60%,拖动与方向键调整改为从实际显示高度开始,
  渲染与交互共用同一上限常量
- 补充 A 活动 / B 暂存、活动仓库无 HEAD、多仓库禁用、目标变化,以及窗口缩小后
  拖动与键盘调整的回归测试

* fix(git): Amend 绑定到明确的仓库与 HEAD,由 Core 拒绝多仓库改写

Core 建立提交计划时会重新读取所有仓库的暂存状态,而界面只基于缓存的状态读取
并展示了某一个仓库的提交说明。若读取之后又有别的仓库被暂存(例如外部终端,
且关闭了自动刷新),一个全局 amend 会让两个仓库共用同一条说明并同时被改写。

- Core: amend 时有暂存更改的仓库最多一个,否则 invalid_request 且不写入
- Core: 新增可选 amendTarget{repositoryId, expectedHead},拒绝未知目标、
  不一致的暂存仓库以及 HEAD 已移动(新提交或切分支)的请求;重试时目标
  已提交则跳过 HEAD 检查
- Core: 约束只在 prepare 校验,不写入 Plan,避免 macOS 的计划模型丢弃未知
  字段后 amend 悄悄变成普通提交;validate_session 兜底拒绝涉及多个暂存仓库的
  amend 续接。缺省 amendTarget 时保持单仓库下限,macOS 无需改动
- Windows: getHeadCommitMessage 同时返回 HEAD hash;面板记录读取说明的仓库与
  hash,提交与重试时转换为仓库标识发送,无法确认时提示重新加载
- 补充 Rust 单元与真实 Git 集成回归、前端面板与 API 测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* fix(git): 重试沿用计划记录的 Amend 仓库,父仓库不再被误改写

子仓库 Amend 成功而父仓库提交被钩子拒绝后,父仓库已暂存了新的子模块引用。
重试时 Core 根据当前暂存区重新推断 Amend 目标,会把它当作唯一的暂存仓库并
改写其原 HEAD,用户确认的“新增父引用提交”变成了历史改写。

- Core: Plan 新增 amendRepositoryId,首次建立计划时确定;step 只 Amend 该
  仓库,其余仓库(含只记录子模块引用的父仓库)做普通提交
- Core: 重试沿用 previous.plan 记录的仓库,指定不同 amendTarget 时拒绝;
  validate_session 拒绝指向未知仓库或非 Amend 计划的续接
- Core: 字段缺失(丢弃未知字段的客户端)时退回按暂存路径判断并限制为一个仓库,
  行为与此前一致
- Windows: 重试不再根据组件 ref 推断目标,直接交还上一次计划
- 补充真实 Git 回归(子 Amend 成功、父钩子失败、恢复后重试)及单元、前端测试
- 更新 rust-core-api 契约与工作区提交 Agent Note

* revert(windows): 移除 Commit 面板的 Amend 功能

Amend 在多仓库工作区里需要把“每个仓库的提交意图”做成 Swift 与 Rust 共享的
模型,当前 PR 内无法在 macOS 缺少构建验证的情况下安全完成,且反复引入回归。
本次先移除,Windows 提交面板恢复为只做普通提交。

- Windows: 删除 Amend 复选框、HEAD 说明读取、目标仓库推断、重试目标处理,
  以及确认框的 Amend Commit 文案和相关 i18n 键
- Core: workspace_commit 及其测试、共享契约与 Agent Note 还原为与 preview 一致,
  macOS 的 amend 布尔字段保持不变,Swift 无需改动
- 测试: 删除全部 Amend 用例,新增“提交始终为普通提交且不显示 Amend”断言
- 矩阵: 去掉功能说明中的 Amend 描述并重新生成
- 保留与 Amend 无关的修复:提交说明分隔条按实际显示高度调整、图标替换、
  svg-editor 测试的 locale mock 还原

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全 (#1016)

* feat(agent): 显示 Agent 思考、计划与斜杠命令补全

共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、
标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新:

- agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或
  工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出
  Markdown 以引用块保留,历史消息数不计思考
- plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体
  替换,空计划清除
- available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀
  优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name),
  输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab
- current_mode_update:Agent 自行切换模式时同步权限模式选择器

另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化,
补齐 zh-Hans 翻译。

fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与
shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报
命令列表、Claude 会上报思考,界面层验证仍待完成。

* fix(agent): 修复命令补全布局和思考搜索展开

为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。

* fix(ci): release Windows Bun install process trees before retry

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

---------

Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: lick <2188718831@qq.com>

* refactor(matrix): split capability records and generate views in CI (#1026)

* Merge pull request #1029 from 1lck/fix/macos-release-reliability

fix(release): 修复 macOS 发布超时与 Sparkle 基线下载重试

* Merge pull request #1004 from 1lck/codex/plugin-package-signing

feat(macos): 修复 PHP 插件下载逻辑问题——Part1

---------

Co-authored-by: genhaosan <3042136826@qq.com>
Co-authored-by: lick <2188718831@qq.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: sinth <2235390062@qq.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
Co-authored-by: 若水 <frankw.wang@qq.com>
Co-authored-by: Xiaoyumuxi <3075514079@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: medium ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants