feat: add bounded diagnostics and improve UX feedback

Ask and Execute guidance, Runtime state, live announcements, loading states,
retry paths, settings focus, and update failures now provide consistent and
accessible feedback across the desktop experience.

Add bounded redacted Desktop and Agent diagnostic logs, a read-only Agent
diagnostics command, and an explicit opt-in for attaching a small Desktop
diagnostic summary to in-app feedback. Diagnostics stay local by default and
the existing feedback v1 service contract remains compatible.

Release note: 新增可选桌面诊断反馈与 Agent 诊断导出,并统一 Ask/Execute 状态、错误恢复和无障碍反馈;诊断默认保留在本地,仅在用户明确勾选时附加桌面摘要。
This commit is contained in:
mesalogo
2026-08-31 15:35:13 +08:00
parent b1729125e1
commit 2833a27f83
60 changed files with 4679 additions and 216 deletions
+1
View File
@@ -38,6 +38,7 @@ GoodBuddy 文档按“文档类型 → 功能域”组织。新增文档应先
- [SSH Host 远程环境准备与控制面直连设计](./architecture/remote-host-environment-provisioning-design.md)
- [跨平台助手产品设计](./design/cross-platform-assistant-product-design.md)
- [长期助手路线图](./roadmap/long-term-assistant-roadmap.md)
- [产品、性能与体验综合改进计划](./roadmap/product-performance-experience-improvement-plan.md)
- [电脑控制实施状态](./status/computer-control-implementation-status.md)
- [知识检索评估](./quality/knowledge-retrieval-evaluation.md)
- [GoodBuddy 龙芯(LoongArch)预览版构建与功能列表](./development/loongarch-preview-build.md)
@@ -45,8 +45,9 @@ Main 进程职责、公共 API 对接、失败处理和验收方法。反馈平
以此保证幂等;创建另一条反馈时才生成新 ID。
10. GoodBuddy 使用单独的随机安装 UUID 做服务端限流。该 UUID 不得复用 Agent
installation ID、硬件 ID、机器名、用户名、项目 ID 或任何设备指纹。
11. 默认不发送对话、提示词、模型回复、日志、文件、项目或工作区路径、知识库、模型配置、
Runtime 配置、API Key、Token、Cookie、SSH 信息、剪贴板或屏幕内容。
11. 默认不发送对话、提示词、模型回复、诊断、日志、文件、项目或工作区路径、知识库、模型
配置、Runtime 配置、API Key、Token、Cookie、SSH 信息、剪贴板或屏幕内容。用户可通过
默认关闭的 Checkbox 主动附加有界的最近桌面诊断摘要。
12. 反馈提交失败时保留全部表单内容和截图,成功后显示可复制的服务端反馈编号。
13. 首版不提供反馈历史、状态查询、编辑、撤回、自动日志收集或服务端管理入口。
14. 生产接口固定为 `https://imp.mesalogo.com/api/v1/feedback`。域名健康检查、
@@ -79,7 +80,8 @@ Main 进程职责、公共 API 对接、失败处理和验收方法。反馈平
- GitHub Issue 创建、GitHub Token 或 GitHub 网页附件上传。
- GoodBuddy 内的管理员后台、处理状态修改或内部备注。
- 用户账户、登录、反馈列表、远程状态查询或推送通知。
- 自动附加当前对话、日志、错误堆栈、项目、文件、模型或 Runtime 信息。
- 自动附加当前对话、桌面诊断、日志、错误堆栈、项目、文件、模型或 Runtime 信息。
- 远端 Agent 日志或通用日志、诊断包和附件框架。
- 自动截取全屏、当前窗口、浏览器、远程桌面或其他应用窗口。
- 多截图、视频、录屏、任意文件附件或压缩包。
- 离线队列、后台自动重试、指数退避、跨重启草稿或发送历史。
@@ -113,16 +115,23 @@ Main 进程职责、公共 API 对接、失败处理和验收方法。反馈平
- 使用体验:`experience`
- 其他:`other`
2. **标题**,必填,1 至 120 字符。
3. **详细描述**,必填,去除首尾空白后 10 至 5,000 字符。
4. **联系邮箱**,可选,最多 254 字符。
5. **截图**,可选,最多一张,支持选择 PNG/JPEG/WebP 或在对话框中粘贴图片。
6. **将发送的信息**,只读显示应用版本、系统、架构和界面语言。
7. **隐私说明**,紧邻提交操作。
3. **详细描述**,必填,去除首尾空白后 10 至 5,000 字符;选择桌面诊断时为摘要预留空间,
用户描述上限为 3,398 字符。
4. **附加最近桌面诊断记录**,可选的原生 Checkbox,默认关闭。
5. **联系邮箱**,可选,最多 254 字符。
6. **截图**,可选,最多一张,支持选择 PNG/JPEG/WebP 或在对话框中粘贴图片。
7. **将发送的信息**,只读显示应用版本、系统、架构和界面语言。
8. **隐私说明**,紧邻提交操作。
隐私说明使用明确文案:
> 将发送反馈类型、标题、描述、可选邮箱、GoodBuddy 版本、操作系统、架构、界面语言,
> 以及你主动添加的截图。不会自动发送对话、日志、文件、项目路径、模型配置或凭据。
> 以及你主动添加的截图。默认不上传桌面诊断;只有勾选后才会把有界诊断摘要追加到描述。
> 不会发送对话、Prompt、凭据、文件内容、路径、Provider 原始响应或远端 Agent 日志。
Checkbox 下方持续说明:诊断摘要只含时间、组件、阶段、稳定错误码、错误类型和固定短消息。
Renderer 不预览、不读取也不接收诊断内容或路径。勾选后详细描述上限为 3,398 字符,为附加
摘要预留 1,600 字符以及分隔换行;超长草稿保留在表单中并显示字段错误,不静默截断。
截图区域必须包含:
@@ -167,7 +176,7 @@ Main 进程职责、公共 API 对接、失败处理和验收方法。反馈平
| `productKey` | Main 常量 `goodbuddy` | 服务端产品路由 |
| `category` | 用户选择 | 分流反馈 |
| `title` | 用户输入 | 摘要 |
| `description` | 用户输入 | 问题和建议详情 |
| `description` | 用户输入;勾选时由 Main 追加桌面诊断摘要 | 问题、建议和主动提供的有界诊断详情 |
| `contactEmail` | 用户可选输入 | 必要时联系用户 |
| `environment.appVersion` | `app.getVersion()` | 判断受影响版本 |
| `environment.platform` | `process.platform` 映射 | 判断受影响平台 |
@@ -197,8 +206,9 @@ Main 进程职责、公共 API 对接、失败处理和验收方法。反馈平
- 剪贴板、屏幕、摄像头、麦克风或其他应用内容。
- Remote Agent installation ID、Runtime ID、Conversation ID、Task ID 或 Project ID。
未来若增加日志、诊断包或其他附件,必须单独设计字段、预览、大小限制、用户选择和服务端
保留策略,不能复用截图字段静默上传。
除上述用户主动选择、追加到描述且有界的桌面诊断摘要外,未来若增加日志、诊断包或其他
附件,必须单独设计字段、预览、大小限制、用户选择和服务端保留策略,不能复用截图字段
静默上传。
### 4.3 本地数据生命周期
@@ -289,6 +299,7 @@ HTTP 201 表示首次创建,HTTP 200 表示相同 `clientRequestId` 的幂等
| 500–599 | 提示服务暂时异常,保留草稿 |
| 超时 / DNS / TLS / 离线 | 提示无法连接反馈服务,保留草稿 |
| 响应格式错误 | 提示服务返回无效结果,不能猜测成功 |
| 本地诊断读取失败 | 不发送反馈,保留草稿、勾选状态和请求 ID,提示重试或取消勾选 |
首版不自动重试。自动重试容易让用户无法判断是否已经发送,也会在服务持续异常时制造额外
流量。用户点击“重试”时复用同一个 `clientRequestId`。
@@ -330,6 +341,7 @@ type FeedbackSubmitInput = {
category: 'bug' | 'feature' | 'experience' | 'other'
title: string
description: string
includeDiagnostics: boolean
contactEmail?: string
locale: 'zh-CN' | 'en-US'
clientRequestId: string
@@ -341,7 +353,7 @@ type FeedbackSubmitInput = {
```
Renderer 不能传入 `productKey`、`appVersion`、`platform`、`architecture` 或
`installationId`。这些字段由 Main 从受信运行环境生成。
`installationId`,也不能传入诊断内容或路径。这些字段由 Main 从受信运行环境生成。
### 6.3 IPC 与 Preload
@@ -402,6 +414,12 @@ Main-only `FeedbackService` 负责:
- 映射应用版本、平台和架构。
- 验证并标准化可选截图。
- 组装严格的公共 payload。
- 仅在 `includeDiagnostics: true` 时通过注入的 DesktopDiagnostics provider 读取最多 20 条
最近记录;默认提交完全不调用诊断 provider。
- 将诊断格式化为带
`[GOODBUDDY_DESKTOP_DIAGNOSTICS_V1_BEGIN]` /
`[GOODBUDDY_DESKTOP_DIAGNOSTICS_V1_END]` 明确分隔、最多 1,600 字符且只保留完整 JSON
行的摘要。无记录时写入固定 `{"status":"no-recent-diagnostics"}` 事实。
- 调用 HTTP Client。
- 维持单次提交的 AbortController,并在 dispose / 清除本地数据时取消。
@@ -416,6 +434,11 @@ Main-only `FeedbackService` 负责:
架构只保留 `x64` 和 `arm64`,其他值映射为 `unknown`。
公共 API 继续使用 `schemaVersion: 1` 和原有固定字段。`includeDiagnostics` 只属于客户端
IPC 输入,不进入公共 payload,也不新增 multipart 字段;Main 把摘要追加到
`payload.description`。默认未勾选时,公共 payload 与既有实现逐字段一致。诊断读取失败时
不得发送部分摘要或声称已附加,必须返回可本地化的 `diagnostics-unavailable` 错误。
### 6.6 严格 HTTPS Client
反馈客户端使用 `undici` 的独立 `Agent`:
@@ -618,7 +641,8 @@ Endpoint 的健康检查和无副作用 schema 探针也必须在发布前通过
- 普通文本粘贴不被图片处理拦截。
- 截图选择、预览、替换、移除和 Object URL 清理。
- 并发截图读取按最新选择生效,关闭对话框后不会留下待处理 Object URL。
- 失败保留字段,重试使用原 `clientRequestId`。
- 失败保留字段、诊断勾选状态,重试使用原 `clientRequestId`。
- 默认提交不读取诊断且公共 payload 不变;主动附加、描述预算、无记录和读取失败均有覆盖。
- 成功显示真实编号并清空后续新草稿。
- Dialog role、初始焦点、Tab 循环、Escape 和焦点恢复。
- 浅色、深色、窄窗口和 reduced motion。
@@ -666,8 +690,9 @@ npm run build
- Endpoint 域名变化属于客户端发布变更,不能依赖 301/302 迁移。
- 入口发布与 `goodbuddy` 产品启用状态、生产 TLS 和 v1 契约保持同一发布门槛。
- 此功能不迁移现有用户数据;只新增可重置的随机反馈安装身份。
- 发布说明应明确:用户现在可以在“关于与更新”内直接提交反馈,邮箱和截图可选,应用不会
自动附加对话、日志、文件或凭据。
- 发布说明应明确:用户现在可以在“关于与更新”内直接提交反馈,邮箱和截图可选;桌面诊断
默认不上传,只有用户勾选后才附加有界摘要,并且不会发送对话、Prompt、凭据、文件内容、
路径、Provider 原始响应或远端 Agent 日志。
---
@@ -52,6 +52,7 @@ Detached GoodBuddy Agent
-> Agent-owned OpenCode ACP Prompt Promise
-> Prompt-scoped Provider gateway / model-call ledger
-> 有界语义 transcript / page / ACK
-> 有界私有诊断记录
-> 直接拥有的 Runtime 进程
```
@@ -369,6 +370,16 @@ model bridge,以及生命周期和恢复逻辑。单元测试、mock、fixture
终态,语义 `latest=ACK=29`,清理计数同样为 0。最终补充验证共 3 次真实文本模型调用。
采证后已按 PID/starttime/executable 停止精确隔离 daemon 并删除隔离 Host 测试根目录;
`/root/.goodbuddy` 下的共享 Agent 安装和进程未被修改。
- 2026-08-31 使用当前工作树短期测试签名 Linux x64 候选,在全新隔离 HOME 和 installation
中验证有界诊断:bootstrap、detached daemon、attach、relay 断开与同 controller 重连、
`controller/resume`、Runtime candidate 激活和 OpenCode ACP 进程启动均通过;新
`diagnostics --installation-id` 命令在 daemon 重启后读取到 23 条完整 JSONL。诊断目录
为 `0700`、文件为 `0600`,单文件 3719 bytes,未超过 64 KiB。六类测试哨兵覆盖 Prompt、
密钥、环境、SSH 参数、用户文件内容和原始错误消息,CLI 输出与磁盘均未出现哨兵。把隔离
diagnostics 目录临时设为不可写后,Attach 和 `agent/status` 仍正常;随后已恢复权限。
本次未注入模型凭据或执行 Prompt,真实文本模型调用 0 次;三文件轮转继续由聚焦测试覆盖。
测试结束前按 PID、UID、starttime、executable 和唯一 installation 核对并停止所有本次
daemon,本地及 Host 临时目录均已清理,共享 current Agent 和 `/root/.goodbuddy` 未修改。
- 正常 Host 更新路径把 Linux x64 Host 的 Agent 更新为 `0.11.2-e2e.12`,并确认
OpenCode Runtime 已安装版本与所需版本均为 `1.18.9`。
- 一条新的 Ask 用户操作只提交一次。OpenCode 先在 build 模型轮次请求一个原生
@@ -420,6 +431,31 @@ v32 保留项目及关联用户数据,并加入 remote-recoverable Task/messag
执行空间表保持 `project_id/kind/root_path/ssh_host_id`
四列,并删除旧 Runtime 验证表。
## Agent 有界诊断
Detached Agent 不依赖 stdio 留存故障证据。每个 installation 在固定私有目录
`~/.goodbuddy/state/<installationId>/diagnostics/` 中维护
`agent-diagnostics.jsonl`、`.1` 和 `.2`,每个文件不超过 64 KiB,目录权限为 `0700`,
文件权限为 `0600`。记录覆盖 daemon 启停、detached 启动、连接、恢复和 Runtime
启动/退出;每条只包含固定事件、时间、PID、可选工作模式、固定原因和白名单错误码。
诊断写入使用最多 64 条的有界异步队列。连接、恢复和 Runtime 回调只把已经归一化的固定
记录入队,不等待磁盘;原始 `Error` 不进入队列。队列满、目录不可写或轮转失败只丢弃诊断,
不得改变 Attach、协议、Runtime 或退出结果。daemon 停止和 bootstrap 生命周期结束时执行
有界 flush。多个 Agent 进程通过 GoodBuddy 私有短期锁协调 append 和轮转,不把长期锁作为
运行前提。
已安装 Agent 提供只读固定命令:
```text
goodbuddy-agent diagnostics --installation-id <installationId>
```
该命令只能从 installation 对应的固定 state 目录读取上述有界文件,并逐行输出已验证 JSONL;
不接受任意路径,也不扩展 Agent protocol。诊断不得包含 accepted Prompt、模型输入输出、
模型密钥、完整配置、环境变量、SSH 参数、用户文件内容、路径或原始错误消息。应用内反馈的
“附加最近桌面诊断记录”只读取 Desktop 诊断,不会自动取得或上传这些远端 Agent 记录。
## 资源与发布
- 所有桌面构建(包括 `portable` 与 `release:package`)只携带
@@ -0,0 +1,563 @@
# GoodBuddy 产品、性能与体验综合改进计划
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 文档类型 | 跨功能实施路线图 |
| 状态 | 规划中 |
| 版本 | 1.0 |
| 日期 | 2026-08-31 |
| 适用范围 | GoodBuddy Desktop、GoodBuddy Agent、发布与质量流程 |
| 评审基线 | Desktop `0.11.13`、Agent lock `0.11.14` |
## 1. 目的
本文把 2026-08-31 对当前仓库进行的功能、性能、体验和交付评审结果整理为一份可分批实施、
持续更新的权威清单。后续每一批工作都从本文选择明确范围,完成后更新状态、验证结果和相关
产品文档,不再维护平行的临时待办。
本计划优先完成已经存在但尚未形成真实用户闭环的能力,其次处理经过测量确认的性能问题,
再安排依赖外部平台或产品选择的增强能力。实施继续遵循以下原则:
1. 先保证完整、可用的生产路径,再扩展能力范围。
2. 性能优化必须有基线、目标和优化后的对比数据。
3. 复用现有合同、IPC、Worker、通知、错误边界和界面组件,不引入不必要的框架。
4. Ask 保持只读;Execute 继续代表当前本机或 SSH 账号的完整授权。
5. 每批只处理列明的范围,不借机进行无关重构。
## 2. 明确排除的工作
本计划**不包含初始 Renderer Bundle 优化**,包括但不限于:
- 不为了缩小入口包继续拆分轻量同级页面。
- 不单独延迟 KaTeX、全局样式或其他入口依赖。
- 不调整现有 Bundle 预算来制造通过或失败。
- 不以 Bundle 大小为理由改变当前页面交互语义。
现有构建预算和按路由拆包继续作为回归保护保留。只有后续获得首屏解析或执行耗时证据,并由
用户单独确认范围后,才重新讨论该项。
## 3. 状态与优先级
### 3.1 状态
| 状态 | 含义 |
| --- | --- |
| 待开始 | 范围已确认,尚未实施 |
| 进行中 | 已进入当前实施批次 |
| 阻塞 | 存在明确外部依赖,已记录解除条件 |
| 已完成 | 代码、真实路径、测试和文档均完成 |
| 不做 | 经重新评审后明确移出范围,并记录原因 |
### 3.2 优先级
| 优先级 | 含义 |
| --- | --- |
| P0 | 影响正式交付、安装或已声明生产路径,发布前处理 |
| P1 | 阻断核心工作流或造成明显错误、卡顿、误导 |
| P2 | 重要增强或规模化问题,可在核心闭环后实施 |
## 4. 分批实施总览
批次表示建议顺序,不表示必须一次完成整批。每次可以从当前批次选择一组边界清晰、能够独立
验收的事项。
| 批次 | 主题 | 事项 | 开始条件 | 完成门槛 |
| --- | --- | --- | --- | --- |
| 0 | 正式交付闭环 | `REL-01` 至 `REL-03`、`QA-03` | 发布资源和目标平台明确 | 正式产物可安装、可启动,版本与验证声明准确 |
| 1 | 核心工作流与恢复体验 | `FUN-01`、`FUN-04`、`UX-01` 至 `UX-12`、`OPS-01` 至 `OPS-03` | 无 | 用户可理解状态、从常见失败中直接恢复,并能导出有界诊断 |
| 2 | 通道、更新和真实 Runtime | `FUN-02`、`FUN-03`、`FUN-05`、`QA-01`、`QA-02` | 对应平台测试配置可用 | 文件办公闭环、更新下载闭环和真实 Runtime E2E 均通过 |
| 3A | 性能基线 | `PERF-01`、`PERF-03`、`PERF-05`、`PERF-07`、`PERF-09` | 固定测试数据和设备 | 形成可重复基线、目标阈值和原始结果 |
| 3B | 已测量性能优化 | `PERF-02`、`PERF-04`、`PERF-06`、`PERF-08`、`PERF-10` | 对应 3A 指标确认存在瓶颈 | 指标改善且功能、取消、恢复语义不回退 |
| 4 | 增强能力 | `FUN-06` 至 `FUN-09` | 核心闭环稳定;首个电脑控制平台已选定 | 每项形成独立、完整、可真实使用的工作流 |
## 5. 发布与交付
### REL-01 Desktop 与 Agent 版本闭环
- **优先级 / 状态:** P0 / 待开始
- **目标:** 当前 Desktop 源码依赖的 Agent 能从正式渠道取得并完成真实 Host 验证。
- **范围:**
- 发布并验证 Agent `0.11.14`,或在 Desktop 发布前恢复到已发布 Agent 契约。
- 验证 Linux x64、Linux arm64 正式候选包。
- 覆盖安装、Attach、Execute、取消和断线恢复。
- 覆盖 GitHub、镜像和离线 GoodBuddy 传输路径。
- **验收:**
- 干净用户目录能获取预期版本。
- Desktop 到 Agent 的正常路径和恢复路径均使用当前候选产物通过。
- 发布说明准确标注已验证架构和仍未验证范围。
- **外部依赖:** Agent 发布审批、双架构正式产物、真实 Linux arm64 环境。
- **起始证据:** `package.json`、`agent-runtime-lock.json`、
`docs/architecture/remote-host-and-goodbuddy-agent-design.md`。
### REL-02 正式 Latest 签名门槛
- **优先级 / 状态:** P0 / 待开始
- **目标:** 官网正式推荐下载不指向可能被系统默认安全策略阻止的测试产物。
- **范围:**
- macOS 缺少签名或公证凭据时,不更新正式 Latest。
- Windows 未签名构建不作为默认推荐安装包。
- 未签名构建继续作为明确标注的测试 artifact。
- **验收:**
- 发布工作流在签名条件不满足时不会切换正式 Latest。
- 正式下载在全新 macOS、Windows 默认安全策略下完成首次启动。
- **外部依赖:** Apple 和 Windows 代码签名凭据。
- **起始证据:** `.github/workflows/packages.yml`、`BUILD.md`、`README.md`。
### REL-03 发布包启动冒烟
- **优先级 / 状态:** P0 / 待开始
- **目标:** 发布成功代表打包应用能够启动,而不只是文件结构完整。
- **范围:**
- 在对应 CI Runner 启动解包应用。
- 等待 Main、Preload、Renderer ready 健康标识后退出。
- Windows x64 接入现有 packaged DeepSeek Harness smoke。
- 为启动设置总超时,并保留无用户内容的失败诊断。
- **验收:**
- 缺 DLL、ASAR unpack、Preload 或 Main 启动错误会使发布任务失败。
- 探针无凭据、无外网也能执行。
- **起始证据:** `.github/workflows/packages.yml`、`build/build-release.cjs`、
`build/run-packaged-deepseek-harness-smoke.cjs`。
## 6. 核心与增强功能
### FUN-01 定时任务编辑
- **优先级 / 状态:** P1 / 待开始
- **目标:** 用户无需删除并重建计划任务即可纠正配置。
- **范围:**
- 新增共享 Update schema、Preload 方法和可信 IPC handler。
- 复用定制任务创建对话框作为编辑模式。
- 支持修改名称、Prompt、Ask/Execute、Runtime、首次运行时间和周期。
- 保留原 Task、Conversation、Schedule 和历史运行关联。
- **验收:**
- 从任务界面进入编辑,保存后列表和下一次运行时间立即更新。
- 编辑不产生重复 Task 或 Schedule。
- 正在运行的实例继续使用启动时快照,后续触发使用新配置。
- **起始证据:** `CustomTaskDialog.tsx`、`TaskScheduleActions.tsx`、`src/main/ipc.ts`。
### FUN-02 企业微信附件收发
- **优先级 / 状态:** P1 / 待开始
- **目标:** 企业微信完成“接收文件或图片、处理、回传成果”的办公闭环。
- **范围:**
- 接收官方接口支持的图片和普通文件。
- 将附件接入现有远程消息上下文。
- 支持回传当前任务生成的图片或文件。
- 复用 `ChannelMediaAttachment`、现有大小限制和 outbox 清理。
- **验收:**
- 收到支持的附件不会再返回 `attachment_not_supported`。
- 任务生成的有界成果能发送到原会话。
- 超限、下载失败和发送失败提供明确错误且临时文件得到清理。
- **起始证据:** `src/main/channels/wecom-driver.ts`、
`src/main/channels/wechat-sidecar.ts`。
### FUN-03 钉钉附件收发
- **优先级 / 状态:** P1 / 待开始
- **目标:** 钉钉非文本消息不再静默丢失,并完成文件办公闭环。
- **范围:**
- 支持官方接口允许的图片和普通文件接收。
- 支持任务成果附件回传。
- 对暂不支持的消息类型返回明确说明。
- **验收:**
- 支持的非文本消息进入对应远程 Conversation。
- 不支持的消息有可见反馈,不被静默忽略。
- 收发限制和清理行为与其他通道一致。
- **起始证据:** `src/main/channels/dingtalk-driver.ts`、
`src/main/channels/dingtalk-channel-driver.ts`。
### FUN-04 浏览器错误分类
- **优先级 / 状态:** P1 / 待开始
- **目标:** 浏览器任务失败后,用户知道失败阶段和下一步操作。
- **范围:**
- 保留代理、DNS、会话创建、CDP、导航和截图等失败阶段。
- 增加少量稳定错误码及一句修复建议。
- 在任务记录和界面中呈现,不建立通用错误协议框架。
- **验收:**
- 典型失败不再全部显示为“工具执行失败”。
- 原始敏感内容不进入 Renderer 或诊断日志。
- 取消继续被识别为取消,而不是错误。
- **起始证据:** `src/main/agent/model-runtime.ts`、
`docs/status/computer-control-implementation-status.md`。
### FUN-05 更新下载闭环
- **优先级 / 状态:** P1 / 待开始
- **目标:** 用户能在应用中取得当前平台安装文件并确认文件完整。
- **范围:**
- 从当前更新源读取当前平台产物。
- 下载到用户选择目录。
- 使用现有发布清单校验大小和 SHA-256。
- 校验成功后允许打开文件或所在目录。
- 安装继续由用户手动触发。
- **验收:**
- 下载源、版本、架构和当前系统匹配。
- 损坏或哈希不匹配的文件不会被呈现为可安装。
- 失败保留目标和错误上下文,可重新下载。
- **起始证据:** `UpdateSettingsSection.tsx`、`src/main/version-checker.ts`、
`src/main/ipc.ts`。
### FUN-06 定时任务常用周期
- **优先级 / 状态:** P2 / 待开始
- **目标:** 覆盖常见办公日历,而不要求用户编写 Cron。
- **范围:** 增加工作日和每月周期,并持续显示下一次实际执行时间。
- **验收:** 创建、编辑、重启恢复和到期触发均按本地日历执行且不重复。
- **依赖:** `FUN-01`、`FUN-07`。
- **起始证据:** `src/shared/assistant-contracts.ts`、
`docs/prd/task-and-job/scheduled-task-prd.md`。
### FUN-07 时区和错过执行策略
- **优先级 / 状态:** P2 / 待开始
- **目标:** 用户明确控制任务在哪个时区运行,以及错过后是否补跑。
- **范围:**
- 默认本机 IANA 时区。
- 支持 `skip` 和 `run_once`。
- 显示 DST 影响后的下一次实际运行时间。
- **验收:**
- 重启或系统恢复后不会形成补跑风暴。
- 时区和策略可创建、编辑、持久化并在界面复现。
- **起始证据:** `src/main/assistant/assistant-database.ts`、
`docs/prd/task-and-job/scheduled-task-prd.md`。
### FUN-08 旧版 Office 文件
- **优先级 / 状态:** P2 / 待开始
- **目标:** DOC、XLS、PPT 能进入聊天附件和知识库解析路径。
- **范围:**
- 检测本机 LibreOffice。
- 使用 headless 转换到 OOXML 或 PDF 后复用现有解析器。
- 未安装时提供明确安装或手工转换建议。
- **验收:**
- 三种旧格式各用真实文件完成聊天解析和知识库导入。
- 转换取消、超时和失败后清理 GoodBuddy 临时目录。
- 不内置第二套文档解析引擎。
- **起始证据:** `src/main/knowledge/document-parser.ts`、
`DocumentParsingSettingsSection.tsx`。
### FUN-09 首个原生电脑控制适配器
- **优先级 / 状态:** P2 / 待开始
- **目标:** 在一个明确的主要部署平台上真实控制桌面应用。
- **范围:**
- 首先从 Windows UIA、macOS AX 或 Linux 原生方案中选择一个平台。
- 完成窗口快照、点击、输入、取消和退出清理。
- 接入现有 computer-control broker。
- **验收:**
- 在真实桌面应用完成一次可重复的查看、点击和输入任务。
- Ask 仍不可执行桌面变更,Execute 路径记录活动。
- 取消和关闭后不遗留 GoodBuddy 控制会话。
- **外部依赖:** 首个平台产品决策及对应真实设备。
- **起始证据:** `src/main/capabilities/capability-service.ts`、
`docs/status/computer-control-implementation-status.md`。
## 7. 性能
### PERF-01 启动性能测量
- **优先级 / 状态:** P1 / 待开始
- **目标:** 得到冷启动各阶段的可重复耗时,而不是依据代码顺序猜测。
- **指标:** `app.whenReady`、窗口创建、数据库、知识库、Provider/Gateway、Runtime hydration、
IPC 注册、`loadMainWindow`、`ready-to-show` 和 Renderer 首帧。
- **验收:** 固定设备至少运行五次冷启动,报告中位数和 p95;诊断不包含用户内容。
### PERF-02 启动路径优化
- **优先级 / 状态:** P1 / 待开始
- **目标:** 尽早显示可理解的应用壳,并延后经测量确认的非首屏工作。
- **实施条件:** `PERF-01` 证明具体阶段构成主要延迟。
- **验收:** 首帧和可交互时间达到批次开始时确定的目标,初始化失败仍有明确状态和恢复入口。
### PERF-03 长流式回答基准
- **优先级 / 状态:** P1 / 待开始
- **场景:** 100KB、500KB、1MB Markdown 回答,包含推理、代码块和常见富文本。
- **指标:** React commit 数和 p95、Long Tasks、Markdown 渲染时间、输入延迟、滚动帧率、
Renderer 堆内存。
- **验收:** 测试数据、运行步骤和原始结果可重复执行。
### PERF-04 流式更新合并
- **优先级 / 状态:** P1 / 待开始
- **目标:** 降低长回答期间的状态复制和完整 Markdown 重解析。
- **实施条件:** `PERF-03` 确认 commit 或 Markdown 渲染是瓶颈。
- **范围:**
- 同一请求的 text/reasoning delta 按 `requestAnimationFrame` 合并。
- 每帧最多提交一次相关 React 状态。
- 流结束后再执行完整富文本渲染。
- **验收:** 目标指标改善;事件顺序、停止、重试、引用、工具和 Subagent 块不回退。
### PERF-05 向量检索规模基准
- **优先级 / 状态:** P1 / 待开始
- **场景:** 1k、10k、50k chunks 的全文、向量和混合检索。
- **指标:** 总耗时、`vectorScannedCount`、Main event-loop lag、取消响应和峰值内存。
- **验收:** 固定语料和查询集产生可比较结果,并保留检索质量指标。
### PERF-06 向量计算移出 Main
- **优先级 / 状态:** P1 / 待开始
- **目标:** 大知识库向量扫描不阻塞 Electron Main。
- **实施条件:** `PERF-05` 确认 Main event-loop lag 或取消响应不达标。
- **范围:** 优先复用已有 Worker,减少重复扫描和复制;本项不自动引入 ANN。
- **验收:** 检索排序和质量不回退,Main 延迟与取消指标达到目标。
### PERF-07 知识库 Snapshot 测量
- **优先级 / 状态:** P2 / 待开始
- **指标:** SQL 时间、对象数量、structured-clone 估算字节、IPC 往返、Renderer commit 和
峰值堆内存。
- **场景:** 小型、典型和大型文档与图谱数据集。
- **验收:** 明确首屏实际需要的字段和超过目标阈值的数据规模。
### PERF-08 知识库按需加载
- **优先级 / 状态:** P2 / 待开始
- **实施条件:** `PERF-07` 证明完整 Snapshot 是可见瓶颈。
- **范围:**
- 首屏只返回列表字段、状态和计数。
- 文档详情按选择加载。
- 图实体、关系和证据仅在图谱视图加载。
- 复用已有列表和 chunk 接口。
- **验收:** 首开与切换指标改善,选择、刷新、取消和局部错误状态不回退。
### PERF-09 Keep-alive 压力测试
- **优先级 / 状态:** P2 / 待开始
- **场景:** 连续打开 12 个会话,每个会话包含 80 条富 Markdown、图片和工具记录。
- **指标:** DOM 节点、Renderer heap、GC pause 和流式 commit。
- **验收:** 明确隐藏会话缓存是否构成实际内存或渲染问题。
### PERF-10 Keep-alive 轻量优化
- **优先级 / 状态:** P2 / 待开始
- **实施条件:** `PERF-09` 确认当前缓存不达标。
- **范围:**
- 优先 memoize 隐藏 `ChatHistoryPane` 并稳定 props。
- 仍不达标时才调整缓存数量或一小时有效期。
- 暂不引入完整虚拟化框架。
- **验收:** 内存和 commit 指标改善,同时保留会话切换位置和快速恢复体验。
## 8. 体验与可访问性
### UX-01 统一 Ask/Execute 文案
- **优先级 / 状态:** P1 / 已完成
- **范围:**
- 删除“Execute 高风险操作仍需审批”的冲突说明。
- 统一表达为使用当前账号完整权限执行,调用记录到活动。
- 同步定时任务、Composer、Runtime、帮助文案及中英文资源。
- **验收:** 所有入口对 Ask/Execute 的描述与真实 Runtime 契约一致。
### UX-02 Runtime 显式状态
- **优先级 / 状态:** P1 / 已完成
- **范围:** 顶栏显示就绪、连接中、不可用等文字,并通过 `aria-describedby` 暴露原因。
- **验收:** 不依赖颜色或 `title` 即可理解 Runtime 状态和发送不可用原因。
### UX-03 等待审批实时通知
- **优先级 / 状态:** P1 / 已完成
- **范围:** 审批卡首次出现时用 polite live region 播报等待状态和工具名;不抢焦点。
- **验收:** 屏幕阅读器能发现新审批,右侧栏数量变化也有可访问状态。
### UX-04 长任务阶段播报
- **优先级 / 状态:** P1 / 已完成
- **范围:** 低频阶段使用 `role="status"`,失败终态使用 `role="alert"`,不逐字播报正文。
- **验收:** 准备、等待、完成和失败可被辅助技术理解,流式输出不会形成播报风暴。
### UX-05 Composer 错误关联
- **优先级 / 状态:** P1 / 已完成
- **范围:** 附件和上下文错误使用稳定 ID、`role="alert"`、`aria-describedby` 和适当的
`aria-invalid`。
- **验收:** 键盘和屏幕阅读器用户能知道发送失败原因及对应操作区域。
### UX-06 设置离开确认焦点
- **优先级 / 状态:** P1 / 已完成
- **范围:** 确认出现时滚动到可见区域并聚焦“继续编辑”,或改用共享确认对话框。
- **验收:** 在长设置页底部切换分类、关闭设置和应用导航时均不会出现不可见确认。
### UX-07 SSH Host 读取失败状态
- **优先级 / 状态:** P1 / 已完成
- **范围:** 读取失败与真实空列表分开,失败状态提供重新读取。
- **验收:** 暂时读取失败不会诱导用户重复添加 Host,重试成功后恢复原列表。
### UX-08 工作区预览重试
- **优先级 / 状态:** P2 / 已完成
- **范围:** 加载使用 `role="status"` 和 `aria-busy`;失败保留路径并提供重新读取。
- **验收:** 网络抖动后无需返回目录重新查找文件即可恢复预览。
### UX-09 最近对话空状态
- **优先级 / 状态:** P2 / 已完成
- **范围:** 区分首次为空、搜索无结果和加载失败,分别提供新建、清除搜索和重试。
- **验收:** 三种状态文案和操作互不混用。
### UX-10 共享加载状态语义
- **优先级 / 状态:** P2 / 已完成
- **范围:** 为共享 `EmptyState` 增加 loading 变体,并迁移知识库、智能心跳和 SSH Host。
- **验收:** 加载状态统一输出 `role="status"`、`aria-live="polite"` 和 `aria-busy="true"`。
### UX-11 更新检查错误反馈
- **优先级 / 状态:** P1 / 已完成
- **范围:**
- 启动检查失败进入去重后的全局错误通知。
- 保留来源、网络和有界 HTTP 错误上下文。
- 打开下载页失败也显示通知。
- **验收:** 不再以空 `catch` 静默丢失用户可处理的更新错误。
### UX-12 更新源与自动检查解耦
- **优先级 / 状态:** P2 / 已完成
- **范围:**
- 关闭启动检查后仍可选择 GitHub 或镜像。
- 手动检查和下载继续使用所选来源。
- 同步修订 `UI-DESIGN.md` 当前相反的规则。
- **验收:** “关闭自动检查、切换镜像、手动检查”流程通过测试。
## 9. 诊断与质量
### OPS-01 桌面端有界诊断日志
- **优先级 / 状态:** P1 / 已完成
- **范围:** 轮转记录最近启动和 Runtime 失败的时间、组件、阶段和稳定错误码。
- **限制:** 不记录 Prompt、凭据、文档正文或 Provider 原始响应。
- **验收:** 重启后仍可定位最近一次人为制造的数据库或 Runtime 启动失败。
### OPS-02 远端 Agent 有界诊断日志
- **优先级 / 状态:** P1 / 已完成
- **范围:** Detached Agent 保存有界轮转诊断,覆盖 Runtime 启动、退出、连接和恢复阶段。
- **验收:** 人为制造远端失败后可导出根因阶段;关闭和轮转不会遗留无界文件。
- **限制:** 不记录 accepted Prompt、模型密钥或完整模型配置。
### OPS-03 反馈可选附加诊断
- **优先级 / 状态:** P1 / 已完成
- **范围:** 用户主动勾选后才附加诊断,提交前说明类别,保留现有截图和草稿重试。
- **验收:** 默认反馈不附加诊断;勾选后只包含允许的有界记录。
- **依赖:** `OPS-01`;本批明确不自动读取或附加 `OPS-02` 的远端 Agent 记录,
远端记录通过 Agent 固定 CLI 独立导出。
### QA-01 真实 Runtime E2E
- **优先级 / 状态:** P1 / 待开始
- **范围:**
- 直连模型一次有界真实请求。
- Bundled OpenCode 启动并执行文件任务。
- Continue 启动并完成一次任务。
- MCP 工具写入生产路径。
- **验收:** 受保护发布候选任务运行通过,并记录精确模型调用次数和费用边界。
### QA-02 本地兼容 Provider E2E
- **优先级 / 状态:** P1 / 待开始
- **目标:** 常规 CI 无需公网或真实模型凭据也能覆盖打包 Runtime 启动和工具路径。
- **范围:** 提供最小本地 OpenAI 兼容测试 Provider,覆盖流式响应和工具调用。
- **验收:** SDK、Runtime 二进制、Provider 适配或工具写入回归会使常规 CI 失败。
### QA-03 Windows ARM64 覆盖纠正
- **优先级 / 状态:** P1 / 待开始
- **范围:**
- 文档明确 Windows ARM64 当前为交叉打包。
- 在真实设备验证 Electron、node-pty、Koffi、Canvas、OCR 和 Runtime 加载。
- 有可用 ARM64 Runner 后再声明原生 CI。
- **验收:** 文档和发布声明不再把文件架构验证描述为原生运行验证。
- **外部依赖:** 真实 Windows ARM64 设备或 Runner。
## 10. 每批完成标准
一个事项只有同时满足以下条件才可标记为“已完成”:
1. 正常 UI 操作到达生产实现并产生预期结果,不以 mock、注入 fake 或禁用入口代替。
2. 已覆盖本事项声明的可达失败场景,用户输入和可恢复上下文不会被静默丢弃。
3. 新增或更新聚焦测试;功能变化后运行:
```text
npm test
npm run typecheck
npm run lint
```
4. 生产构建或发布脚本变化后运行 `npm run build`。
5. 改动涉及 GoodBuddy Agent 或 Desktop-to-Agent 生产路径时,按 `AGENTS.md` 在共享 Linux x64
Test Host 验证当前源码或候选包;Host 不可达时明确记录阻塞,不能标记完成。
6. 检查并更新受影响的 PRD、架构、设计、功能矩阵、构建和运维文档。
7. 在批次记录中填写实际验证命令、结果、剩余限制和对应提交。
## 11. 批次记录模板
开始一个批次时,在本节末尾复制以下模板:
```markdown
### 批次 N:标题
- 状态:进行中
- 范围:ITEM-01、ITEM-02
- 明确不包含:
- 开始日期:
- 完成日期:
- 外部依赖:
#### 验收结果
- [ ] 正常生产路径
- [ ] 声明的失败与恢复路径
- [ ] 聚焦测试
- [ ] npm test
- [ ] npm run typecheck
- [ ] npm run lint
- [ ] npm run build(如适用)
- [ ] 真实 Host 或目标平台验证(如适用)
- [ ] 相关文档更新
#### 结果与剩余限制
- 提交:
- 验证:
- 剩余限制:
```
### 批次 1A:体验一致性与 P1 诊断
- 状态:已完成
- 范围:`UX-01` 至 `UX-12`、`OPS-01` 至 `OPS-03`
- 明确不包含:`REL-*`、`FUN-*`、`PERF-*`、`QA-*`,以及初始 Renderer Bundle 优化
- 开始日期:2026-08-31
- 完成日期:2026-08-31
- 外部依赖:无
#### 验收结果
- [x] 正常生产路径
- [x] 声明的失败与恢复路径
- [x] 聚焦测试
- [x] `npm test`
- [x] `npm run typecheck`
- [x] `npm run lint`
- [x] `npm run build`
- [x] 共享 Linux x64 Host 的当前源码 Agent 候选验证
- [x] 相关文档更新
#### 结果与剩余限制
- 提交:尚未提交
- 验证:306 个测试文件、3322 项测试通过,49 项按既有条件跳过;Node/Web TypeScript、
完整 ESLint、生产构建和 Renderer Bundle 预算均通过。共享 Linux x64 Host 使用隔离
installation 完成 bootstrap、attach、断开重连、controller resume、Runtime 进程启动、
CLI 诊断导出、重启读取、权限和诊断写失败隔离;真实文本模型调用 0 次。
- 剩余限制:真实 Host 本次没有通过 Agent-owned model bridge 执行 Prompt,因此未在该
Host 上覆盖 Prompt 期间的 `runtime.starting/runtime.started` 诊断;三文件真实轮转仍由
聚焦测试覆盖。正式发布、功能增强、性能基线和 QA 路线均不属于本批。